On 12/12/14 04:35, Vittorio Giovara wrote:
> 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];
are we sure it won't get over the buffer? (are the offsets validated
somewhere?).
> + 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);
Is that enough?
> + 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);
> + }
> + }
lu
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel