mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-05-13 21:26:33 +02:00
finally working with old theora bitstream (flipped image), the only sample I have is decoded successfully (theora.ogg)
Originally committed as revision 2526 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
bcbecff13f
commit
9a7ad92531
106
libavcodec/vp3.c
106
libavcodec/vp3.c
@ -222,6 +222,7 @@ typedef struct Vp3DecodeContext {
|
|||||||
AVFrame current_frame;
|
AVFrame current_frame;
|
||||||
int keyframe;
|
int keyframe;
|
||||||
DSPContext dsp;
|
DSPContext dsp;
|
||||||
|
int flipped_image;
|
||||||
|
|
||||||
int quality_index;
|
int quality_index;
|
||||||
int last_quality_index;
|
int last_quality_index;
|
||||||
@ -2365,7 +2366,8 @@ static void render_fragments(Vp3DecodeContext *s,
|
|||||||
output_plane = s->current_frame.data[0];
|
output_plane = s->current_frame.data[0];
|
||||||
last_plane = s->last_frame.data[0];
|
last_plane = s->last_frame.data[0];
|
||||||
golden_plane = s->golden_frame.data[0];
|
golden_plane = s->golden_frame.data[0];
|
||||||
stride = -s->current_frame.linesize[0];
|
stride = s->current_frame.linesize[0];
|
||||||
|
if (!s->flipped_image) stride = -stride;
|
||||||
upper_motion_limit = 7 * s->current_frame.linesize[0];
|
upper_motion_limit = 7 * s->current_frame.linesize[0];
|
||||||
lower_motion_limit = height * s->current_frame.linesize[0] + width - 8;
|
lower_motion_limit = height * s->current_frame.linesize[0] + width - 8;
|
||||||
} else if (plane == 1) {
|
} else if (plane == 1) {
|
||||||
@ -2373,7 +2375,8 @@ static void render_fragments(Vp3DecodeContext *s,
|
|||||||
output_plane = s->current_frame.data[1];
|
output_plane = s->current_frame.data[1];
|
||||||
last_plane = s->last_frame.data[1];
|
last_plane = s->last_frame.data[1];
|
||||||
golden_plane = s->golden_frame.data[1];
|
golden_plane = s->golden_frame.data[1];
|
||||||
stride = -s->current_frame.linesize[1];
|
stride = s->current_frame.linesize[1];
|
||||||
|
if (!s->flipped_image) stride = -stride;
|
||||||
upper_motion_limit = 7 * s->current_frame.linesize[1];
|
upper_motion_limit = 7 * s->current_frame.linesize[1];
|
||||||
lower_motion_limit = height * s->current_frame.linesize[1] + width - 8;
|
lower_motion_limit = height * s->current_frame.linesize[1] + width - 8;
|
||||||
} else {
|
} else {
|
||||||
@ -2381,7 +2384,8 @@ static void render_fragments(Vp3DecodeContext *s,
|
|||||||
output_plane = s->current_frame.data[2];
|
output_plane = s->current_frame.data[2];
|
||||||
last_plane = s->last_frame.data[2];
|
last_plane = s->last_frame.data[2];
|
||||||
golden_plane = s->golden_frame.data[2];
|
golden_plane = s->golden_frame.data[2];
|
||||||
stride = -s->current_frame.linesize[2];
|
stride = s->current_frame.linesize[2];
|
||||||
|
if (!s->flipped_image) stride = -stride;
|
||||||
upper_motion_limit = 7 * s->current_frame.linesize[2];
|
upper_motion_limit = 7 * s->current_frame.linesize[2];
|
||||||
lower_motion_limit = height * s->current_frame.linesize[2] + width - 8;
|
lower_motion_limit = height * s->current_frame.linesize[2] + width - 8;
|
||||||
}
|
}
|
||||||
@ -2436,6 +2440,7 @@ av_log(s->avctx, AV_LOG_ERROR, " help! got beefy vector! (%X, %X)\n", motion_x,
|
|||||||
if(src_x<0 || src_y<0 || src_x + 9 >= width || src_y + 9 >= height){
|
if(src_x<0 || src_y<0 || src_x + 9 >= width || src_y + 9 >= height){
|
||||||
uint8_t *temp= s->edge_emu_buffer;
|
uint8_t *temp= s->edge_emu_buffer;
|
||||||
if(stride<0) temp -= 9*stride;
|
if(stride<0) temp -= 9*stride;
|
||||||
|
else temp += 9*stride;
|
||||||
|
|
||||||
ff_emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, width, height);
|
ff_emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, width, height);
|
||||||
motion_source= temp;
|
motion_source= temp;
|
||||||
@ -2547,6 +2552,53 @@ static void vp3_calculate_pixel_addresses(Vp3DecodeContext *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: this should be merged with the above! */
|
||||||
|
static void theora_calculate_pixel_addresses(Vp3DecodeContext *s)
|
||||||
|
{
|
||||||
|
|
||||||
|
int i, x, y;
|
||||||
|
|
||||||
|
/* figure out the first pixel addresses for each of the fragments */
|
||||||
|
/* Y plane */
|
||||||
|
i = 0;
|
||||||
|
for (y = 1; y <= s->fragment_height; y++) {
|
||||||
|
for (x = 0; x < s->fragment_width; x++) {
|
||||||
|
s->all_fragments[i++].first_pixel =
|
||||||
|
s->golden_frame.linesize[0] * y * FRAGMENT_PIXELS -
|
||||||
|
s->golden_frame.linesize[0] +
|
||||||
|
x * FRAGMENT_PIXELS;
|
||||||
|
debug_init(" fragment %d, first pixel @ %d\n",
|
||||||
|
i-1, s->all_fragments[i-1].first_pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* U plane */
|
||||||
|
i = s->u_fragment_start;
|
||||||
|
for (y = 1; y <= s->fragment_height / 2; y++) {
|
||||||
|
for (x = 0; x < s->fragment_width / 2; x++) {
|
||||||
|
s->all_fragments[i++].first_pixel =
|
||||||
|
s->golden_frame.linesize[1] * y * FRAGMENT_PIXELS -
|
||||||
|
s->golden_frame.linesize[1] +
|
||||||
|
x * FRAGMENT_PIXELS;
|
||||||
|
debug_init(" fragment %d, first pixel @ %d\n",
|
||||||
|
i-1, s->all_fragments[i-1].first_pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* V plane */
|
||||||
|
i = s->v_fragment_start;
|
||||||
|
for (y = 1; y <= s->fragment_height / 2; y++) {
|
||||||
|
for (x = 0; x < s->fragment_width / 2; x++) {
|
||||||
|
s->all_fragments[i++].first_pixel =
|
||||||
|
s->golden_frame.linesize[2] * y * FRAGMENT_PIXELS -
|
||||||
|
s->golden_frame.linesize[2] +
|
||||||
|
x * FRAGMENT_PIXELS;
|
||||||
|
debug_init(" fragment %d, first pixel @ %d\n",
|
||||||
|
i-1, s->all_fragments[i-1].first_pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the ffmpeg/libavcodec API init function.
|
* This is the ffmpeg/libavcodec API init function.
|
||||||
*/
|
*/
|
||||||
@ -2709,16 +2761,23 @@ static int vp3_decode_frame(AVCodecContext *avctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->keyframe = !get_bits1(&gb);
|
s->keyframe = !get_bits1(&gb);
|
||||||
if (s->theora && s->keyframe)
|
if (s->theora)
|
||||||
{
|
{
|
||||||
if (get_bits1(&gb))
|
s->last_quality_index = s->quality_index;
|
||||||
av_log(s->avctx, AV_LOG_ERROR, "Theora: warning, unsupported keyframe coding type?!\n");
|
s->quality_index = get_bits(&gb, 6);
|
||||||
skip_bits(&gb, 2); /* reserved? */
|
if ( s->keyframe)
|
||||||
|
{
|
||||||
|
if (get_bits1(&gb))
|
||||||
|
av_log(s->avctx, AV_LOG_ERROR, "Theora: warning, unsupported keyframe coding type?!\n");
|
||||||
|
skip_bits(&gb, 2); /* reserved? */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
skip_bits(&gb, 1);
|
skip_bits(&gb, 1);
|
||||||
s->last_quality_index = s->quality_index;
|
s->last_quality_index = s->quality_index;
|
||||||
s->quality_index = get_bits(&gb, 6);
|
s->quality_index = get_bits(&gb, 6);
|
||||||
|
}
|
||||||
|
|
||||||
debug_vp3(" VP3 %sframe #%d: Q index = %d\n",
|
debug_vp3(" VP3 %sframe #%d: Q index = %d\n",
|
||||||
s->keyframe?"key":"", counter, s->quality_index);
|
s->keyframe?"key":"", counter, s->quality_index);
|
||||||
@ -2752,8 +2811,12 @@ static int vp3_decode_frame(AVCodecContext *avctx,
|
|||||||
|
|
||||||
/* time to figure out pixel addresses? */
|
/* time to figure out pixel addresses? */
|
||||||
if (!s->pixel_addresses_inited)
|
if (!s->pixel_addresses_inited)
|
||||||
vp3_calculate_pixel_addresses(s);
|
{
|
||||||
|
if (!s->flipped_image)
|
||||||
|
vp3_calculate_pixel_addresses(s);
|
||||||
|
else
|
||||||
|
theora_calculate_pixel_addresses(s);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* allocate a new current frame */
|
/* allocate a new current frame */
|
||||||
s->current_frame.reference = 3;
|
s->current_frame.reference = 3;
|
||||||
@ -2850,16 +2913,25 @@ static int vp3_decode_end(AVCodecContext *avctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* current version is 3.2.0 */
|
|
||||||
|
|
||||||
static int theora_decode_header(AVCodecContext *avctx, GetBitContext gb)
|
static int theora_decode_header(AVCodecContext *avctx, GetBitContext gb)
|
||||||
{
|
{
|
||||||
Vp3DecodeContext *s = avctx->priv_data;
|
Vp3DecodeContext *s = avctx->priv_data;
|
||||||
|
int major, minor, micro;
|
||||||
|
|
||||||
|
major = get_bits(&gb, 8); /* version major */
|
||||||
|
minor = get_bits(&gb, 8); /* version minor */
|
||||||
|
micro = get_bits(&gb, 8); /* version micro */
|
||||||
|
av_log(avctx, AV_LOG_INFO, "Theora bitstream version %d.%d.%d\n",
|
||||||
|
major, minor, micro);
|
||||||
|
|
||||||
|
/* 3.3.0 aka alpha3 has the same frame orientation as original vp3 */
|
||||||
|
/* but previous versions have the image flipped relative to vp3 */
|
||||||
|
if ((major <= 3) && (minor < 3))
|
||||||
|
{
|
||||||
|
s->flipped_image = 1;
|
||||||
|
av_log(avctx, AV_LOG_DEBUG, "Old (<alpha3) Theora bitstream, flipped image\n");
|
||||||
|
}
|
||||||
|
|
||||||
skip_bits(&gb, 8); /* version major */
|
|
||||||
skip_bits(&gb, 8); /* version minor */
|
|
||||||
skip_bits(&gb, 8); /* version micro */
|
|
||||||
|
|
||||||
s->width = get_bits(&gb, 16) << 4;
|
s->width = get_bits(&gb, 16) << 4;
|
||||||
s->height = get_bits(&gb, 16) << 4;
|
s->height = get_bits(&gb, 16) << 4;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user