diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2003-10-11 17:44:21 +0000 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2003-10-11 17:44:21 +0000 |
commit | f44ee2c34b33d9d15c8edd369ef01444fc1c81a9 (patch) | |
tree | 83d9475fd0d9768a1cebf6e50ae5025191a80f78 | |
parent | a62a7323fab878f0623f5d4901e5e44989916a9c (diff) | |
download | ffmpeg-f44ee2c34b33d9d15c8edd369ef01444fc1c81a9.tar.gz |
theora decoding support (only keyframes for now, because by theora the frame isn't flipped so the motion vectors are getting screwed up)
Originally committed as revision 2359 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/allcodecs.c | 1 | ||||
-rw-r--r-- | libavcodec/avcodec.h | 2 | ||||
-rw-r--r-- | libavcodec/vp3.c | 189 |
3 files changed, 174 insertions, 18 deletions
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index ca6f5002e8..7762c3ff9c 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -117,6 +117,7 @@ void avcodec_register_all(void) register_avcodec(&cyuv_decoder); register_avcodec(&h264_decoder); register_avcodec(&vp3_decoder); + register_avcodec(&theora_decoder); register_avcodec(&asv1_decoder); register_avcodec(&asv2_decoder); register_avcodec(&vcr1_decoder); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index b0b3bf551b..1f57584acd 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -61,6 +61,7 @@ enum CodecID { CODEC_ID_H264, CODEC_ID_INDEO3, CODEC_ID_VP3, + CODEC_ID_THEORA, CODEC_ID_AAC, CODEC_ID_MPEG4AAC, CODEC_ID_ASV1, @@ -1433,6 +1434,7 @@ extern AVCodec cyuv_decoder; extern AVCodec h264_decoder; extern AVCodec indeo3_decoder; extern AVCodec vp3_decoder; +extern AVCodec theora_decoder; extern AVCodec amr_nb_decoder; extern AVCodec amr_nb_encoder; extern AVCodec amr_wb_encoder; diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 00007788b2..315e18566c 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -20,6 +20,8 @@ * For more information about the VP3 coding process, visit: * http://www.pcisys.net/~melanson/codecs/ * + * Theora decoder by Alex Beregszaszi + * */ /** @@ -213,6 +215,7 @@ static int ModeAlphabet[7][CODING_MODE_COUNT] = typedef struct Vp3DecodeContext { AVCodecContext *avctx; + int theora, theora_tables; int width, height; AVFrame golden_frame; AVFrame last_frame; @@ -245,6 +248,13 @@ typedef struct Vp3DecodeContext { Vp3Fragment *all_fragments; int u_fragment_start; int v_fragment_start; + + /* tables */ + uint16_t coded_dc_scale_factor[64]; + uint32_t coded_quality_threshold[64]; + uint16_t coded_intra_y_dequant[64]; + uint16_t coded_intra_c_dequant[64]; + uint16_t coded_inter_dequant[64]; /* this is a list of indices into the all_fragments array indicating * which of the fragments are coded */ @@ -1130,8 +1140,8 @@ s->all_fragments[i].motion_y = 0xbeef; static void init_dequantizer(Vp3DecodeContext *s) { - int quality_scale = vp31_quality_threshold[s->quality_index]; - int dc_scale_factor = vp31_dc_scale_factor[s->quality_index]; + int quality_scale = s->coded_quality_threshold[s->quality_index]; + int dc_scale_factor = s->coded_dc_scale_factor[s->quality_index]; int i, j; debug_vp3(" vp3: initializing dequantization tables\n"); @@ -1151,17 +1161,17 @@ static void init_dequantizer(Vp3DecodeContext *s) #define SCALER 4 /* scale DC quantizers */ - s->intra_y_dequant[0] = vp31_intra_y_dequant[0] * dc_scale_factor / 100; + s->intra_y_dequant[0] = s->coded_intra_y_dequant[0] * dc_scale_factor / 100; if (s->intra_y_dequant[0] < MIN_DEQUANT_VAL * 2) s->intra_y_dequant[0] = MIN_DEQUANT_VAL * 2; s->intra_y_dequant[0] *= SCALER; - s->intra_c_dequant[0] = vp31_intra_c_dequant[0] * dc_scale_factor / 100; + s->intra_c_dequant[0] = s->coded_intra_c_dequant[0] * dc_scale_factor / 100; if (s->intra_c_dequant[0] < MIN_DEQUANT_VAL * 2) s->intra_c_dequant[0] = MIN_DEQUANT_VAL * 2; s->intra_c_dequant[0] *= SCALER; - s->inter_dequant[0] = vp31_inter_dequant[0] * dc_scale_factor / 100; + s->inter_dequant[0] = s->coded_inter_dequant[0] * dc_scale_factor / 100; if (s->inter_dequant[0] < MIN_DEQUANT_VAL * 4) s->inter_dequant[0] = MIN_DEQUANT_VAL * 4; s->inter_dequant[0] *= SCALER; @@ -1172,17 +1182,17 @@ static void init_dequantizer(Vp3DecodeContext *s) j = zigzag_index[i]; - s->intra_y_dequant[j] = vp31_intra_y_dequant[i] * quality_scale / 100; + s->intra_y_dequant[j] = s->coded_intra_y_dequant[i] * quality_scale / 100; if (s->intra_y_dequant[j] < MIN_DEQUANT_VAL) s->intra_y_dequant[j] = MIN_DEQUANT_VAL; s->intra_y_dequant[j] *= SCALER; - s->intra_c_dequant[j] = vp31_intra_c_dequant[i] * quality_scale / 100; + s->intra_c_dequant[j] = s->coded_intra_c_dequant[i] * quality_scale / 100; if (s->intra_c_dequant[j] < MIN_DEQUANT_VAL) s->intra_c_dequant[j] = MIN_DEQUANT_VAL; s->intra_c_dequant[j] *= SCALER; - s->inter_dequant[j] = vp31_inter_dequant[i] * quality_scale / 100; + s->inter_dequant[j] = s->coded_inter_dequant[i] * quality_scale / 100; if (s->inter_dequant[j] < MIN_DEQUANT_VAL * 2) s->inter_dequant[j] = MIN_DEQUANT_VAL * 2; s->inter_dequant[j] *= SCALER; @@ -2614,6 +2624,20 @@ static int vp3_decode_init(AVCodecContext *avctx) s->coded_fragment_list = av_malloc(s->fragment_count * sizeof(int)); s->pixel_addresses_inited = 0; + if (!s->theora_tables) + { + for (i = 0; i < 64; i++) + s->coded_dc_scale_factor[i] = vp31_dc_scale_factor[i]; + for (i = 0; i < 64; i++) + s->coded_quality_threshold[i] = vp31_quality_threshold[i]; + for (i = 0; i < 64; i++) + s->coded_intra_y_dequant[i] = vp31_intra_y_dequant[i]; + for (i = 0; i < 64; i++) + s->coded_intra_c_dequant[i] = vp31_intra_c_dequant[i]; + for (i = 0; i < 64; i++) + s->coded_inter_dequant[i] = vp31_inter_dequant[i]; + } + /* init VLC tables */ for (i = 0; i < 16; i++) { @@ -2677,24 +2701,35 @@ static int vp3_decode_frame(AVCodecContext *avctx, *data_size = 0; init_get_bits(&gb, buf, buf_size * 8); + + if (s->theora && get_bits1(&gb)) + { + printf("Theora: bad frame indicator\n"); + return -1; + } - s->keyframe = get_bits(&gb, 1); - s->keyframe ^= 1; - skip_bits(&gb, 1); + s->keyframe = !get_bits1(&gb); + if (s->theora && s->keyframe) + { + if (get_bits1(&gb)) + printf("Theora: warning, unsupported keyframe coding type?!\n"); + skip_bits(&gb, 2); /* reserved? */ + } + else + skip_bits(&gb, 1); s->last_quality_index = s->quality_index; s->quality_index = get_bits(&gb, 6); - debug_vp3(" VP3 frame #%d: Q index = %d", counter, s->quality_index); + debug_vp3(" VP3 %sframe #%d: Q index = %d\n", + s->keyframe?"key":"", counter, s->quality_index); counter++; if (s->quality_index != s->last_quality_index) init_dequantizer(s); if (s->keyframe) { - - debug_vp3(", keyframe\n"); /* skip the other 2 header bytes for now */ - skip_bits(&gb, 16); + if (!s->theora) skip_bits(&gb, 16); if (s->last_frame.data[0] == s->golden_frame.data[0]) { if (s->golden_frame.data[0]) avctx->release_buffer(avctx, &s->golden_frame); @@ -2720,9 +2755,6 @@ static int vp3_decode_frame(AVCodecContext *avctx, vp3_calculate_pixel_addresses(s); } else { - - debug_vp3("\n"); - /* allocate a new current frame */ s->current_frame.reference = 3; if(avctx->get_buffer(avctx, &s->current_frame) < 0) { @@ -2818,6 +2850,114 @@ static int vp3_decode_end(AVCodecContext *avctx) return 0; } +/* current version is 3.2.0 */ + +static int theora_decode_header(AVCodecContext *avctx, GetBitContext gb) +{ + Vp3DecodeContext *s = avctx->priv_data; + + 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->height = get_bits(&gb, 16) << 4; + + skip_bits(&gb, 24); /* frame width */ + skip_bits(&gb, 24); /* frame height */ + + skip_bits(&gb, 8); /* offset x */ + skip_bits(&gb, 8); /* offset y */ + + skip_bits(&gb, 32); /* fps numerator */ + skip_bits(&gb, 32); /* fps denumerator */ + skip_bits(&gb, 24); /* aspect numerator */ + skip_bits(&gb, 24); /* aspect denumerator */ + + skip_bits(&gb, 5); /* keyframe frequency force */ + skip_bits(&gb, 8); /* colorspace */ + skip_bits(&gb, 24); /* bitrate */ + + skip_bits(&gb, 6); /* last(?) quality index */ + +// align_get_bits(&gb); + + avctx->width = s->width; + avctx->height = s->height; + + vp3_decode_init(avctx); + + return 0; +} + +static int theora_decode_tables(AVCodecContext *avctx, GetBitContext gb) +{ + Vp3DecodeContext *s = avctx->priv_data; + int i; + + /* quality threshold table */ + for (i = 0; i < 64; i++) + s->coded_quality_threshold[i] = get_bits(&gb, 16); + + /* dc scale factor table */ + for (i = 0; i < 64; i++) + s->coded_dc_scale_factor[i] = get_bits(&gb, 16); + + /* y coeffs */ + for (i = 0; i < 64; i++) + s->coded_intra_y_dequant[i] = get_bits(&gb, 8); + + /* uv coeffs */ + for (i = 0; i < 64; i++) + s->coded_intra_c_dequant[i] = get_bits(&gb, 8); + + /* inter coeffs */ + for (i = 0; i < 64; i++) + s->coded_inter_dequant[i] = get_bits(&gb, 8); + + s->theora_tables = 1; + + return 0; +} + +static int theora_decode_init(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + GetBitContext gb; + int ptype; + + s->theora = 1; + + if (!avctx->extradata_size) + return -1; + + init_get_bits(&gb, avctx->extradata, avctx->extradata_size); + + ptype = get_bits(&gb, 8); + debug_vp3("Theora headerpacket type: %x\n", ptype); + + if (!(ptype & 0x80)) + return -1; + + skip_bits(&gb, 6*8); /* "theora" */ + + switch(ptype) + { + case 0x80: + theora_decode_header(avctx, gb); + vp3_decode_init(avctx); + break; + case 0x81: + /* comment */ + break; + case 0x82: + theora_decode_tables(avctx, gb); + break; + } + + return 0; +} + AVCodec vp3_decoder = { "vp3", CODEC_TYPE_VIDEO, @@ -2830,3 +2970,16 @@ AVCodec vp3_decoder = { 0, NULL }; + +AVCodec theora_decoder = { + "theora", + CODEC_TYPE_VIDEO, + CODEC_ID_THEORA, + sizeof(Vp3DecodeContext), + theora_decode_init, + NULL, + vp3_decode_end, + vp3_decode_frame, + 0, + NULL +}; |