]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dvdec.c
fate: Add dependencies for dct/fft/mdct/rdft tests
[ffmpeg] / libavcodec / dvdec.c
index 4b7dfeebeddfe261bd388008f145292e99ffb5d9..89f5821b0027a434f046df65d9535181da9d3635 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #include "libavutil/internal.h"
+#include "libavutil/imgutils.h"
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "internal.h"
@@ -43,6 +44,7 @@
 #include "put_bits.h"
 #include "simple_idct.h"
 #include "dvdata.h"
+#include "dv.h"
 
 typedef struct BlockInfo {
     const uint32_t *factor_table;
@@ -177,12 +179,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
             if (DV_PROFILE_IS_HD(s->sys)) {
                 mb->idct_put     = s->idct_put[0];
                 mb->scan_table   = s->dv_zigzag[0];
-                mb->factor_table = &s->sys->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64];
+                mb->factor_table = &s->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64];
                 is_field_mode[mb_index] |= !j && dct_mode;
             } else {
                 mb->idct_put     = s->idct_put[dct_mode && log2_blocksize == 3];
                 mb->scan_table   = s->dv_zigzag[dct_mode];
-                mb->factor_table = &s->sys->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 +
+                mb->factor_table = &s->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 +
                                                         (quant + ff_dv_quant_offset[class1])*64];
             }
             dc = dc << 2;
@@ -257,12 +259,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
         if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) ||
             (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
             (s->sys->height >= 720 && mb_y != 134)) {
-            y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
+            y_stride = (s->frame->linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
         } else {
             y_stride = (2 << log2_blocksize);
         }
-        y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize);
-        linesize = s->picture.linesize[0] << is_field_mode[mb_index];
+        y_ptr = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << log2_blocksize);
+        linesize = s->frame->linesize[0] << is_field_mode[mb_index];
         mb[0]    .idct_put(y_ptr                                   , linesize, block + 0*64);
         if (s->sys->video_stype == 4) { /* SD 422 */
             mb[2].idct_put(y_ptr + (1 << log2_blocksize)           , linesize, block + 2*64);
@@ -275,19 +277,19 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
         block += 4*64;
 
         /* idct_put'ting chrominance */
-        c_offset = (((mb_y >>  (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] +
+        c_offset = (((mb_y >>  (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] +
                      (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize);
         for (j = 2; j; j--) {
-            uint8_t *c_ptr = s->picture.data[j] + c_offset;
+            uint8_t *c_ptr = s->frame->data[j] + c_offset;
             if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
                   uint64_t aligned_pixels[64/8];
                   uint8_t *pixels = (uint8_t*)aligned_pixels;
                   uint8_t *c_ptr1, *ptr1;
                   int x, y;
                   mb->idct_put(pixels, 8, block);
-                  for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
+                  for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->frame->linesize[j], pixels += 8) {
                       ptr1   = pixels + (1 << (log2_blocksize - 1));
-                      c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize);
+                      c_ptr1 = c_ptr + (s->frame->linesize[j] << log2_blocksize);
                       for (x = 0; x < (1 << (log2_blocksize - 1)); x++) {
                           c_ptr[x]  = pixels[x];
                           c_ptr1[x] = ptr1[x];
@@ -296,8 +298,8 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
                   block += 64; mb++;
             } else {
                   y_stride = (mb_y == 134) ? (1 << log2_blocksize) :
-                                             s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
-                  linesize = s->picture.linesize[j] << is_field_mode[mb_index];
+                                             s->frame->linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
+                  linesize = s->frame->linesize[j] << is_field_mode[mb_index];
                   (mb++)->    idct_put(c_ptr           , linesize, block); block += 64;
                   if (s->sys->bpm == 8) {
                       (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64;
@@ -318,56 +320,61 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     DVVideoContext *s = avctx->priv_data;
     const uint8_t* vsc_pack;
-    int apt, is16_9;
+    int apt, is16_9, ret;
+    const DVprofile *sys;
 
-    s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size);
-    if (!s->sys || buf_size < s->sys->frame_size || ff_dv_init_dynamic_tables(s->sys)) {
+    sys = avpriv_dv_frame_profile(s->sys, buf, buf_size);
+    if (!sys || buf_size < sys->frame_size) {
         av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
         return -1; /* NOTE: we only accept several full frames */
     }
 
-    s->picture.key_frame = 1;
-    s->picture.pict_type = AV_PICTURE_TYPE_I;
+    if (sys != s->sys) {
+        ret = ff_dv_init_dynamic_tables(s, sys);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Error initializing the work tables.\n");
+            return ret;
+        }
+        s->sys = sys;
+    }
+
+    s->frame            = data;
+    s->frame->key_frame = 1;
+    s->frame->pict_type = AV_PICTURE_TYPE_I;
     avctx->pix_fmt   = s->sys->pix_fmt;
     avctx->time_base = s->sys->time_base;
-    avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
-    if (ff_get_buffer(avctx, &s->picture, 0) < 0) {
+
+    ret = ff_set_dimensions(avctx, s->sys->width, s->sys->height);
+    if (ret < 0)
+        return ret;
+
+    /* Determine the codec's sample_aspect ratio from the packet */
+    vsc_pack = buf + 80*5 + 48 + 5;
+    if ( *vsc_pack == dv_video_control ) {
+        apt = buf[4] & 0x07;
+        is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07)));
+        ff_set_sar(avctx, s->sys->sar[is16_9]);
+    }
+
+    if (ff_get_buffer(avctx, s->frame, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
-    s->picture.interlaced_frame = 1;
-    s->picture.top_field_first  = 0;
+    s->frame->interlaced_frame = 1;
+    s->frame->top_field_first  = 0;
 
     s->buf = buf;
-    avctx->execute(avctx, dv_decode_video_segment, s->sys->work_chunks, NULL,
+    avctx->execute(avctx, dv_decode_video_segment, s->work_chunks, NULL,
                    dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
 
     emms_c();
 
     /* return image */
     *got_frame = 1;
-    av_frame_move_ref(data, &s->picture);
-
-    /* Determine the codec's sample_aspect ratio from the packet */
-    vsc_pack = buf + 80*5 + 48 + 5;
-    if ( *vsc_pack == dv_video_control ) {
-        apt = buf[4] & 0x07;
-        is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07)));
-        avctx->sample_aspect_ratio = s->sys->sar[is16_9];
-    }
 
     return s->sys->frame_size;
 }
 
-static int dvvideo_close(AVCodecContext *c)
-{
-    DVVideoContext *s = c->priv_data;
-
-    av_frame_unref(&s->picture);
-
-    return 0;
-}
-
 AVCodec ff_dvvideo_decoder = {
     .name           = "dvvideo",
     .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
@@ -375,7 +382,6 @@ AVCodec ff_dvvideo_decoder = {
     .id             = AV_CODEC_ID_DVVIDEO,
     .priv_data_size = sizeof(DVVideoContext),
     .init           = ff_dvvideo_init,
-    .close          = dvvideo_close,
     .decode         = dvvideo_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
 };