Add DXVA2 HEVC HWAccel
[ffmpeg.git] / libavcodec / jpeglsenc.c
index a825cf9..3af6412 100644 (file)
 #include "avcodec.h"
 #include "get_bits.h"
 #include "golomb.h"
+#include "internal.h"
 #include "mathops.h"
-#include "dsputil.h"
 #include "mjpeg.h"
 #include "jpegls.h"
 
-
 /**
  * Encode error from regular symbol
  */
-static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, int err){
+static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q,
+                                     int err)
+{
     int k;
     int val;
     int map;
 
-    for(k = 0; (state->N[Q] << k) < state->A[Q]; k++);
+    for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
+        ;
 
     map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]);
 
-    if(err < 0)
+    if (err < 0)
         err += state->range;
-    if(err >= ((state->range + 1) >> 1)) {
+    if (err >= (state->range + 1 >> 1)) {
         err -= state->range;
-        val = 2 * FFABS(err) - 1 - map;
+        val  = 2 * FFABS(err) - 1 - map;
     } else
         val = 2 * err + map;
 
@@ -62,27 +64,30 @@ static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q,
 /**
  * Encode error from run termination
  */
-static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RItype, int err, int limit_add){
+static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb,
+                                     int RItype, int err, int limit_add)
+{
     int k;
     int val, map;
     int Q = 365 + RItype;
     int temp;
 
     temp = state->A[Q];
-    if(RItype)
+    if (RItype)
         temp += state->N[Q] >> 1;
-    for(k = 0; (state->N[Q] << k) < temp; k++);
+    for (k = 0; (state->N[Q] << k) < temp; k++)
+        ;
     map = 0;
-    if(!k && err && (2 * state->B[Q] < state->N[Q]))
+    if (!k && err && (2 * state->B[Q] < state->N[Q]))
         map = 1;
 
-    if(err < 0)
-        val = - (2 * err) - 1 - RItype + map;
+    if (err < 0)
+        val = -(2 * err) - 1 - RItype + map;
     else
         val = 2 * err - RItype - map;
     set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp);
 
-    if(err < 0)
+    if (err < 0)
         state->B[Q]++;
     state->A[Q] += (val + 1 - RItype) >> 1;
 
@@ -92,19 +97,21 @@ static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RIt
 /**
  * Encode run value as specified by JPEG-LS standard
  */
-static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, int comp, int trail){
-    while(run >= (1 << ff_log2_run[state->run_index[comp]])){
+static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run,
+                                 int comp, int trail)
+{
+    while (run >= (1 << ff_log2_run[state->run_index[comp]])) {
         put_bits(pb, 1, 1);
         run -= 1 << ff_log2_run[state->run_index[comp]];
-        if(state->run_index[comp] < 31)
+        if (state->run_index[comp] < 31)
             state->run_index[comp]++;
     }
     /* if hit EOL, encode another full run, else encode aborted run */
-    if(!trail && run) {
+    if (!trail && run) {
         put_bits(pb, 1, 1);
-    }else if(trail){
+    } else if (trail) {
         put_bits(pb, 1, 0);
-        if(ff_log2_run[state->run_index[comp]])
+        if (ff_log2_run[state->run_index[comp]])
             put_bits(pb, ff_log2_run[state->run_index[comp]], run);
     }
 }
@@ -112,12 +119,15 @@ static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, in
 /**
  * Encode one line of image
  */
-static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last, void *cur, int last2, int w, int stride, int comp, int bits){
+static inline void ls_encode_line(JLSState *state, PutBitContext *pb,
+                                  void *last, void *cur, int last2, int w,
+                                  int stride, int comp, int bits)
+{
     int x = 0;
     int Ra, Rb, Rc, Rd;
     int D0, D1, D2;
 
-    while(x < w) {
+    while (x < w) {
         int err, pred, sign;
 
         /* compute gradients */
@@ -130,71 +140,76 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last
         D2 = Rc - Ra;
 
         /* run mode */
-        if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) {
+        if ((FFABS(D0) <= state->near) &&
+            (FFABS(D1) <= state->near) &&
+            (FFABS(D2) <= state->near)) {
             int RUNval, RItype, run;
 
-            run = 0;
+            run    = 0;
             RUNval = Ra;
-            while(x < w && (FFABS(R(cur, x) - RUNval) <= state->near)){
+            while (x < w && (FFABS(R(cur, x) - RUNval) <= state->near)) {
                 run++;
                 W(cur, x, Ra);
                 x += stride;
             }
             ls_encode_run(state, pb, run, comp, x < w);
-            if(x >= w)
+            if (x >= w)
                 return;
-            Rb = R(last, x);
-            RItype = (FFABS(Ra - Rb) <= state->near);
-            pred = RItype ? Ra : Rb;
-            err = R(cur, x) - pred;
+            Rb     = R(last, x);
+            RItype = FFABS(Ra - Rb) <= state->near;
+            pred   = RItype ? Ra : Rb;
+            err    = R(cur, x) - pred;
 
-            if(!RItype && Ra > Rb)
+            if (!RItype && Ra > Rb)
                 err = -err;
 
-            if(state->near){
-                if(err > 0)
-                    err = (state->near + err) / state->twonear;
+            if (state->near) {
+                if (err > 0)
+                    err =  (state->near + err) / state->twonear;
                 else
                     err = -(state->near - err) / state->twonear;
 
-                if(RItype || (Rb >= Ra))
+                if (RItype || (Rb >= Ra))
                     Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
                 else
                     Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
                 W(cur, x, Ra);
             }
-            if(err < 0)
+            if (err < 0)
                 err += state->range;
-            if(err >= ((state->range + 1) >> 1))
+            if (err >= state->range + 1 >> 1)
                 err -= state->range;
 
-            ls_encode_runterm(state, pb, RItype, err, ff_log2_run[state->run_index[comp]]);
+            ls_encode_runterm(state, pb, RItype, err,
+                              ff_log2_run[state->run_index[comp]]);
 
-            if(state->run_index[comp] > 0)
+            if (state->run_index[comp] > 0)
                 state->run_index[comp]--;
         } else { /* regular mode */
             int context;
 
-            context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2);
-            pred = mid_pred(Ra, Ra + Rb - Rc, Rb);
+            context = ff_jpegls_quantize(state, D0) * 81 +
+                      ff_jpegls_quantize(state, D1) *  9 +
+                      ff_jpegls_quantize(state, D2);
+            pred    = mid_pred(Ra, Ra + Rb - Rc, Rb);
 
-            if(context < 0){
+            if (context < 0) {
                 context = -context;
-                sign = 1;
-                pred = av_clip(pred - state->C[context], 0, state->maxval);
-                err = pred - R(cur, x);
-            }else{
+                sign    = 1;
+                pred    = av_clip(pred - state->C[context], 0, state->maxval);
+                err     = pred - R(cur, x);
+            } else {
                 sign = 0;
                 pred = av_clip(pred + state->C[context], 0, state->maxval);
-                err = R(cur, x) - pred;
+                err  = R(cur, x) - pred;
             }
 
-            if(state->near){
-                if(err > 0)
-                    err = (state->near + err) / state->twonear;
+            if (state->near) {
+                if (err > 0)
+                    err =  (state->near + err) / state->twonear;
                 else
                     err = -(state->near - err) / state->twonear;
-                if(!sign)
+                if (!sign)
                     Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
                 else
                     Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
@@ -207,19 +222,22 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last
     }
 }
 
-static void ls_store_lse(JLSState *state, PutBitContext *pb){
+static void ls_store_lse(JLSState *state, PutBitContext *pb)
+{
     /* Test if we have default params and don't need to store LSE */
-    JLSState state2;
-    memset(&state2, 0, sizeof(JLSState));
-    state2.bpp = state->bpp;
+    JLSState state2 = { 0 };
+    state2.bpp  = state->bpp;
     state2.near = state->near;
     ff_jpegls_reset_coding_parameters(&state2, 1);
-    if(state->T1 == state2.T1 && state->T2 == state2.T2 && state->T3 == state2.T3 && state->reset == state2.reset)
+    if (state->T1 == state2.T1 &&
+        state->T2 == state2.T2 &&
+        state->T3 == state2.T3 &&
+        state->reset == state2.reset)
         return;
     /* store LSE type 1 */
     put_marker(pb, LSE);
     put_bits(pb, 16, 13);
-    put_bits(pb, 8,   1);
+    put_bits(pb, 8, 1);
     put_bits(pb, 16, state->maxval);
     put_bits(pb, 16, state->T1);
     put_bits(pb, 16, state->T2);
@@ -227,61 +245,64 @@ static void ls_store_lse(JLSState *state, PutBitContext *pb){
     put_bits(pb, 16, state->reset);
 }
 
-static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
-    JpeglsContext * const s = avctx->priv_data;
-    AVFrame *pict = data;
-    AVFrame * const p= (AVFrame*)&s->picture;
-    const int near = avctx->prediction_method;
+static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
+                             const AVFrame *pict, int *got_packet)
+{
+    const AVFrame *const p = pict;
+    const int near         = avctx->prediction_method;
     PutBitContext pb, pb2;
     GetBitContext gb;
     uint8_t *buf2, *zero, *cur, *last;
     JLSState *state;
-    int i, size;
+    int i, size, ret;
     int comps;
 
-    buf2 = av_malloc(buf_size);
-
-    init_put_bits(&pb, buf, buf_size);
-    init_put_bits(&pb2, buf2, buf_size);
-
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
-
-    if(avctx->pix_fmt == PIX_FMT_GRAY8 || avctx->pix_fmt == PIX_FMT_GRAY16)
+    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||
+        avctx->pix_fmt == AV_PIX_FMT_GRAY16)
         comps = 1;
     else
         comps = 3;
 
+    if ((ret = ff_alloc_packet(pkt, avctx->width * avctx->height * comps * 4 +
+                               FF_MIN_BUFFER_SIZE)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+        return ret;
+    }
+
+    buf2 = av_malloc(pkt->size);
+
+    init_put_bits(&pb, pkt->data, pkt->size);
+    init_put_bits(&pb2, buf2, pkt->size);
+
     /* write our own JPEG header, can't use mjpeg_picture_header */
     put_marker(&pb, SOI);
     put_marker(&pb, SOF48);
     put_bits(&pb, 16, 8 + comps * 3); // header size depends on components
-    put_bits(&pb,  8, (avctx->pix_fmt == PIX_FMT_GRAY16) ? 16 : 8); // bpp
+    put_bits(&pb, 8, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8);  // bpp
     put_bits(&pb, 16, avctx->height);
     put_bits(&pb, 16, avctx->width);
-    put_bits(&pb,  8, comps);         // components
-    for(i = 1; i <= comps; i++) {
-        put_bits(&pb,  8, i);    // component ID
-        put_bits(&pb,  8, 0x11); // subsampling: none
-        put_bits(&pb,  8, 0);    // Tiq, used by JPEG-LS ext
+    put_bits(&pb, 8, comps);          // components
+    for (i = 1; i <= comps; i++) {
+        put_bits(&pb, 8, i);     // component ID
+        put_bits(&pb, 8, 0x11);  // subsampling: none
+        put_bits(&pb, 8, 0);     // Tiq, used by JPEG-LS ext
     }
 
     put_marker(&pb, SOS);
     put_bits(&pb, 16, 6 + comps * 2);
-    put_bits(&pb,  8, comps);
-    for(i = 1; i <= comps; i++) {
-        put_bits(&pb,  8, i);  // component ID
-        put_bits(&pb,  8, 0);  // mapping index: none
+    put_bits(&pb, 8, comps);
+    for (i = 1; i <= comps; i++) {
+        put_bits(&pb, 8, i);   // component ID
+        put_bits(&pb, 8, 0);   // mapping index: none
     }
-    put_bits(&pb,  8, near);
-    put_bits(&pb,  8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line
-    put_bits(&pb,  8, 0); // point transform: none
+    put_bits(&pb, 8, near);
+    put_bits(&pb, 8, (comps > 1) ? 1 : 0);  // interleaving: 0 - plane, 1 - line
+    put_bits(&pb, 8, 0);  // point transform: none
 
     state = av_mallocz(sizeof(JLSState));
     /* initialize JPEG-LS state from JPEG parameters */
     state->near = near;
-    state->bpp = (avctx->pix_fmt == PIX_FMT_GRAY16) ? 16 : 8;
+    state->bpp  = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8;
     ff_jpegls_reset_coding_parameters(state, 0);
     ff_jpegls_init_state(state);
 
@@ -289,75 +310,77 @@ static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_
 
     zero = av_mallocz(p->linesize[0]);
     last = zero;
-    cur = p->data[0];
-    if(avctx->pix_fmt == PIX_FMT_GRAY8){
+    cur  = p->data[0];
+    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
         int t = 0;
 
-        for(i = 0; i < avctx->height; i++) {
-            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0,  8);
-            t = last[0];
+        for (i = 0; i < avctx->height; i++) {
+            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 8);
+            t    = last[0];
             last = cur;
             cur += p->linesize[0];
         }
-    }else if(avctx->pix_fmt == PIX_FMT_GRAY16){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY16) {
         int t = 0;
 
-        for(i = 0; i < avctx->height; i++) {
+        for (i = 0; i < avctx->height; i++) {
             ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16);
-            t = *((uint16_t*)last);
+            t    = *((uint16_t *)last);
             last = cur;
             cur += p->linesize[0];
         }
-    }else if(avctx->pix_fmt == PIX_FMT_RGB24){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
         int j, width;
-        int Rc[3] = {0, 0, 0};
+        int Rc[3] = { 0, 0, 0 };
 
         width = avctx->width * 3;
-        for(i = 0; i < avctx->height; i++) {
-            for(j = 0; j < 3; j++) {
-                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8);
+        for (i = 0; i < avctx->height; i++) {
+            for (j = 0; j < 3; j++) {
+                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],
+                               width, 3, j, 8);
                 Rc[j] = last[j];
             }
             last = cur;
-            cur += s->picture.linesize[0];
+            cur += p->linesize[0];
         }
-    }else if(avctx->pix_fmt == PIX_FMT_BGR24){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
         int j, width;
-        int Rc[3] = {0, 0, 0};
+        int Rc[3] = { 0, 0, 0 };
 
         width = avctx->width * 3;
-        for(i = 0; i < avctx->height; i++) {
-            for(j = 2; j >= 0; j--) {
-                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8);
+        for (i = 0; i < avctx->height; i++) {
+            for (j = 2; j >= 0; j--) {
+                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],
+                               width, 3, j, 8);
                 Rc[j] = last[j];
             }
             last = cur;
-            cur += s->picture.linesize[0];
+            cur += p->linesize[0];
         }
     }
 
     av_free(zero);
     av_free(state);
 
-    // the specification says that after doing 0xff escaping unused bits in the
-    // last byte must be set to 0, so just append 7 "optional" zero-bits to
-    // avoid special-casing.
+    /* the specification says that after doing 0xff escaping unused bits in
+     * the last byte must be set to 0, so just append 7 "optional" zero-bits
+     * to avoid special-casing. */
     put_bits(&pb2, 7, 0);
     size = put_bits_count(&pb2);
     flush_put_bits(&pb2);
     /* do escape coding */
     init_get_bits(&gb, buf2, size);
     size -= 7;
-    while(get_bits_count(&gb) < size){
+    while (get_bits_count(&gb) < size) {
         int v;
         v = get_bits(&gb, 8);
         put_bits(&pb, 8, v);
-        if(v == 0xFF){
+        if (v == 0xFF) {
             v = get_bits(&gb, 7);
             put_bits(&pb, 8, v);
         }
     }
-    align_put_bits(&pb);
+    avpriv_align_put_bits(&pb);
     av_free(buf2);
 
     /* End of image */
@@ -366,30 +389,49 @@ static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_
 
     emms_c();
 
-    return put_bits_count(&pb) >> 3;
+    pkt->size   = put_bits_count(&pb) >> 3;
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+    return 0;
 }
 
-static av_cold int encode_init_ls(AVCodecContext *ctx) {
-    JpeglsContext *c = (JpeglsContext*)ctx->priv_data;
-
-    c->avctx = ctx;
-    ctx->coded_frame = &c->picture;
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
 
-    if(ctx->pix_fmt != PIX_FMT_GRAY8 && ctx->pix_fmt != PIX_FMT_GRAY16 && ctx->pix_fmt != PIX_FMT_RGB24 && ctx->pix_fmt != PIX_FMT_BGR24){
-        av_log(ctx, AV_LOG_ERROR, "Only grayscale and RGB24/BGR24 images are supported\n");
+static av_cold int encode_init_ls(AVCodecContext *ctx)
+{
+    ctx->coded_frame = av_frame_alloc();
+    if (!ctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    ctx->coded_frame->key_frame = 1;
+
+    if (ctx->pix_fmt != AV_PIX_FMT_GRAY8  &&
+        ctx->pix_fmt != AV_PIX_FMT_GRAY16 &&
+        ctx->pix_fmt != AV_PIX_FMT_RGB24  &&
+        ctx->pix_fmt != AV_PIX_FMT_BGR24) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Only grayscale and RGB24/BGR24 images are supported\n");
         return -1;
     }
     return 0;
 }
 
-AVCodec ff_jpegls_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them
-    "jpegls",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_JPEGLS,
-    sizeof(JpeglsContext),
-    encode_init_ls,
-    encode_picture_ls,
-    NULL,
-    .pix_fmts= (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_RGB24, PIX_FMT_GRAY8, PIX_FMT_GRAY16, PIX_FMT_NONE},
-    .long_name= NULL_IF_CONFIG_SMALL("JPEG-LS"),
+AVCodec ff_jpegls_encoder = {
+    .name           = "jpegls",
+    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_JPEGLS,
+    .init           = encode_init_ls,
+    .close          = encode_close,
+    .encode2        = encode_picture_ls,
+    .pix_fmts       = (const enum AVPixelFormat[]) {
+        AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24,
+        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
+        AV_PIX_FMT_NONE
+    },
 };