lavc/prores: restore pict_type and key_frame setting.
[ffmpeg.git] / libavcodec / proresdec2.c
index a96af4f..bd6404a 100644 (file)
 
 //#define DEBUG
 
-#define A32_BITSTREAM_READER
+#define LONG_BITSTREAM_READER
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "simple_idct.h"
 #include "proresdec.h"
 
@@ -69,13 +70,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     avctx->bits_per_raw_sample = 10;
 
-    dsputil_init(&ctx->dsp, avctx);
+    ff_dsputil_init(&ctx->dsp, avctx);
     ff_proresdsp_init(&ctx->prodsp, avctx);
 
-    avctx->coded_frame = &ctx->frame;
-    ctx->frame.type = FF_I_TYPE;
-    ctx->frame.key_frame = 1;
-
     ff_init_scantable_permutation(idct_permutation,
                                   ctx->prodsp.idct_permutation_type);
 
@@ -122,17 +119,21 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
         ctx->scan = ctx->progressive_scan; // permuted
     } else {
         ctx->scan = ctx->interlaced_scan; // permuted
-        ctx->frame.interlaced_frame = 1;
-        ctx->frame.top_field_first = ctx->frame_type == 1;
+        ctx->frame->interlaced_frame = 1;
+        ctx->frame->top_field_first = ctx->frame_type == 1;
     }
 
-    avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? PIX_FMT_YUV444P10 : PIX_FMT_YUV422P10;
+    avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10;
 
     ptr   = buf + 20;
     flags = buf[19];
     av_dlog(avctx, "flags %x\n", flags);
 
     if (flags & 2) {
+        if(buf + data_size - ptr < 64) {
+            av_log(avctx, AV_LOG_ERROR, "Header truncated\n");
+            return -1;
+        }
         permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr);
         ptr += 64;
     } else {
@@ -140,6 +141,10 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
     }
 
     if (flags & 1) {
+        if(buf + data_size - ptr < 64) {
+            av_log(avctx, AV_LOG_ERROR, "Header truncated\n");
+            return -1;
+        }
         permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr);
     } else {
         memset(ctx->qmat_chroma, 4, 64);
@@ -277,7 +282,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons
             val = q;                                                    \
             SKIP_BITS(re, gb, q+1);                                     \
         }                                                               \
-    } while (0);                                                        \
+    } while (0)
 
 #define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1)))
 
@@ -285,10 +290,10 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons
 
 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
 
-static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
+static av_always_inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out,
                                               int blocks_per_slice)
 {
-    DCTELEM prev_dc;
+    int16_t prev_dc;
     int code, i, sign;
 
     OPEN_READER(re, gb);
@@ -302,7 +307,7 @@ static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
     code = 5;
     sign = 0;
     for (i = 1; i < blocks_per_slice; i++, out += 64) {
-        DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6)]);
+        DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]);
         if(code) sign ^= -(code & 1);
         else     sign  = 0;
         prev_dc += (((code + 1) >> 1) ^ sign) - sign;
@@ -316,7 +321,7 @@ static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29,
 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C };
 
 static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb,
-                                              DCTELEM *out, int blocks_per_slice)
+                                              int16_t *out, int blocks_per_slice)
 {
     ProresContext *ctx = avctx->priv_data;
     int block_mask, sign;
@@ -325,7 +330,7 @@ static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitConte
     int log2_block_count = av_log2(blocks_per_slice);
 
     OPEN_READER(re, gb);
-
+    UPDATE_CACHE(re, gb);                                           \
     run   = 4;
     level = 2;
 
@@ -333,7 +338,7 @@ static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitConte
     block_mask = blocks_per_slice - 1;
 
     for (pos = block_mask;;) {
-        bits_left = gb->size_in_bits - (((uint8_t*)re_buffer_ptr - gb->buffer)*8 - 32 + re_bit_count);
+        bits_left = gb->size_in_bits - re_index;
         if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left)))
             break;
 
@@ -358,13 +363,13 @@ static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitConte
 }
 
 static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice,
-                              uint8_t *dst, int dst_stride,
+                              uint16_t *dst, int dst_stride,
                               const uint8_t *buf, unsigned buf_size,
                               const int16_t *qmat)
 {
     ProresContext *ctx = avctx->priv_data;
-    LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]);
-    DCTELEM *block;
+    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);
+    int16_t *block;
     GetBitContext gb;
     int i, blocks_per_slice = slice->mb_count<<2;
 
@@ -379,22 +384,22 @@ static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice,
     block = blocks;
     for (i = 0; i < slice->mb_count; i++) {
         ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat);
-        ctx->prodsp.idct_put(dst+16, dst_stride, block+(1<<6), qmat);
-        ctx->prodsp.idct_put(dst+8*dst_stride, dst_stride, block+(2<<6), qmat);
-        ctx->prodsp.idct_put(dst+8*dst_stride+16, dst_stride, block+(3<<6), qmat);
+        ctx->prodsp.idct_put(dst             +8, dst_stride, block+(1<<6), qmat);
+        ctx->prodsp.idct_put(dst+4*dst_stride  , dst_stride, block+(2<<6), qmat);
+        ctx->prodsp.idct_put(dst+4*dst_stride+8, dst_stride, block+(3<<6), qmat);
         block += 4*64;
-        dst += 32;
+        dst += 16;
     }
 }
 
 static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice,
-                                uint8_t *dst, int dst_stride,
+                                uint16_t *dst, int dst_stride,
                                 const uint8_t *buf, unsigned buf_size,
                                 const int16_t *qmat, int log2_blocks_per_mb)
 {
     ProresContext *ctx = avctx->priv_data;
-    LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]);
-    DCTELEM *block;
+    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);
+    int16_t *block;
     GetBitContext gb;
     int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb;
 
@@ -410,9 +415,9 @@ static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice,
     for (i = 0; i < slice->mb_count; i++) {
         for (j = 0; j < log2_blocks_per_mb; j++) {
             ctx->prodsp.idct_put(dst,              dst_stride, block+(0<<6), qmat);
-            ctx->prodsp.idct_put(dst+8*dst_stride, dst_stride, block+(1<<6), qmat);
+            ctx->prodsp.idct_put(dst+4*dst_stride, dst_stride, block+(1<<6), qmat);
             block += 2*64;
-            dst += 16;
+            dst += 8;
         }
     }
 }
@@ -422,7 +427,7 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
     ProresContext *ctx = avctx->priv_data;
     SliceContext *slice = &ctx->slices[jobnr];
     const uint8_t *buf = slice->data;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = ctx->frame;
     int i, hdr_size, qscale, log2_chroma_blocks_per_mb;
     int luma_stride, chroma_stride;
     int y_data_size, u_data_size, v_data_size;
@@ -431,6 +436,7 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
     int16_t qmat_chroma_scaled[64];
     int mb_x_shift;
 
+    slice->ret = -1;
     //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n",
     //       jobnr, slice->mb_count, slice->mb_x, slice->mb_y);
 
@@ -443,7 +449,8 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
     v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size;
     if (hdr_size > 7) v_data_size = AV_RB16(buf + 6);
 
-    if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0) {
+    if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0
+        || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){
         av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n");
         return -1;
     }
@@ -463,7 +470,7 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
         chroma_stride = pic->linesize[1] << 1;
     }
 
-    if (avctx->pix_fmt == PIX_FMT_YUV444P10) {
+    if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
         mb_x_shift = 5;
         log2_chroma_blocks_per_mb = 2;
     } else {
@@ -475,46 +482,47 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
     dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
     dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
 
-    if (ctx->frame_type && ctx->first_field ^ ctx->frame.top_field_first) {
+    if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) {
         dest_y += pic->linesize[0];
         dest_u += pic->linesize[1];
         dest_v += pic->linesize[2];
     }
 
-    decode_slice_luma(avctx, slice, dest_y, luma_stride,
+    decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride,
                       buf, y_data_size, qmat_luma_scaled);
 
     if (!(avctx->flags & CODEC_FLAG_GRAY)) {
-        decode_slice_chroma(avctx, slice, dest_u, chroma_stride,
+        decode_slice_chroma(avctx, slice, (uint16_t*)dest_u, chroma_stride,
                             buf + y_data_size, u_data_size,
                             qmat_chroma_scaled, log2_chroma_blocks_per_mb);
-        decode_slice_chroma(avctx, slice, dest_v, chroma_stride,
+        decode_slice_chroma(avctx, slice, (uint16_t*)dest_v, chroma_stride,
                             buf + y_data_size + u_data_size, v_data_size,
                             qmat_chroma_scaled, log2_chroma_blocks_per_mb);
     }
 
+    slice->ret = 0;
     return 0;
 }
 
 static int decode_picture(AVCodecContext *avctx)
 {
     ProresContext *ctx = avctx->priv_data;
-    int i, threads_ret[ctx->slice_count];
+    int i;
 
-    avctx->execute2(avctx, decode_slice_thread, NULL, threads_ret, ctx->slice_count);
+    avctx->execute2(avctx, decode_slice_thread, NULL, NULL, ctx->slice_count);
 
     for (i = 0; i < ctx->slice_count; i++)
-        if (threads_ret[i] < 0)
-            return threads_ret[i];
+        if (ctx->slices[i].ret < 0)
+            return ctx->slices[i].ret;
 
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     ProresContext *ctx = avctx->priv_data;
-    AVFrame *frame = avctx->coded_frame;
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     int frame_hdr_size, pic_size;
@@ -524,6 +532,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
         return -1;
     }
 
+    ctx->frame = frame;
+    ctx->frame->pict_type = AV_PICTURE_TYPE_I;
+    ctx->frame->key_frame = 1;
     ctx->first_field = 1;
 
     buf += 8;
@@ -536,10 +547,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     buf += frame_hdr_size;
     buf_size -= frame_hdr_size;
 
-    if (frame->data[0])
-        avctx->release_buffer(avctx, frame);
-
-    if (avctx->get_buffer(avctx, frame) < 0)
+    if (ff_get_buffer(avctx, frame, 0) < 0)
         return -1;
 
  decode_picture:
@@ -562,8 +570,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
         goto decode_picture;
     }
 
-    *data_size = sizeof(AVFrame);
-    *(AVFrame*)data = *frame;
+    *got_frame      = 1;
 
     return avpkt->size;
 }
@@ -572,9 +579,6 @@ static av_cold int decode_close(AVCodecContext *avctx)
 {
     ProresContext *ctx = avctx->priv_data;
 
-    AVFrame *frame = avctx->coded_frame;
-    if (frame->data[0])
-        avctx->release_buffer(avctx, frame);
     av_freep(&ctx->slices);
 
     return 0;
@@ -583,7 +587,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
 AVCodec ff_prores_decoder = {
     .name           = "prores",
     .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = CODEC_ID_PRORES,
+    .id             = AV_CODEC_ID_PRORES,
     .priv_data_size = sizeof(ProresContext),
     .init           = decode_init,
     .close          = decode_close,