]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/vp3.c
libilbc: support for latest git of libilbc
[ffmpeg] / libavcodec / vp3.c
index 2de3ebdc8993f64644a1225a7014ba06e8aaf2b3..26374cc5d3bc86ab7f6f6d62bdadc923b30cc6ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2004 the ffmpeg project
+ * Copyright (C) 2003-2004 The FFmpeg project
  *
  * This file is part of Libav.
  *
@@ -171,6 +171,8 @@ typedef struct Vp3DecodeContext {
     Vp3Fragment *all_fragments;
     int fragment_start[3];
     int data_offset[3];
+    uint8_t offset_x;
+    uint8_t offset_y;
 
     int8_t (*motion_val[2])[2];
 
@@ -930,14 +932,14 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
     int num_coeffs      = s->num_coded_frags[plane][coeff_index];
     int16_t *dct_tokens = s->dct_tokens[plane][coeff_index];
 
-    /* local references to structure members to avoid repeated deferences */
+    /* local references to structure members to avoid repeated dereferences */
     int *coded_fragment_list   = s->coded_fragment_list[plane];
     Vp3Fragment *all_fragments = s->all_fragments;
     VLC_TYPE(*vlc_table)[2] = table->table;
 
     if (num_coeffs < 0)
         av_log(s->avctx, AV_LOG_ERROR,
-               "Invalid number of coefficents at level %d\n", coeff_index);
+               "Invalid number of coefficients at level %d\n", coeff_index);
 
     if (eob_run > num_coeffs) {
         coeff_i      =
@@ -1019,7 +1021,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
     if (blocks_ended > s->num_coded_frags[plane][coeff_index])
         av_log(s->avctx, AV_LOG_ERROR, "More blocks ended than coded!\n");
 
-    // decrement the number of blocks that have higher coeffecients for each
+    // decrement the number of blocks that have higher coefficients for each
     // EOB run at this level
     if (blocks_ended)
         for (i = coeff_index + 1; i < 64; i++)
@@ -1079,7 +1081,7 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
         return residual_eob_run;
 
     /* reverse prediction of the C-plane DC coefficients */
-    if (!(s->avctx->flags & CODEC_FLAG_GRAY)) {
+    if (!(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
         reverse_dc_prediction(s, s->fragment_start[1],
                               s->fragment_width[1], s->fragment_height[1]);
         reverse_dc_prediction(s, s->fragment_start[2],
@@ -1108,7 +1110,7 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
         c_tables[i] = &s->ac_vlc_4[ac_c_table];
     }
 
-    /* decode all AC coefficents */
+    /* decode all AC coefficients */
     for (i = 1; i <= 63; i++) {
         residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i,
                                        0, residual_eob_run);
@@ -1306,7 +1308,7 @@ static void apply_loop_filter(Vp3DecodeContext *s, int plane,
         for (x = 0; x < width; x++) {
             /* This code basically just deblocks on the edges of coded blocks.
              * However, it has to be much more complicated because of the
-             * braindamaged deblock ordering used in VP3/Theora. Order matters
+             * brain damaged deblock ordering used in VP3/Theora. Order matters
              * because some pixels get filtered twice. */
             if (s->all_fragments[fragment].coding_method != MODE_COPY) {
                 /* do not perform left edge filter for left columns frags */
@@ -1405,18 +1407,18 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
     int offset[AV_NUM_DATA_POINTERS];
 
     if (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_FRAME) {
-        int y_flipped = s->flipped_image ? s->avctx->height - y : y;
+        int y_flipped = s->flipped_image ? s->height - y : y;
 
         /* At the end of the frame, report INT_MAX instead of the height of
          * the frame. This makes the other threads' ff_thread_await_progress()
          * calls cheaper, because they don't have to clip their values. */
         ff_thread_report_progress(&s->current_frame,
-                                  y_flipped == s->avctx->height ? INT_MAX
-                                                                : y_flipped - 1,
+                                  y_flipped == s->height ? INT_MAX
+                                                         : y_flipped - 1,
                                   0);
     }
 
-    if (s->avctx->draw_horiz_band == NULL)
+    if (!s->avctx->draw_horiz_band)
         return;
 
     h = y - s->last_slice_end;
@@ -1424,7 +1426,7 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
     y -= h;
 
     if (!s->flipped_image)
-        y = s->avctx->height - y - h;
+        y = s->height - y - h;
 
     cy        = y >> s->chroma_y_shift;
     offset[0] = s->current_frame.f->linesize[0] * y;
@@ -1502,7 +1504,7 @@ static void render_slice(Vp3DecodeContext *s, int slice)
 
         if (!s->flipped_image)
             stride = -stride;
-        if (CONFIG_GRAY && plane && (s->avctx->flags & CODEC_FLAG_GRAY))
+        if (CONFIG_GRAY && plane && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
             continue;
 
         /* for each superblock row in the slice (both of them)... */
@@ -1579,7 +1581,7 @@ static void render_slice(Vp3DecodeContext *s, int slice)
                             /* Note, it is possible to implement all MC cases
                              * with put_no_rnd_pixels_l2 which would look more
                              * like the VP3 source but this would be slower as
-                             * put_no_rnd_pixels_tab is better optimzed */
+                             * put_no_rnd_pixels_tab is better optimized */
                             if (motion_halfpel_index != 3) {
                                 s->hdsp.put_no_rnd_pixels_tab[1][motion_halfpel_index](
                                     output_plane + first_pixel,
@@ -1721,12 +1723,12 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
         s->version = 1;
 
     s->avctx  = avctx;
-    s->width  = FFALIGN(avctx->width, 16);
-    s->height = FFALIGN(avctx->height, 16);
+    s->width  = FFALIGN(avctx->coded_width, 16);
+    s->height = FFALIGN(avctx->coded_height, 16);
     if (avctx->pix_fmt == AV_PIX_FMT_NONE)
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
-    ff_hpeldsp_init(&s->hdsp, avctx->flags | CODEC_FLAG_BITEXACT);
+    ff_hpeldsp_init(&s->hdsp, avctx->flags | AV_CODEC_FLAG_BITEXACT);
     ff_videodsp_init(&s->vdsp, 8);
     ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
 
@@ -2115,10 +2117,17 @@ static int vp3_decode_frame(AVCodecContext *avctx,
         int row = (s->height >> (3 + (i && s->chroma_y_shift))) - 1;
         apply_loop_filter(s, i, row, row + 1);
     }
-    vp3_draw_horiz_band(s, s->avctx->height);
+    vp3_draw_horiz_band(s, s->height);
 
+    /* output frame, offset as needed */
     if ((ret = av_frame_ref(data, s->current_frame.f)) < 0)
         return ret;
+    for (i = 0; i < 3; i++) {
+        AVFrame *dst = data;
+        int off = (s->offset_x >> (i && s->chroma_y_shift)) +
+                  (s->offset_y >> (i && s->chroma_y_shift)) * dst->linesize[i];
+        dst->data[i] += off;
+    }
     *got_frame = 1;
 
     if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
@@ -2149,7 +2158,7 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb)
             return -1;
         }
         token = get_bits(gb, 5);
-        av_dlog(avctx, "hti %d hbits %x token %d entry : %d size %d\n",
+        ff_dlog(avctx, "hti %d hbits %x token %d entry : %d size %d\n",
                 s->hti, s->hbits, token, s->entries, s->huff_code_size);
         s->huffman_table[s->hti][token][0] = s->hbits;
         s->huffman_table[s->hti][token][1] = s->huff_code_size;
@@ -2198,7 +2207,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
 {
     Vp3DecodeContext *s = avctx->priv_data;
     int visible_width, visible_height, colorspace;
-    int offset_x = 0, offset_y = 0;
+    uint8_t offset_x = 0, offset_y = 0;
     int ret;
     AVRational fps, aspect;
 
@@ -2226,6 +2235,17 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
         offset_y = get_bits(gb, 8); /* offset y, from bottom */
     }
 
+    /* sanity check */
+    if (av_image_check_size(visible_width, visible_height, 0, avctx) < 0 ||
+        visible_width  + offset_x > s->width ||
+        visible_height + offset_y > s->height) {
+        av_log(s, AV_LOG_ERROR,
+               "Invalid frame dimensions - w:%d h:%d x:%d y:%d (%dx%d).\n",
+               visible_width, visible_height, offset_x, offset_y,
+               s->width, s->height);
+        return AVERROR_INVALIDDATA;
+    }
+
     fps.num = get_bits_long(gb, 32);
     fps.den = get_bits_long(gb, 32);
     if (fps.num && fps.den) {
@@ -2233,7 +2253,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
             av_log(avctx, AV_LOG_ERROR, "Invalid framerate\n");
             return AVERROR_INVALIDDATA;
         }
-        av_reduce(&avctx->time_base.num, &avctx->time_base.den,
+        av_reduce(&avctx->framerate.den, &avctx->framerate.num,
                   fps.den, fps.num, 1 << 30);
     }
 
@@ -2243,6 +2263,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
         av_reduce(&avctx->sample_aspect_ratio.num,
                   &avctx->sample_aspect_ratio.den,
                   aspect.num, aspect.den, 1 << 30);
+        ff_set_sar(avctx, avctx->sample_aspect_ratio);
     }
 
     if (s->theora < 0x030200)
@@ -2258,16 +2279,25 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
         skip_bits(gb, 3); /* reserved */
     }
 
-//    align_get_bits(gb);
-
-    if (visible_width  <= s->width  && visible_width  > s->width  - 16 &&
-        visible_height <= s->height && visible_height > s->height - 16 &&
-        !offset_x && (offset_y == s->height - visible_height))
-        ret = ff_set_dimensions(avctx, visible_width, visible_height);
-    else
-        ret = ff_set_dimensions(avctx, s->width, s->height);
+    ret = ff_set_dimensions(avctx, s->width, s->height);
     if (ret < 0)
         return ret;
+    if (!(avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) &&
+        (visible_width != s->width || visible_height != s->height)) {
+        avctx->width  = visible_width;
+        avctx->height = visible_height;
+        // translate offsets from theora axis ([0,0] lower left)
+        // to normal axis ([0,0] upper left)
+        s->offset_x = offset_x;
+        s->offset_y = s->height - visible_height - offset_y;
+
+        if ((s->offset_x & 0x1F) && !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
+            s->offset_x &= ~0x1F;
+            av_log(avctx, AV_LOG_WARNING, "Reducing offset_x from %d to %d"
+                   "chroma samples to preserve alignment.\n",
+                   offset_x, s->offset_x);
+        }
+    }
 
     if (colorspace == 1)
         avctx->color_primaries = AVCOL_PRI_BT470M;
@@ -2465,8 +2495,8 @@ AVCodec ff_theora_decoder = {
     .init                  = theora_decode_init,
     .close                 = vp3_decode_end,
     .decode                = vp3_decode_frame,
-    .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
-                             CODEC_CAP_FRAME_THREADS,
+    .capabilities          = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
+                             AV_CODEC_CAP_FRAME_THREADS,
     .flush                 = vp3_decode_flush,
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context)
@@ -2482,8 +2512,8 @@ AVCodec ff_vp3_decoder = {
     .init                  = vp3_decode_init,
     .close                 = vp3_decode_end,
     .decode                = vp3_decode_frame,
-    .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
-                             CODEC_CAP_FRAME_THREADS,
+    .capabilities          = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
+                             AV_CODEC_CAP_FRAME_THREADS,
     .flush                 = vp3_decode_flush,
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context),