The YUV channels of VP6 are encoded in a highly linear fashion which does not have any slice-like concept to thread. The alpha channel of VP6A is fairly independent of the YUV and comprises 40% of the work. This patch uses the THREAD_SLICE capability to split the YUV and A decodes into separate threads. Two bugs are fixed by splitting YUV and alpha state: - qscale_table from VP6A decode was for alpha channel instead of YUV - alpha channel filtering settings were overwritten by YUV header parse Signed-off-by: Ben Jackson <ben@ben.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>tags/n1.0
| @@ -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; | |||
| @@ -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; | |||
| @@ -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)"), | |||
| }; | |||
| @@ -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 | |||