/*
- * Copyright (C) 2003-2004 the ffmpeg project
+ * Copyright (C) 2003-2004 The FFmpeg project
*
* This file is part of Libav.
*
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];
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 =
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++)
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],
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);
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 */
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;
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;
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)... */
/* 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,
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);
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)) {
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;
{
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;
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) {
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);
}
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)
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;
.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)
.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),