aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/vp3.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-01-16 20:02:37 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-01-20 17:55:24 +0100
commitbc15fcb8cfa87ef91e2b00ab5951c5b6dc78e72b (patch)
tree0f6c3a0274c9db124999528795adafb6761927f6 /libavcodec/vp3.c
parent7cb27d216d1caa2c6fbd957bc477def6baf2f3cb (diff)
downloadffmpeg-bc15fcb8cfa87ef91e2b00ab5951c5b6dc78e72b.tar.gz
theora: support midstream reconfiguration
Fixes Ticket868 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/vp3.c')
-rw-r--r--libavcodec/vp3.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 98e8e729d8..c768eb94ad 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -75,6 +75,10 @@ typedef struct Vp3Fragment {
/* special internal mode */
#define MODE_COPY 8
+static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb);
+static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb);
+
+
/* There are 6 preset schemes, plus a free-form scheme */
static const int ModeAlphabet[6][CODING_MODE_COUNT] =
{
@@ -292,6 +296,8 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
av_freep(&s->motion_val[1]);
av_freep(&s->edge_emu_buffer);
+ s->theora_tables = 0;
+
if (avctx->internal->is_copy)
return 0;
@@ -1912,16 +1918,46 @@ static int vp3_decode_frame(AVCodecContext *avctx,
Vp3DecodeContext *s = avctx->priv_data;
GetBitContext gb;
int i;
+ int ret;
init_get_bits(&gb, buf, buf_size * 8);
if (s->theora && get_bits1(&gb))
{
+ int type = get_bits(&gb, 7);
+ skip_bits_long(&gb, 6*8); /* "theora" */
+
+ if (type == 0) {
+ if (s->avctx->active_thread_type&FF_THREAD_FRAME) {
+ av_log(avctx, AV_LOG_ERROR, "midstream reconfiguration with multithreading is unsupported, try -threads 1\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ vp3_decode_end(avctx);
+ ret = theora_decode_header(avctx, &gb);
+
+ if (ret < 0) {
+ vp3_decode_end(avctx);
+ } else
+ ret = vp3_decode_init(avctx);
+ return ret;
+ } else if (type == 2) {
+ ret = theora_decode_tables(avctx, &gb);
+ if (ret < 0) {
+ vp3_decode_end(avctx);
+ } else
+ ret = vp3_decode_init(avctx);
+ return ret;
+ }
+
av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n");
return -1;
}
s->keyframe = !get_bits1(&gb);
+ if (!s->all_fragments) {
+ av_log(avctx, AV_LOG_ERROR, "Data packet without prior valid headers\n");
+ return -1;
+ }
if (!s->theora)
skip_bits(&gb, 1);
for (i = 0; i < 3; i++)