Mercurial > libavcodec.hg
changeset 1516:0f0e9dfa6723 libavcodec
theora decoding support (only keyframes for now, because by theora the frame isn't flipped so the motion vectors are getting screwed up)
author | alex |
---|---|
date | Sat, 11 Oct 2003 17:44:21 +0000 |
parents | e94e299aee40 |
children | d107c545d745 |
files | allcodecs.c avcodec.h vp3.c |
diffstat | 3 files changed, 175 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/allcodecs.c Sat Oct 11 16:43:51 2003 +0000 +++ b/allcodecs.c Sat Oct 11 17:44:21 2003 +0000 @@ -117,6 +117,7 @@ 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);
--- a/avcodec.h Sat Oct 11 16:43:51 2003 +0000 +++ b/avcodec.h Sat Oct 11 17:44:21 2003 +0000 @@ -61,6 +61,7 @@ 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 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;
--- a/vp3.c Sat Oct 11 16:43:51 2003 +0000 +++ b/vp3.c Sat Oct 11 17:44:21 2003 +0000 @@ -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 @@ typedef struct Vp3DecodeContext { AVCodecContext *avctx; + int theora, theora_tables; int width, height; AVFrame golden_frame; AVFrame last_frame; @@ -245,6 +248,13 @@ 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 @@ 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 @@ #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 @@ 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 @@ 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 @@ *data_size = 0; init_get_bits(&gb, buf, buf_size * 8); - - s->keyframe = get_bits(&gb, 1); - s->keyframe ^= 1; - skip_bits(&gb, 1); + + if (s->theora && get_bits1(&gb)) + { + printf("Theora: bad frame indicator\n"); + return -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 @@ 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 @@ 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 @@ 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 +};