Commit 39a3894a authored by Ben Jackson's avatar Ben Jackson Committed by Michael Niedermayer

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: 's avatarBen Jackson <ben@ben.com>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 1c20fcf0
......@@ -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)"),
};
#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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment