]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/tscc2.c
mpeg12dec: move setting first_field to mpeg_field_start()
[ffmpeg] / libavcodec / tscc2.c
index 36287137ad8695502c59a0a663af60f0aa4889bf..d86428afc6f8a14a5e9fe26fb478bac11678dbbc 100644 (file)
  * TechSmith Screen Codec 2 decoder
  */
 
+#include <inttypes.h>
+
 #define BITSTREAM_READER_LE
 #include "avcodec.h"
-#include "get_bits.h"
+#include "bitstream.h"
 #include "bytestream.h"
+#include "internal.h"
+#include "mathops.h"
 #include "tscc2data.h"
 
 typedef struct TSCC2Context {
     AVCodecContext *avctx;
-    AVFrame        pic;
+    AVFrame       *pic;
     int            mb_width, mb_height;
     uint8_t        *slice_quants;
     int            quant[2];
     int            q[2][3];
-    GetBitContext  gb;
+    BitstreamContext bc;
 
     VLC            dc_vlc, nc_vlc[NUM_VLC_SETS], ac_vlc[NUM_VLC_SETS];
     int            block[16];
@@ -123,21 +127,21 @@ static void tscc2_idct4_put(int *in, int q[3], uint8_t *dst, int stride)
 static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set,
                            uint8_t *dst, int stride, int plane)
 {
-    GetBitContext *gb = &c->gb;
+    BitstreamContext *bc = &c->bc;
     int prev_dc, dc, nc, ac, bpos, val;
     int i, j, k, l;
 
-    if (get_bits1(gb)) {
-        if (get_bits1(gb)) {
-            val = get_bits(gb, 8);
+    if (bitstream_read_bit(bc)) {
+        if (bitstream_read_bit(bc)) {
+            val = bitstream_read(bc, 8);
             for (i = 0; i < 8; i++, dst += stride)
                 memset(dst, val, 16);
         } else {
-            if (get_bits_left(gb) < 16 * 8 * 8)
+            if (bitstream_bits_left(bc) < 16 * 8 * 8)
                 return AVERROR_INVALIDDATA;
             for (i = 0; i < 8; i++) {
                 for (j = 0; j < 16; j++)
-                    dst[j] = get_bits(gb, 8);
+                    dst[j] = bitstream_read(bc, 8);
                 dst += stride;
             }
         }
@@ -148,35 +152,35 @@ static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set,
     for (j = 0; j < 2; j++) {
         for (k = 0; k < 4; k++) {
             if (!(j | k)) {
-                dc = get_bits(gb, 8);
+                dc = bitstream_read(bc, 8);
             } else {
-                dc = get_vlc2(gb, c->dc_vlc.table, 9, 2);
+                dc = bitstream_read_vlc(bc, c->dc_vlc.table, 9, 2);
                 if (dc == -1)
                     return AVERROR_INVALIDDATA;
                 if (dc == 0x100)
-                    dc = get_bits(gb, 8);
+                    dc = bitstream_read(bc, 8);
             }
             dc          = (dc + prev_dc) & 0xFF;
             prev_dc     = dc;
             c->block[0] = dc;
 
-            nc = get_vlc2(gb, c->nc_vlc[vlc_set].table, 9, 1);
+            nc = bitstream_read_vlc(bc, c->nc_vlc[vlc_set].table, 9, 1);
             if (nc == -1)
                 return AVERROR_INVALIDDATA;
 
             bpos = 1;
             memset(c->block + 1, 0, 15 * sizeof(*c->block));
             for (l = 0; l < nc; l++) {
-                ac = get_vlc2(gb, c->ac_vlc[vlc_set].table, 9, 2);
+                ac = bitstream_read_vlc(bc, c->ac_vlc[vlc_set].table, 9, 2);
                 if (ac == -1)
                     return AVERROR_INVALIDDATA;
                 if (ac == 0x1000)
-                    ac = get_bits(gb, 12);
+                    ac = bitstream_read(bc, 12);
                 bpos += ac & 0xF;
                 if (bpos >= 16)
                     return AVERROR_INVALIDDATA;
                 val = sign_extend(ac >> 4, 8);
-                c->block[tscc2_zigzag[bpos++]] = val;
+                c->block[ff_zigzag_scan[bpos++]] = val;
             }
             tscc2_idct4_put(c->block, q, dst + k * 4, stride);
         }
@@ -191,7 +195,7 @@ static int tscc2_decode_slice(TSCC2Context *c, int mb_y,
     int i, mb_x, q, ret;
     int off;
 
-    init_get_bits(&c->gb, buf, buf_size * 8);
+    bitstream_init(&c->bc, buf, buf_size * 8);
 
     for (mb_x = 0; mb_x < c->mb_width; mb_x++) {
         q = c->slice_quants[mb_x + c->mb_width * mb_y];
@@ -199,9 +203,9 @@ static int tscc2_decode_slice(TSCC2Context *c, int mb_y,
         if (q == 0 || q == 3) // skip block
             continue;
         for (i = 0; i < 3; i++) {
-            off = mb_x * 16 + mb_y * 8 * c->pic.linesize[i];
+            off = mb_x * 16 + mb_y * 8 * c->pic->linesize[i];
             ret = tscc2_decode_mb(c, c->q[q - 1], c->quant[q - 1] - 2,
-                                  c->pic.data[i] + off, c->pic.linesize[i], i);
+                                  c->pic->data[i] + off, c->pic->linesize[i], i);
             if (ret)
                 return ret;
         }
@@ -211,7 +215,7 @@ static int tscc2_decode_slice(TSCC2Context *c, int mb_y,
 }
 
 static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
-                              int *data_size, AVPacket *avpkt)
+                              int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -225,21 +229,20 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
     bytestream2_init(&gb, buf, buf_size);
     frame_type = bytestream2_get_byte(&gb);
     if (frame_type > 1) {
-        av_log(avctx, AV_LOG_ERROR, "Incorrect frame type %d\n", frame_type);
+        av_log(avctx, AV_LOG_ERROR, "Incorrect frame type %"PRIu32"\n",
+               frame_type);
         return AVERROR_INVALIDDATA;
     }
 
-    c->pic.reference    = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
 
     if (frame_type == 0) {
-        *data_size      = sizeof(AVFrame);
-        *(AVFrame*)data = c->pic;
+        *got_frame      = 1;
+        if ((ret = av_frame_ref(data, c->pic)) < 0)
+            return ret;
 
         return buf_size;
     }
@@ -310,7 +313,7 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
             }
         }
         if (bytestream2_get_bytes_left(&gb) < size) {
-            av_log(avctx, AV_LOG_ERROR, "Invalid slice size (%d/%d)\n",
+            av_log(avctx, AV_LOG_ERROR, "Invalid slice size (%"PRIu32"/%u)\n",
                    size, bytestream2_get_bytes_left(&gb));
             return AVERROR_INVALIDDATA;
         }
@@ -322,13 +325,25 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
         bytestream2_skip(&gb, size);
     }
 
-    *data_size      = sizeof(AVFrame);
-    *(AVFrame*)data = c->pic;
+    *got_frame      = 1;
+    if ((ret = av_frame_ref(data, c->pic)) < 0)
+        return ret;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
 }
 
+static av_cold int tscc2_decode_end(AVCodecContext *avctx)
+{
+    TSCC2Context * const c = avctx->priv_data;
+
+    av_frame_free(&c->pic);
+    av_freep(&c->slice_quants);
+    free_vlcs(c);
+
+    return 0;
+}
+
 static av_cold int tscc2_decode_init(AVCodecContext *avctx)
 {
     TSCC2Context * const c = avctx->priv_data;
@@ -352,31 +367,23 @@ static av_cold int tscc2_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
-    avctx->coded_frame = &c->pic;
-
-    return 0;
-}
-
-static av_cold int tscc2_decode_end(AVCodecContext *avctx)
-{
-    TSCC2Context * const c = avctx->priv_data;
-
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    av_freep(&c->slice_quants);
-    free_vlcs(c);
+    c->pic = av_frame_alloc();
+    if (!c->pic) {
+        tscc2_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
     return 0;
 }
 
 AVCodec ff_tscc2_decoder = {
     .name           = "tscc2",
+    .long_name      = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TSCC2,
     .priv_data_size = sizeof(TSCC2Context),
     .init           = tscc2_decode_init,
     .close          = tscc2_decode_end,
     .decode         = tscc2_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"),
+    .capabilities   = AV_CODEC_CAP_DR1,
 };