summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Jacobs <aurel@gnuage.org>2007-01-14 18:17:15 +0000
committerAurelien Jacobs <aurel@gnuage.org>2007-01-14 18:17:15 +0000
commitdd9b86354c4ab002f7a3509d71461a84e21d1be9 (patch)
treef3c07e7037390ca53e67a425a67371faf98445bf
parent2592438dd845dddafe5960e316b02d8df3f728d3 (diff)
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
-rw-r--r--libavcodec/vp56.h3
-rw-r--r--libavcodec/vp6.c33
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;