# HG changeset patch # User aurel # Date 1190747566 0 # Node ID 314be1cfdcb0d23cdfdcdc26cdc5682d5d61ad72 # Parent f45228f65e06d7ab46eb88480d9e7a4efd598aa7 add a new vp6a codec (add alpha plan support to vp6) diff -r f45228f65e06 -r 314be1cfdcb0 allcodecs.c --- a/allcodecs.c Tue Sep 25 08:43:49 2007 +0000 +++ b/allcodecs.c Tue Sep 25 19:12:46 2007 +0000 @@ -156,6 +156,7 @@ REGISTER_DECODER (VP3, vp3); REGISTER_DECODER (VP5, vp5); REGISTER_DECODER (VP6, vp6); + REGISTER_DECODER (VP6A, vp6a); REGISTER_DECODER (VP6F, vp6f); REGISTER_DECODER (VQA, vqa); REGISTER_ENCDEC (WMV1, wmv1); diff -r f45228f65e06 -r 314be1cfdcb0 avcodec.h --- a/avcodec.h Tue Sep 25 08:43:49 2007 +0000 +++ b/avcodec.h Tue Sep 25 19:12:46 2007 +0000 @@ -166,6 +166,7 @@ CODEC_ID_BETHSOFTVID, CODEC_ID_PTX, CODEC_ID_TXD, + CODEC_ID_VP6A, /* various PCM "codecs" */ CODEC_ID_PCM_S16LE= 0x10000, diff -r f45228f65e06 -r 314be1cfdcb0 vp5.c --- a/vp5.c Tue Sep 25 08:43:49 2007 +0000 +++ b/vp5.c Tue Sep 25 19:12:46 2007 +0000 @@ -270,7 +270,7 @@ { vp56_context_t *s = avctx->priv_data; - vp56_init(avctx, 1); + vp56_init(avctx, 1, 0); s->vp56_coord_div = vp5_coord_div; s->parse_vector_adjustment = vp5_parse_vector_adjustment; s->adjust = vp5_adjust; diff -r f45228f65e06 -r 314be1cfdcb0 vp56.c --- a/vp56.c Tue Sep 25 08:43:49 2007 +0000 +++ b/vp56.c Tue Sep 25 19:12:46 2007 +0000 @@ -22,6 +22,7 @@ */ #include "avcodec.h" +#include "bytestream.h" #include "vp56.h" #include "vp56data.h" @@ -394,12 +395,12 @@ } } -static void vp56_decode_mb(vp56_context_t *s, int row, int col) +static void vp56_decode_mb(vp56_context_t *s, int row, int col, int is_alpha) { AVFrame *frame_current, *frame_ref; vp56_mb_t mb_type; vp56_frame_t ref_frame; - int b, plan, off; + int b, ab, b_max, plan, off; if (s->framep[VP56_FRAME_CURRENT]->key_frame) mb_type = VP56_MB_INTRA; @@ -416,10 +417,13 @@ frame_current = s->framep[VP56_FRAME_CURRENT]; frame_ref = s->framep[ref_frame]; + ab = 6*is_alpha; + b_max = 6 - 2*is_alpha; + switch (mb_type) { case VP56_MB_INTRA: - for (b=0; b<6; b++) { - plan = vp56_b2p[b]; + for (b=0; bdsp.idct_put(frame_current->data[plan] + s->block_offset[b], s->stride[plan], s->block_coeff[b]); } @@ -427,8 +431,8 @@ case VP56_MB_INTER_NOVEC_PF: case VP56_MB_INTER_NOVEC_GF: - for (b=0; b<6; b++) { - plan = vp56_b2p[b]; + for (b=0; bblock_offset[b]; s->dsp.put_pixels_tab[1][0](frame_current->data[plan] + off, frame_ref->data[plan] + off, @@ -445,10 +449,10 @@ case VP56_MB_INTER_4V: case VP56_MB_INTER_V1_GF: case VP56_MB_INTER_V2_GF: - for (b=0; b<6; b++) { + for (b=0; bdata[plan], s->stride[plan], 16*col+x_off, 16*row+y_off); s->dsp.idct_add(frame_current->data[plan] + s->block_offset[b], @@ -464,12 +468,12 @@ int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0]; int i; - s->plane_width[0] = avctx->coded_width; + s->plane_width[0] = s->plane_width[3] = avctx->coded_width; s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2; - s->plane_height[0] = avctx->coded_height; + s->plane_height[0] = s->plane_height[3] = avctx->coded_height; s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; - for (i=0; i<3; i++) + for (i=0; i<4; i++) s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i]; s->mb_width = (avctx->coded_width +15) / 16; @@ -498,17 +502,26 @@ { vp56_context_t *s = avctx->priv_data; AVFrame *const p = s->framep[VP56_FRAME_CURRENT]; + int is_alpha, alpha_offset; + + if (s->has_alpha) { + alpha_offset = bytestream_get_be24(&buf); + buf_size -= 3; + } + + for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) { int mb_row, mb_col, mb_row_flip, mb_offset = 0; int block, y, uv, stride_y, stride_uv; int golden_frame = 0; int res; - s->modelp = &s->models; + s->modelp = &s->models[is_alpha]; res = s->parse_header(s, buf, buf_size, &golden_frame); if (!res) return -1; + if (!is_alpha) { p->reference = 1; if (avctx->get_buffer(avctx, p) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -520,6 +533,7 @@ avctx->release_buffer(avctx, p); return -1; } + } if (p->key_frame) { p->pict_type = FF_I_TYPE; @@ -583,7 +597,7 @@ s->block_offset[5] = s->block_offset[4]; for (mb_col=0; mb_colmb_width; mb_col++) { - vp56_decode_mb(s, mb_row, mb_col); + vp56_decode_mb(s, mb_row, mb_col, is_alpha); for (y=0; y<4; y++) { s->above_block_idx[y] += 2; @@ -597,16 +611,32 @@ } } - if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN]) - FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], - s->framep[VP56_FRAME_UNUSED]); - else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); if (p->key_frame || golden_frame) { - if (s->framep[VP56_FRAME_GOLDEN]->data[0]) + if (s->framep[VP56_FRAME_GOLDEN]->data[0] && + s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2]) avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); s->framep[VP56_FRAME_GOLDEN] = p; } + + if (s->has_alpha) { + FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN], + s->framep[VP56_FRAME_GOLDEN2]); + buf += alpha_offset; + buf_size -= alpha_offset; + } + } + + if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] || + s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) { + if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] && + s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2]) + FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], + s->framep[VP56_FRAME_UNUSED]); + else + FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], + s->framep[VP56_FRAME_UNUSED2]); + } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) + avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT], s->framep[VP56_FRAME_PREVIOUS]); @@ -616,13 +646,13 @@ return buf_size; } -void vp56_init(AVCodecContext *avctx, int flip) +void vp56_init(AVCodecContext *avctx, int flip, int has_alpha) { vp56_context_t *s = avctx->priv_data; int i; s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_YUV420P; + avctx->pix_fmt = has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P; if (avctx->idct_algo == FF_IDCT_AUTO) avctx->idct_algo = FF_IDCT_VP3; @@ -631,9 +661,10 @@ avcodec_set_dimensions(avctx, 0, 0); - for (i=0; i<3; i++) + for (i=0; i<4; i++) s->framep[i] = &s->frames[i]; s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN]; + s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2]; s->edge_emu_buffer_alloc = NULL; s->above_blocks = NULL; @@ -643,6 +674,7 @@ s->filter = NULL; + s->has_alpha = has_alpha; if (flip) { s->flip = -1; s->frbi = 2; @@ -663,6 +695,8 @@ av_free(s->edge_emu_buffer_alloc); if (s->framep[VP56_FRAME_GOLDEN]->data[0]) avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); + if (s->framep[VP56_FRAME_GOLDEN2]->data[0]) + avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]); if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); return 0; diff -r f45228f65e06 -r 314be1cfdcb0 vp56.h --- a/vp56.h Tue Sep 25 08:43:49 2007 +0000 +++ b/vp56.h Tue Sep 25 19:12:46 2007 +0000 @@ -90,8 +90,8 @@ AVCodecContext *avctx; DSPContext dsp; ScanTable scantable; - AVFrame frames[3]; - AVFrame *framep[4]; + AVFrame frames[4]; + AVFrame *framep[6]; uint8_t *edge_emu_buffer_alloc; uint8_t *edge_emu_buffer; vp56_range_coder_t c; @@ -100,8 +100,8 @@ int sub_version; /* frame info */ - int plane_width[3]; - int plane_height[3]; + int plane_width[4]; + int plane_height[4]; int mb_width; /* number of horizontal MB */ int mb_height; /* number of vertical MB */ int block_offset[6]; @@ -137,11 +137,13 @@ uint8_t coeff_ctx[4][64]; /* used in vp5 only */ uint8_t coeff_ctx_last[4]; /* used in vp5 only */ + int has_alpha; + /* upside-down flipping hints */ int flip; /* are we flipping ? */ int frbi; /* first row block index in MB */ int srbi; /* second row block index in MB */ - int stride[3]; /* stride for each plan */ + int stride[4]; /* stride for each plan */ const uint8_t *vp56_coord_div; vp56_parse_vector_adjustment_t parse_vector_adjustment; @@ -154,11 +156,11 @@ vp56_parse_header_t parse_header; vp56_model_t *modelp; - vp56_model_t models; + vp56_model_t models[2]; }; -void vp56_init(AVCodecContext *avctx, int flip); +void vp56_init(AVCodecContext *avctx, int flip, int has_alpha); int vp56_free(AVCodecContext *avctx); void vp56_init_dequant(vp56_context_t *s, int quantizer); int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, diff -r f45228f65e06 -r 314be1cfdcb0 vp56data.c --- a/vp56data.c Tue Sep 25 08:43:49 2007 +0000 +++ b/vp56data.c Tue Sep 25 19:12:46 2007 +0000 @@ -23,7 +23,7 @@ #include "vp56data.h" -const uint8_t vp56_b2p[] = { 0, 0, 0, 0, 1, 2 }; +const uint8_t vp56_b2p[] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 3 }; const uint8_t vp56_b6to4[] = { 0, 0, 1, 1, 2, 3 }; const uint8_t vp56_coeff_parse_table[6][11] = { diff -r f45228f65e06 -r 314be1cfdcb0 vp56data.h --- a/vp56data.h Tue Sep 25 08:43:49 2007 +0000 +++ b/vp56data.h Tue Sep 25 19:12:46 2007 +0000 @@ -30,7 +30,9 @@ VP56_FRAME_CURRENT = 0, VP56_FRAME_PREVIOUS = 1, VP56_FRAME_GOLDEN = 2, - VP56_FRAME_UNUSED = 3, + VP56_FRAME_GOLDEN2 = 3, + VP56_FRAME_UNUSED = 4, + VP56_FRAME_UNUSED2 = 5, } vp56_frame_t; typedef enum { diff -r f45228f65e06 -r 314be1cfdcb0 vp6.c --- a/vp6.c Tue Sep 25 08:43:49 2007 +0000 +++ b/vp6.c Tue Sep 25 19:12:46 2007 +0000 @@ -494,7 +494,8 @@ { vp56_context_t *s = avctx->priv_data; - vp56_init(avctx, avctx->codec->id == CODEC_ID_VP6); + vp56_init(avctx, avctx->codec->id == CODEC_ID_VP6, + avctx->codec->id == CODEC_ID_VP6A); s->vp56_coord_div = vp6_coord_div; s->parse_vector_adjustment = vp6_parse_vector_adjustment; s->adjust = vp6_adjust; @@ -532,3 +533,16 @@ vp56_decode_frame, CODEC_CAP_DR1, }; + +/* flash version, not flipped upside-down, with alpha channel */ +AVCodec vp6a_decoder = { + "vp6a", + CODEC_TYPE_VIDEO, + CODEC_ID_VP6A, + sizeof(vp56_context_t), + vp6_decode_init, + NULL, + vp56_free, + vp56_decode_frame, + CODEC_CAP_DR1, +};