diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 7d771f31f7..0eb9314c48 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -449,9 +449,9 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) } } -static int vp56_size_changed(AVCodecContext *avctx) +static int vp56_size_changed(VP56Context *s) { - VP56Context *s = avctx->priv_data; + AVCodecContext *avctx = s->avctx; int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0]; int i; @@ -483,9 +483,14 @@ static int vp56_size_changed(AVCodecContext *avctx) if (s->flip < 0) s->edge_emu_buffer += 15 * stride; + if (s->alpha_context) + return vp56_size_changed(s->alpha_context); + return 0; } +static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *, int, int); + int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { @@ -493,8 +498,8 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, VP56Context *s = avctx->priv_data; AVFrame *p = 0; int remaining_buf_size = avpkt->size; - int is_alpha, av_uninit(alpha_offset); - int i; + int av_uninit(alpha_offset); + int i, res; /* select a current frame from the unused frames */ for (i = 0; i < 4; ++i) { @@ -505,6 +510,8 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } av_assert0(p != 0); s->framep[VP56_FRAME_CURRENT] = p; + if (s->alpha_context) + s->alpha_context->framep[VP56_FRAME_CURRENT] = p; if (s->has_alpha) { if (remaining_buf_size < 3) @@ -515,30 +522,17 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, return -1; } - 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 res; - - s->modelp = &s->models[is_alpha]; - res = s->parse_header(s, buf, remaining_buf_size); if (!res) return -1; if (res == 2) { - int i; for (i = 0; i < 4; i++) { if (s->frames[i].data[0]) avctx->release_buffer(avctx, &s->frames[i]); } - if (is_alpha) { - avcodec_set_dimensions(avctx, 0, 0); - return -1; - } } - if (!is_alpha) { p->reference = 3; if (avctx->get_buffer(avctx, p) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -546,11 +540,53 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } if (res == 2) - if (vp56_size_changed(avctx)) { + if (vp56_size_changed(s)) { avctx->release_buffer(avctx, p); return -1; } + + if (s->has_alpha) { + buf += alpha_offset; + remaining_buf_size -= alpha_offset; + + res = s->alpha_context->parse_header(s->alpha_context, buf, remaining_buf_size); + if (res != 1) { + avctx->release_buffer(avctx, p); + return -1; } + } + + avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, s->has_alpha + 1); + + /* release frames that aren't in use */ + for (i = 0; i < 4; ++i) { + AVFrame *victim = &s->frames[i]; + if (!victim->data[0]) + continue; + if (victim != s->framep[VP56_FRAME_PREVIOUS] && + victim != s->framep[VP56_FRAME_GOLDEN] && + (!s->has_alpha || victim != s->alpha_context->framep[VP56_FRAME_GOLDEN])) + avctx->release_buffer(avctx, victim); + } + + p->qstride = 0; + p->qscale_table = s->qscale_table; + p->qscale_type = FF_QSCALE_TYPE_VP56; + *(AVFrame*)data = *p; + *data_size = sizeof(AVFrame); + + return avpkt->size; +} + +static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, + int jobnr, int threadnr) +{ + VP56Context *s0 = avctx->priv_data; + int is_alpha = (jobnr == 1); + VP56Context *s = is_alpha ? s0->alpha_context : s0; + AVFrame *const p = s->framep[VP56_FRAME_CURRENT]; + int mb_row, mb_col, mb_row_flip, mb_offset = 0; + int block, y, uv, stride_y, stride_uv; if (p->key_frame) { p->pict_type = AV_PICTURE_TYPE_I; @@ -634,35 +670,9 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, 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; - remaining_buf_size -= alpha_offset; - } - } - FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT], s->framep[VP56_FRAME_PREVIOUS]); - - /* release frames that aren't in use */ - for (i = 0; i < 4; ++i) { - AVFrame *victim = &s->frames[i]; - if (!victim->data[0]) - continue; - if (victim != s->framep[VP56_FRAME_PREVIOUS] && - victim != s->framep[VP56_FRAME_GOLDEN] && - (!s->has_alpha || victim != s->framep[VP56_FRAME_GOLDEN2])) - avctx->release_buffer(avctx, victim); - } - - p->qstride = 0; - p->qscale_table = s->qscale_table; - p->qscale_type = FF_QSCALE_TYPE_VP56; - *(AVFrame*)data = *p; - *data_size = sizeof(AVFrame); - - return avpkt->size; + return 0; } av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha) @@ -702,6 +712,9 @@ av_cold void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s, s->filter = NULL; s->has_alpha = has_alpha; + + s->modelp = &s->model; + if (flip) { s->flip = -1; s->frbi = 2; diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index 7a32342aee..44bd229a6d 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -161,8 +161,11 @@ struct vp56_context { VP56ParseCoeffModels parse_coeff_models; VP56ParseHeader parse_header; + /* for "slice" parallelism between YUV and A */ + VP56Context *alpha_context; + VP56Model *modelp; - VP56Model models[2]; + VP56Model model; /* huffman decoding */ int use_huffman; diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index c8a191799e..bafa2b4d0a 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -599,6 +599,18 @@ static av_cold int vp6_decode_init(AVCodecContext *avctx) ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6, avctx->codec->id == AV_CODEC_ID_VP6A); vp6_decode_init_context(s); + + if (s->has_alpha) { + int i; + + s->alpha_context = av_mallocz(sizeof(VP56Context)); + ff_vp56_init_context(avctx, s->alpha_context, + s->flip == -1, s->has_alpha); + vp6_decode_init_context(s->alpha_context); + for (i = 0; i < 6; ++i) + s->alpha_context->framep[i] = s->framep[i]; + } + return 0; } @@ -622,6 +634,13 @@ static av_cold int vp6_decode_free(AVCodecContext *avctx) ff_vp56_free(avctx); vp6_decode_free_context(s); + + if (s->alpha_context) { + ff_vp56_free_context(s->alpha_context); + vp6_decode_free_context(s->alpha_context); + av_free(s->alpha_context); + } + return 0; } @@ -672,6 +691,6 @@ AVCodec ff_vp6a_decoder = { .init = vp6_decode_init, .close = vp6_decode_free, .decode = ff_vp56_decode_frame, - .capabilities = CODEC_CAP_DR1, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), }; diff --git a/tests/ref/fate/vp6a b/tests/ref/fate/vp6a index de0518bf35..1f2ddd9859 100644 --- a/tests/ref/fate/vp6a +++ b/tests/ref/fate/vp6a @@ -1,94 +1,94 @@ #tb 0: 1/4 0, 0, 0, 1, 135000, 0x9dceed6d -0, 1, 1, 1, 135000, 0xcb87787f -0, 2, 2, 1, 135000, 0xdb4361ce -0, 3, 3, 1, 135000, 0xb8fd81c2 -0, 4, 4, 1, 135000, 0xbf86a7af -0, 5, 5, 1, 135000, 0x2e7787e3 -0, 6, 6, 1, 135000, 0x6cec6ebd -0, 7, 7, 1, 135000, 0xa4d08c07 -0, 8, 8, 1, 135000, 0x1be48faf -0, 9, 9, 1, 135000, 0xf3cd8ede -0, 10, 10, 1, 135000, 0x33ec8a49 -0, 11, 11, 1, 135000, 0x11e887ec -0, 12, 12, 1, 135000, 0x3e215c25 -0, 13, 13, 1, 135000, 0x1a2cb3f8 -0, 14, 14, 1, 135000, 0x7fb0e48a -0, 15, 15, 1, 135000, 0x749f3738 -0, 16, 16, 1, 135000, 0x686e78e9 -0, 17, 17, 1, 135000, 0x29515bc7 -0, 18, 18, 1, 135000, 0x987126bd -0, 19, 19, 1, 135000, 0xdf77bb13 -0, 20, 20, 1, 135000, 0x5fb1468a -0, 21, 21, 1, 135000, 0x06ea50ea -0, 22, 22, 1, 135000, 0x7bd9c715 -0, 23, 23, 1, 135000, 0xdd6e6831 -0, 24, 24, 1, 135000, 0x0ee3760f -0, 25, 25, 1, 135000, 0xc7984dc8 -0, 26, 26, 1, 135000, 0x7e385bff -0, 27, 27, 1, 135000, 0xae155ab9 -0, 28, 28, 1, 135000, 0xc05ee8f7 -0, 29, 29, 1, 135000, 0x93de3392 -0, 30, 30, 1, 135000, 0xfe45b38b -0, 31, 31, 1, 135000, 0xeb5ed72c -0, 32, 32, 1, 135000, 0x0794cb57 -0, 33, 33, 1, 135000, 0x2578c6e5 -0, 34, 34, 1, 135000, 0x78486707 -0, 35, 35, 1, 135000, 0x41e1f0e6 -0, 36, 36, 1, 135000, 0x4508eb76 -0, 37, 37, 1, 135000, 0xd8c087f3 -0, 38, 38, 1, 135000, 0x1a8db89a -0, 39, 39, 1, 135000, 0x6dbd90c6 -0, 40, 40, 1, 135000, 0x0845e400 -0, 41, 41, 1, 135000, 0xe8b02fc2 -0, 42, 42, 1, 135000, 0x8007d813 -0, 43, 43, 1, 135000, 0xdfb04e69 -0, 44, 44, 1, 135000, 0x5746cf71 -0, 45, 45, 1, 135000, 0xe510299f -0, 46, 46, 1, 135000, 0xeea0c829 -0, 47, 47, 1, 135000, 0x7c0578ab +0, 1, 1, 1, 135000, 0x47e5778d +0, 2, 2, 1, 135000, 0x5de36599 +0, 3, 3, 1, 135000, 0x540d8079 +0, 4, 4, 1, 135000, 0xba9ea534 +0, 5, 5, 1, 135000, 0xa75088f8 +0, 6, 6, 1, 135000, 0x7d867559 +0, 7, 7, 1, 135000, 0xcc678fee +0, 8, 8, 1, 135000, 0x79c590b9 +0, 9, 9, 1, 135000, 0x87789918 +0, 10, 10, 1, 135000, 0xaa939213 +0, 11, 11, 1, 135000, 0x3912916d +0, 12, 12, 1, 135000, 0x41305d0b +0, 13, 13, 1, 135000, 0x2686b5dd +0, 14, 14, 1, 135000, 0xa69ae422 +0, 15, 15, 1, 135000, 0x998a3478 +0, 16, 16, 1, 135000, 0x5842768d +0, 17, 17, 1, 135000, 0xf6a85b16 +0, 18, 18, 1, 135000, 0x7a5b2708 +0, 19, 19, 1, 135000, 0x8b2abb63 +0, 20, 20, 1, 135000, 0x7dc8468b +0, 21, 21, 1, 135000, 0x04d85001 +0, 22, 22, 1, 135000, 0x83e3c647 +0, 23, 23, 1, 135000, 0xcddd687e +0, 24, 24, 1, 135000, 0x818e785e +0, 25, 25, 1, 135000, 0x3a915080 +0, 26, 26, 1, 135000, 0x953d603d +0, 27, 27, 1, 135000, 0x79005ebf +0, 28, 28, 1, 135000, 0x80afec75 +0, 29, 29, 1, 135000, 0xfc8e376b +0, 30, 30, 1, 135000, 0xf957b7ef +0, 31, 31, 1, 135000, 0xe878da44 +0, 32, 32, 1, 135000, 0xe68ecca3 +0, 33, 33, 1, 135000, 0x1a2cc7d3 +0, 34, 34, 1, 135000, 0x4f346a69 +0, 35, 35, 1, 135000, 0x7a0cf4ac +0, 36, 36, 1, 135000, 0x6d4eee7a +0, 37, 37, 1, 135000, 0xf0688cbd +0, 38, 38, 1, 135000, 0xca4abbbc +0, 39, 39, 1, 135000, 0x87669519 +0, 40, 40, 1, 135000, 0xd090e9d7 +0, 41, 41, 1, 135000, 0xd7f536c1 +0, 42, 42, 1, 135000, 0x353ede54 +0, 43, 43, 1, 135000, 0xbc8f5358 +0, 44, 44, 1, 135000, 0xb52cd59a +0, 45, 45, 1, 135000, 0x0b882eba +0, 46, 46, 1, 135000, 0xc544cd54 +0, 47, 47, 1, 135000, 0x31ca7e73 0, 48, 48, 1, 135000, 0xb1569ce9 -0, 49, 49, 1, 135000, 0x6c233986 -0, 50, 50, 1, 135000, 0x95b77f3d -0, 51, 51, 1, 135000, 0xfc368d80 -0, 52, 52, 1, 135000, 0x5c73b064 -0, 53, 53, 1, 135000, 0x2206da8d -0, 54, 54, 1, 135000, 0x62bb599e -0, 55, 55, 1, 135000, 0x15a68991 -0, 56, 56, 1, 135000, 0x5f5eb810 +0, 49, 49, 1, 135000, 0x8bf4394f +0, 50, 50, 1, 135000, 0xf413812a +0, 51, 51, 1, 135000, 0xf2fa90ab +0, 52, 52, 1, 135000, 0xdcd8b265 +0, 53, 53, 1, 135000, 0xa89cdba1 +0, 54, 54, 1, 135000, 0x212b59a5 +0, 55, 55, 1, 135000, 0x10c589c3 +0, 56, 56, 1, 135000, 0x432ab5b4 0, 57, 57, 1, 135000, 0x85a9634a -0, 58, 58, 1, 135000, 0xf24b5c1a -0, 59, 59, 1, 135000, 0x38034850 -0, 60, 60, 1, 135000, 0x48fd3599 -0, 61, 61, 1, 135000, 0xb9d62408 -0, 62, 62, 1, 135000, 0xaf202a21 -0, 63, 63, 1, 135000, 0x341aa582 -0, 64, 64, 1, 135000, 0x90cdc9bb -0, 65, 65, 1, 135000, 0x0b52f319 -0, 66, 66, 1, 135000, 0xce61aa5e -0, 67, 67, 1, 135000, 0x988acb45 -0, 68, 68, 1, 135000, 0xcd353664 -0, 69, 69, 1, 135000, 0xa80c8ce9 -0, 70, 70, 1, 135000, 0x15dce784 -0, 71, 71, 1, 135000, 0x16bd4519 -0, 72, 72, 1, 135000, 0x571712f3 -0, 73, 73, 1, 135000, 0x6b109f1e +0, 58, 58, 1, 135000, 0x10db5b87 +0, 59, 59, 1, 135000, 0x583145d9 +0, 60, 60, 1, 135000, 0x7d3a33bd +0, 61, 61, 1, 135000, 0xcf592423 +0, 62, 62, 1, 135000, 0xb59728e5 +0, 63, 63, 1, 135000, 0x1eeca660 +0, 64, 64, 1, 135000, 0xff7bcc34 +0, 65, 65, 1, 135000, 0x0ef8f271 +0, 66, 66, 1, 135000, 0x8c9ca8ee +0, 67, 67, 1, 135000, 0x8a7ece34 +0, 68, 68, 1, 135000, 0x7d4c3b5d +0, 69, 69, 1, 135000, 0x99118f21 +0, 70, 70, 1, 135000, 0xd97fe7e2 +0, 71, 71, 1, 135000, 0xf93842f1 +0, 72, 72, 1, 135000, 0x35c912e8 +0, 73, 73, 1, 135000, 0x14e59e97 0, 74, 74, 1, 135000, 0x8e4c19aa -0, 75, 75, 1, 135000, 0x4132bd4c -0, 76, 76, 1, 135000, 0x5babafe2 -0, 77, 77, 1, 135000, 0xddef6313 -0, 78, 78, 1, 135000, 0x76d6b48b -0, 79, 79, 1, 135000, 0x929e7702 -0, 80, 80, 1, 135000, 0x33f5e4a1 +0, 75, 75, 1, 135000, 0x4adfbc53 +0, 76, 76, 1, 135000, 0x0613adde +0, 77, 77, 1, 135000, 0x8db264ab +0, 78, 78, 1, 135000, 0x3948b619 +0, 79, 79, 1, 135000, 0x843d7c02 +0, 80, 80, 1, 135000, 0x534fea34 0, 81, 81, 1, 135000, 0xdb7041bf -0, 82, 82, 1, 135000, 0xbc761e04 -0, 83, 83, 1, 135000, 0x0b2a81e6 -0, 84, 84, 1, 135000, 0xf6fd20ea -0, 85, 85, 1, 135000, 0x1894a26c -0, 86, 86, 1, 135000, 0xb25e216f -0, 87, 87, 1, 135000, 0x83bb02ee -0, 88, 88, 1, 135000, 0x6952a3c3 -0, 89, 89, 1, 135000, 0x372184d6 -0, 90, 90, 1, 135000, 0x2ac47afe +0, 82, 82, 1, 135000, 0xd0ce1cce +0, 83, 83, 1, 135000, 0x3c008335 +0, 84, 84, 1, 135000, 0xb699208f +0, 85, 85, 1, 135000, 0xe07da3ca +0, 86, 86, 1, 135000, 0x26331f41 +0, 87, 87, 1, 135000, 0x4e19fe83 +0, 88, 88, 1, 135000, 0xaa9a9e45 +0, 89, 89, 1, 135000, 0x336b7ed0 +0, 90, 90, 1, 135000, 0xc9bf7611 0, 91, 91, 1, 135000, 0x14c33a35 0, 92, 92, 1, 135000, 0xdc08470e