Signed-off-by: Vittorio Giovara <[email protected]>
---
Blame j-b.
Vittorio

 libavcodec/vp3.c | 52 +++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index fec8766..5212046 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -171,6 +171,8 @@ typedef struct Vp3DecodeContext {
     Vp3Fragment *all_fragments;
     int fragment_start[3];
     int data_offset[3];
+    int offset_x;
+    int offset_y;
 
     int8_t (*motion_val[2])[2];
 
@@ -1405,14 +1407,14 @@ 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);
     }
 
@@ -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;
@@ -1721,8 +1723,8 @@ 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;
@@ -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)) {
@@ -2259,16 +2268,29 @@ 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 & CODEC_FLAG2_IGNORE_CROP) &&
+        (visible_width != s->width || visible_height != s->height)) {
+        av_log(s, AV_LOG_DEBUG, "w:%d h:%d x:%d y:%d (%dx%d)\n",
+               visible_width, visible_height, offset_x, offset_y,
+               s->width, 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 & 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;
-- 
1.9.3 (Apple Git-50)

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to