mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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:
parent
1c20fcf0b0
commit
39a3894ad5
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user