]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/svq1dec.c
pthread_frame: ensure the threads don't run simultaneously with hwaccel
[ffmpeg] / libavcodec / svq1dec.c
index 909ace7b7f84086060f7b1d6c7a5049af072a824..2ab0f238bbb678de1780b377e7a1f471f6bee4bd 100644 (file)
@@ -4,7 +4,7 @@
  * ported to libavcodec by Nick Kurshev <nickols_k@mail.ru>
  *
  * Copyright (C) 2002 the xine project
- * Copyright (C) 2002 the ffmpeg project
+ * Copyright (C) 2002 The FFmpeg project
  *
  * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net>
  *
  */
 
 #include "avcodec.h"
-#include "get_bits.h"
+#include "bitstream.h"
 #include "h263.h"
 #include "hpeldsp.h"
 #include "internal.h"
 #include "mathops.h"
 #include "svq1.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 static VLC svq1_block_type;
 static VLC svq1_motion_component;
 static VLC svq1_intra_multistage[6];
@@ -58,7 +55,7 @@ typedef struct svq1_pmv_s {
 
 typedef struct SVQ1Context {
     HpelDSPContext hdsp;
-    GetBitContext gb;
+    BitstreamContext bc;
     AVFrame *prev;
 
     uint8_t *pkt_swapped;
@@ -114,7 +111,7 @@ static const uint8_t string_table[256] = {
                 break;                                                  \
         }                                                               \
         /* divide block if next bit set */                              \
-        if (get_bits1(bitbuf) == 0)                                     \
+        if (bitstream_read_bit(bc) == 0)                                \
             break;                                                      \
         /* add child nodes */                                           \
         list[n++] = list[i];                                            \
@@ -148,7 +145,7 @@ static const uint8_t string_table[256] = {
 #define SVQ1_CALC_CODEBOOK_ENTRIES(cbook)                               \
     codebook = (const uint32_t *)cbook[level];                          \
     if (stages > 0)                                                     \
-        bit_cache = get_bits(bitbuf, 4 * stages);                       \
+        bit_cache = bitstream_read(bc, 4 * stages);                     \
     /* calculate codebook entries for this vector */                    \
     for (j = 0; j < stages; j++) {                                      \
         entries[j] = (((bit_cache >> (4 * (stages - j - 1))) & 0xF) +   \
@@ -157,8 +154,8 @@ static const uint8_t string_table[256] = {
     mean -= stages * 128;                                               \
     n4    = mean + (mean >> 31) << 16 | (mean & 0xFFFF);
 
-static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels,
-                                   int pitch)
+static int svq1_decode_block_intra(BitstreamContext *bc, uint8_t *pixels,
+                                   ptrdiff_t pitch)
 {
     uint32_t bit_cache;
     uint8_t *list[63];
@@ -183,7 +180,7 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels,
         height = 1 << ((3 + level) / 2);
 
         /* get number of stages (-1 skips vector, 0 for mean only) */
-        stages = get_vlc2(bitbuf, svq1_intra_multistage[level].table, 3, 3) - 1;
+        stages = bitstream_read_vlc(bc, svq1_intra_multistage[level].table, 3, 3) - 1;
 
         if (stages == -1) {
             for (y = 0; y < height; y++)
@@ -192,13 +189,13 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels,
         }
 
         if ((stages > 0 && level >= 4) || stages < 0) {
-            av_dlog(NULL,
+            ff_dlog(NULL,
                     "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",
                     stages, level);
             return AVERROR_INVALIDDATA;  /* invalid vector */
         }
 
-        mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3);
+        mean = bitstream_read_vlc(bc, svq1_intra_mean.table, 8, 3);
 
         if (stages == 0) {
             for (y = 0; y < height; y++)
@@ -222,8 +219,8 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels,
     return 0;
 }
 
-static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels,
-                                       int pitch)
+static int svq1_decode_block_non_intra(BitstreamContext *bc, uint8_t *pixels,
+                                       ptrdiff_t pitch)
 {
     uint32_t bit_cache;
     uint8_t *list[63];
@@ -248,19 +245,19 @@ static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels,
         height = 1 << ((3 + level) / 2);
 
         /* get number of stages (-1 skips vector, 0 for mean only) */
-        stages = get_vlc2(bitbuf, svq1_inter_multistage[level].table, 3, 2) - 1;
+        stages = bitstream_read_vlc(bc, svq1_inter_multistage[level].table, 3, 2) - 1;
 
         if (stages == -1)
             continue;           /* skip vector */
 
         if ((stages > 0 && level >= 4) || stages < 0) {
-            av_dlog(NULL,
+            ff_dlog(NULL,
                     "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",
                     stages, level);
             return AVERROR_INVALIDDATA;  /* invalid vector */
         }
 
-        mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256;
+        mean = bitstream_read_vlc(bc, svq1_inter_mean.table, 9, 3) - 256;
 
         SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_inter_codebooks);
 
@@ -280,7 +277,7 @@ static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels,
     return 0;
 }
 
-static int svq1_decode_motion_vector(GetBitContext *bitbuf, svq1_pmv *mv,
+static int svq1_decode_motion_vector(BitstreamContext *bc, svq1_pmv *mv,
                                      svq1_pmv **pmv)
 {
     int diff;
@@ -288,11 +285,11 @@ static int svq1_decode_motion_vector(GetBitContext *bitbuf, svq1_pmv *mv,
 
     for (i = 0; i < 2; i++) {
         /* get motion code */
-        diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2);
+        diff = bitstream_read_vlc(bc, svq1_motion_component.table, 7, 2);
         if (diff < 0)
             return AVERROR_INVALIDDATA;
         else if (diff) {
-            if (get_bits1(bitbuf))
+            if (bitstream_read_bit(bc))
                 diff = -diff;
         }
 
@@ -307,7 +304,7 @@ static int svq1_decode_motion_vector(GetBitContext *bitbuf, svq1_pmv *mv,
 }
 
 static void svq1_skip_block(uint8_t *current, uint8_t *previous,
-                            int pitch, int x, int y)
+                            ptrdiff_t pitch, int x, int y)
 {
     uint8_t *src;
     uint8_t *dst;
@@ -323,9 +320,9 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous,
     }
 }
 
-static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf,
+static int svq1_motion_inter_block(HpelDSPContext *hdsp, BitstreamContext *bc,
                                    uint8_t *current, uint8_t *previous,
-                                   int pitch, svq1_pmv *motion, int x, int y,
+                                   ptrdiff_t pitch, svq1_pmv *motion, int x, int y,
                                    int width, int height)
 {
     uint8_t *src;
@@ -344,7 +341,7 @@ static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf,
         pmv[2] = &motion[x / 8 + 4];
     }
 
-    result = svq1_decode_motion_vector(bitbuf, &mv, pmv);
+    result = svq1_decode_motion_vector(bc, &mv, pmv);
 
     if (result != 0)
         return result;
@@ -367,9 +364,9 @@ static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf,
     return 0;
 }
 
-static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbuf,
+static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, BitstreamContext *bc,
                                       uint8_t *current, uint8_t *previous,
-                                      int pitch, svq1_pmv *motion, int x, int y,
+                                      ptrdiff_t pitch, svq1_pmv *motion, int x, int y,
                                       int width, int height)
 {
     uint8_t *src;
@@ -388,7 +385,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu
         pmv[2] = &motion[(x / 8) + 4];
     }
 
-    result = svq1_decode_motion_vector(bitbuf, &mv, pmv);
+    result = svq1_decode_motion_vector(bc, &mv, pmv);
 
     if (result != 0)
         return result;
@@ -401,7 +398,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu
     } else {
         pmv[1] = &motion[(x / 8) + 3];
     }
-    result = svq1_decode_motion_vector(bitbuf, &motion[0], pmv);
+    result = svq1_decode_motion_vector(bc, &motion[0], pmv);
 
     if (result != 0)
         return result;
@@ -410,7 +407,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu
     pmv[1] = &motion[0];
     pmv[2] = &motion[(x / 8) + 1];
 
-    result = svq1_decode_motion_vector(bitbuf, &motion[(x / 8) + 2], pmv);
+    result = svq1_decode_motion_vector(bc, &motion[(x / 8) + 2], pmv);
 
     if (result != 0)
         return result;
@@ -419,7 +416,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu
     pmv[2] = &motion[(x / 8) + 2];
     pmv[3] = &motion[(x / 8) + 3];
 
-    result = svq1_decode_motion_vector(bitbuf, pmv[3], pmv);
+    result = svq1_decode_motion_vector(bc, pmv[3], pmv);
 
     if (result != 0)
         return result;
@@ -449,16 +446,16 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu
 }
 
 static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp,
-                                   GetBitContext *bitbuf,
+                                   BitstreamContext *bc,
                                    uint8_t *current, uint8_t *previous,
-                                   int pitch, svq1_pmv *motion, int x, int y,
+                                   ptrdiff_t pitch, svq1_pmv *motion, int x, int y,
                                    int width, int height)
 {
     uint32_t block_type;
     int result = 0;
 
     /* get block type */
-    block_type = get_vlc2(bitbuf, svq1_block_type.table, 2, 2);
+    block_type = bitstream_read_vlc(bc, svq1_block_type.table, 2, 2);
 
     /* reset motion vectors */
     if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) {
@@ -476,45 +473,45 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp,
         break;
 
     case SVQ1_BLOCK_INTER:
-        result = svq1_motion_inter_block(hdsp, bitbuf, current, previous,
+        result = svq1_motion_inter_block(hdsp, bc, current, previous,
                                          pitch, motion, x, y, width, height);
 
         if (result != 0) {
-            av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result);
+            ff_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result);
             break;
         }
-        result = svq1_decode_block_non_intra(bitbuf, current, pitch);
+        result = svq1_decode_block_non_intra(bc, current, pitch);
         break;
 
     case SVQ1_BLOCK_INTER_4V:
-        result = svq1_motion_inter_4v_block(hdsp, bitbuf, current, previous,
+        result = svq1_motion_inter_4v_block(hdsp, bc, current, previous,
                                             pitch, motion, x, y, width, height);
 
         if (result != 0) {
-            av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result);
+            ff_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result);
             break;
         }
-        result = svq1_decode_block_non_intra(bitbuf, current, pitch);
+        result = svq1_decode_block_non_intra(bc, current, pitch);
         break;
 
     case SVQ1_BLOCK_INTRA:
-        result = svq1_decode_block_intra(bitbuf, current, pitch);
+        result = svq1_decode_block_intra(bc, current, pitch);
         break;
     }
 
     return result;
 }
 
-static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out)
+static void svq1_parse_string(BitstreamContext *bc, uint8_t *out)
 {
     uint8_t seed;
     int i;
 
-    out[0] = get_bits(bitbuf, 8);
+    out[0] = bitstream_read(bc, 8);
     seed   = string_table[out[0]];
 
     for (i = 1; i <= out[0]; i++) {
-        out[i] = get_bits(bitbuf, 8) ^ seed;
+        out[i] = bitstream_read(bc, 8) ^ seed;
         seed   = string_table[out[i] ^ seed];
     }
 }
@@ -522,14 +519,14 @@ static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out)
 static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame)
 {
     SVQ1Context *s = avctx->priv_data;
-    GetBitContext *bitbuf = &s->gb;
+    BitstreamContext *bc = &s->bc;
     int frame_size_code;
 
-    skip_bits(bitbuf, 8); /* temporal_reference */
+    bitstream_skip(bc, 8); /* temporal_reference */
 
     /* frame type */
     s->nonref = 0;
-    switch (get_bits(bitbuf, 2)) {
+    switch (bitstream_read(bc, 2)) {
     case 0:
         frame->pict_type = AV_PICTURE_TYPE_I;
         break;
@@ -546,36 +543,35 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame)
     if (frame->pict_type == AV_PICTURE_TYPE_I) {
         /* unknown fields */
         if (s->frame_code == 0x50 || s->frame_code == 0x60) {
-            int csum = get_bits(bitbuf, 16);
+            int csum = bitstream_read(bc, 16);
 
-            csum = ff_svq1_packet_checksum(bitbuf->buffer,
-                                           bitbuf->size_in_bits >> 3,
+            csum = ff_svq1_packet_checksum(bc->buffer, bc->size_in_bits >> 3,
                                            csum);
 
-            av_dlog(avctx, "%s checksum (%02x) for packet data\n",
+            ff_dlog(avctx, "%s checksum (%02x) for packet data\n",
                     (csum == 0) ? "correct" : "incorrect", csum);
         }
 
         if ((s->frame_code ^ 0x10) >= 0x50) {
             uint8_t msg[256];
 
-            svq1_parse_string(bitbuf, msg);
+            svq1_parse_string(bc, msg);
 
             av_log(avctx, AV_LOG_INFO,
                    "embedded message: \"%s\"\n", (char *)msg);
         }
 
-        skip_bits(bitbuf, 2);
-        skip_bits(bitbuf, 2);
-        skip_bits1(bitbuf);
+        bitstream_skip(bc, 2);
+        bitstream_skip(bc, 2);
+        bitstream_skip(bc, 1);
 
         /* load frame size */
-        frame_size_code = get_bits(bitbuf, 3);
+        frame_size_code = bitstream_read(bc, 3);
 
         if (frame_size_code == 7) {
             /* load width, height (12 bits each) */
-            s->width  = get_bits(bitbuf, 12);
-            s->height = get_bits(bitbuf, 12);
+            s->width  = bitstream_read(bc, 12);
+            s->height = bitstream_read(bc, 12);
 
             if (!s->width || !s->height)
                 return AVERROR_INVALIDDATA;
@@ -587,22 +583,22 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame)
     }
 
     /* unknown fields */
-    if (get_bits1(bitbuf) == 1) {
-        skip_bits1(bitbuf);    /* use packet checksum if (1) */
-        skip_bits1(bitbuf);    /* component checksums after image data if (1) */
+    if (bitstream_read_bit(bc) == 1) {
+        bitstream_skip(bc, 1); /* use packet checksum if (1) */
+        bitstream_skip(bc, 1); /* component checksums after image data if (1) */
 
-        if (get_bits(bitbuf, 2) != 0)
+        if (bitstream_read(bc, 2) != 0)
             return AVERROR_INVALIDDATA;
     }
 
-    if (get_bits1(bitbuf) == 1) {
-        skip_bits1(bitbuf);
-        skip_bits(bitbuf, 4);
-        skip_bits1(bitbuf);
-        skip_bits(bitbuf, 2);
+    if (bitstream_read_bit(bc) == 1) {
+        bitstream_skip(bc, 1);
+        bitstream_skip(bc, 4);
+        bitstream_skip(bc, 1);
+        bitstream_skip(bc, 2);
 
-        while (get_bits1(bitbuf) == 1)
-            skip_bits(bitbuf, 8);
+        while (bitstream_read_bit(bc) == 1)
+            bitstream_skip(bc, 8);
     }
 
     return 0;
@@ -620,10 +616,10 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
     svq1_pmv *pmv;
 
     /* initialize bit buffer */
-    init_get_bits(&s->gb, buf, buf_size * 8);
+    bitstream_init(&s->bc, buf, buf_size * 8);
 
     /* decode frame header */
-    s->frame_code = get_bits(&s->gb, 22);
+    s->frame_code = bitstream_read(&s->bc, 22);
 
     if ((s->frame_code & ~0x70) || !(s->frame_code & 0x60))
         return AVERROR_INVALIDDATA;
@@ -645,19 +641,20 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
 
         memcpy(s->pkt_swapped, buf, buf_size);
         buf = s->pkt_swapped;
-        init_get_bits(&s->gb, buf, buf_size * 8);
-        skip_bits(&s->gb, 22);
 
         src = (uint32_t *)(s->pkt_swapped + 4);
 
         for (i = 0; i < 4; i++)
             src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i];
+
+        bitstream_init(&s->bc, buf, buf_size * 8);
+        bitstream_skip(&s->bc, 22);
     }
 
     result = svq1_decode_frame_header(avctx, cur);
 
     if (result != 0) {
-        av_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result);
+        ff_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result);
         return result;
     }
 
@@ -686,7 +683,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
             width    = FFALIGN(s->width,  16);
             height   = FFALIGN(s->height, 16);
         } else {
-            if (avctx->flags & CODEC_FLAG_GRAY)
+            if (avctx->flags & AV_CODEC_FLAG_GRAY)
                 break;
             width    = FFALIGN(s->width  / 4, 16);
             height   = FFALIGN(s->height / 4, 16);
@@ -698,7 +695,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
             /* keyframe */
             for (y = 0; y < height; y += 16) {
                 for (x = 0; x < width; x += 16) {
-                    result = svq1_decode_block_intra(&s->gb, &current[x],
+                    result = svq1_decode_block_intra(&s->bc, &current[x],
                                                      linesize);
                     if (result != 0) {
                         av_log(avctx, AV_LOG_INFO,
@@ -724,11 +721,11 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
             for (y = 0; y < height; y += 16) {
                 for (x = 0; x < width; x += 16) {
                     result = svq1_decode_delta_block(avctx, &s->hdsp,
-                                                     &s->gb, &current[x],
+                                                     &s->bc, &current[x],
                                                      previous, linesize,
                                                      pmv, x, y, width, height);
                     if (result != 0) {
-                        av_dlog(avctx,
+                        ff_dlog(avctx,
                                 "Error in svq1_decode_delta_block %i\n",
                                 result);
                         goto err;
@@ -839,7 +836,7 @@ AVCodec ff_svq1_decoder = {
     .init           = svq1_decode_init,
     .close          = svq1_decode_end,
     .decode         = svq1_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = AV_CODEC_CAP_DR1,
     .flush          = svq1_flush,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
                                                      AV_PIX_FMT_NONE },