diff options
author | Aurelien Jacobs <aurel@gnuage.org> | 2007-01-14 18:17:15 +0000 |
---|---|---|
committer | Aurelien Jacobs <aurel@gnuage.org> | 2007-01-14 18:17:15 +0000 |
commit | dd9b86354c4ab002f7a3509d71461a84e21d1be9 (patch) | |
tree | f3c07e7037390ca53e67a425a67371faf98445bf /libavcodec | |
parent | 2592438dd845dddafe5960e316b02d8df3f728d3 (diff) | |
download | ffmpeg-dd9b86354c4ab002f7a3509d71461a84e21d1be9.tar.gz |
add support for another variant of vp6
with block coeffs coded separatly from other parts of the frame
Originally committed as revision 7484 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/vp56.h | 3 | ||||
-rw-r--r-- | libavcodec/vp6.c | 33 |
2 files changed, 29 insertions, 7 deletions
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index f8b3a8e4b6..50e2015504 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -76,6 +76,8 @@ struct vp56_context { uint8_t *edge_emu_buffer_alloc; uint8_t *edge_emu_buffer; vp56_range_coder_t c; + vp56_range_coder_t cc; + vp56_range_coder_t *ccp; int sub_version; /* frame info */ @@ -108,6 +110,7 @@ struct vp56_context { int vector_candidate_pos; /* filtering hints */ + int filter_header; /* used in vp6 only */ int deblock_filtering; int filter_selection; int filter_mode; diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index 381fcc8eed..fdbfd5fb2c 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -43,13 +43,12 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, { vp56_range_coder_t *c = &s->c; int parse_filter_info = 0; + int coeff_offset = 0; int vrt_shift = 0; int sub_version; int rows, cols; int res = 1; - - if (buf[0] & 1) - return 0; + int separated_coeff = buf[0] & 1; s->frames[VP56_FRAME_CURRENT].key_frame = !(buf[0] & 0x80); vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); @@ -58,12 +57,16 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, sub_version = buf[1] >> 3; if (sub_version > 8) return 0; - if ((buf[1] & 0x06) != 0x06) - return 0; + s->filter_header = buf[1] & 0x06; if (buf[1] & 1) { av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); return 0; } + if (separated_coeff || !s->filter_header) { + coeff_offset = BE_16(buf+2) - 2; + buf += 2; + buf_size -= 2; + } rows = buf[2]; /* number of stored macroblock rows */ cols = buf[3]; /* number of stored macroblock cols */ @@ -83,7 +86,7 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, vp56_init_range_decoder(c, buf+6, buf_size-6); vp56_rac_gets(c, 2); - parse_filter_info = 1; + parse_filter_info = s->filter_header; if (sub_version < 8) vrt_shift = 5; s->sub_version = sub_version; @@ -91,14 +94,21 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, if (!s->sub_version) return 0; + if (separated_coeff || !s->filter_header) { + coeff_offset = BE_16(buf+1) - 2; + buf += 2; + buf_size -= 2; + } vp56_init_range_decoder(c, buf+1, buf_size-1); *golden_frame = vp56_rac_get(c); + if (s->filter_header) { s->deblock_filtering = vp56_rac_get(c); if (s->deblock_filtering) vp56_rac_get(c); if (s->sub_version > 7) parse_filter_info = vp56_rac_get(c); + } } if (parse_filter_info) { @@ -118,6 +128,15 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, } vp56_rac_get(c); + + if (coeff_offset) { + vp56_init_range_decoder(&s->cc, buf+coeff_offset, + buf_size-coeff_offset); + s->ccp = &s->cc; + } else { + s->ccp = &s->c; + } + return res; } @@ -259,7 +278,7 @@ static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) static void vp6_parse_coeff(vp56_context_t *s) { - vp56_range_coder_t *c = &s->c; + vp56_range_coder_t *c = s->ccp; uint8_t *permute = s->scantable.permutated; uint8_t *model, *model2, *model3; int coeff, sign, coeff_idx; |