lavc/vp6: Implement "slice" threading for VP6A decode

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>
This commit is contained in:
Ben Jackson 2012-09-15 10:32:43 -07:00 committed by Michael Niedermayer
parent 1c20fcf0b0
commit 39a3894ad5
4 changed files with 168 additions and 133 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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)"),
};

View File

@ -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