mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-04-19 09:02:26 +02:00
Merge commit '67fc8a15e4182ea111cfcd05897709f09d99a33a'
* commit '67fc8a15e4182ea111cfcd05897709f09d99a33a': theora: support different visible and coded frame size Conflicts: libavcodec/vp3.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
6fcdcc414b
@ -175,6 +175,8 @@ typedef struct Vp3DecodeContext {
|
|||||||
Vp3Fragment *all_fragments;
|
Vp3Fragment *all_fragments;
|
||||||
int fragment_start[3];
|
int fragment_start[3];
|
||||||
int data_offset[3];
|
int data_offset[3];
|
||||||
|
uint8_t offset_x;
|
||||||
|
uint8_t offset_y;
|
||||||
|
|
||||||
int8_t (*motion_val[2])[2];
|
int8_t (*motion_val[2])[2];
|
||||||
|
|
||||||
@ -1418,13 +1420,13 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
|
|||||||
int offset[AV_NUM_DATA_POINTERS];
|
int offset[AV_NUM_DATA_POINTERS];
|
||||||
|
|
||||||
if (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_FRAME) {
|
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
|
/* 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()
|
* the frame. This makes the other threads' ff_thread_await_progress()
|
||||||
* calls cheaper, because they don't have to clip their values. */
|
* calls cheaper, because they don't have to clip their values. */
|
||||||
ff_thread_report_progress(&s->current_frame,
|
ff_thread_report_progress(&s->current_frame,
|
||||||
y_flipped == s->avctx->height ? INT_MAX
|
y_flipped == s->height ? INT_MAX
|
||||||
: y_flipped - 1,
|
: y_flipped - 1,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
@ -1437,7 +1439,7 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
|
|||||||
y -= h;
|
y -= h;
|
||||||
|
|
||||||
if (!s->flipped_image)
|
if (!s->flipped_image)
|
||||||
y = s->avctx->height - y - h;
|
y = s->height - y - h;
|
||||||
|
|
||||||
cy = y >> s->chroma_y_shift;
|
cy = y >> s->chroma_y_shift;
|
||||||
offset[0] = s->current_frame.f->linesize[0] * y;
|
offset[0] = s->current_frame.f->linesize[0] * y;
|
||||||
@ -1730,8 +1732,8 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
|
|||||||
s->version = 1;
|
s->version = 1;
|
||||||
|
|
||||||
s->avctx = avctx;
|
s->avctx = avctx;
|
||||||
s->width = FFALIGN(avctx->width, 16);
|
s->width = FFALIGN(avctx->coded_width, 16);
|
||||||
s->height = FFALIGN(avctx->height, 16);
|
s->height = FFALIGN(avctx->coded_height, 16);
|
||||||
if (avctx->codec_id != AV_CODEC_ID_THEORA)
|
if (avctx->codec_id != AV_CODEC_ID_THEORA)
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||||
avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
|
avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
|
||||||
@ -2151,10 +2153,17 @@ static int vp3_decode_frame(AVCodecContext *avctx,
|
|||||||
int row = (s->height >> (3 + (i && s->chroma_y_shift))) - 1;
|
int row = (s->height >> (3 + (i && s->chroma_y_shift))) - 1;
|
||||||
apply_loop_filter(s, i, row, row + 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)
|
if ((ret = av_frame_ref(data, s->current_frame.f)) < 0)
|
||||||
return ret;
|
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;
|
*got_frame = 1;
|
||||||
|
|
||||||
if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
|
if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
|
||||||
@ -2234,7 +2243,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
|
|||||||
{
|
{
|
||||||
Vp3DecodeContext *s = avctx->priv_data;
|
Vp3DecodeContext *s = avctx->priv_data;
|
||||||
int visible_width, visible_height, colorspace;
|
int visible_width, visible_height, colorspace;
|
||||||
int offset_x = 0, offset_y = 0;
|
uint8_t offset_x = 0, offset_y = 0;
|
||||||
int ret;
|
int ret;
|
||||||
AVRational fps, aspect;
|
AVRational fps, aspect;
|
||||||
|
|
||||||
@ -2262,6 +2271,17 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
|
|||||||
offset_y = get_bits(gb, 8); /* offset y, from bottom */
|
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.num = get_bits_long(gb, 32);
|
||||||
fps.den = get_bits_long(gb, 32);
|
fps.den = get_bits_long(gb, 32);
|
||||||
if (fps.num && fps.den) {
|
if (fps.num && fps.den) {
|
||||||
@ -2299,16 +2319,25 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
|
|||||||
skip_bits(gb, 3); /* reserved */
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
if (!(avctx->flags2 & 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 & 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)
|
if (colorspace == 1)
|
||||||
avctx->color_primaries = AVCOL_PRI_BT470M;
|
avctx->color_primaries = AVCOL_PRI_BT470M;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user