aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2003-10-11 17:44:21 +0000
committerAlex Beregszaszi <alex@rtfs.hu>2003-10-11 17:44:21 +0000
commitf44ee2c34b33d9d15c8edd369ef01444fc1c81a9 (patch)
tree83d9475fd0d9768a1cebf6e50ae5025191a80f78
parenta62a7323fab878f0623f5d4901e5e44989916a9c (diff)
downloadffmpeg-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.c1
-rw-r--r--libavcodec/avcodec.h2
-rw-r--r--libavcodec/vp3.c189
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
+};