Re: [FFmpeg-devel] [PATCH 087/114] avcodec/vc1: Avoid code duplication when initializing VLCs
I don't think it is a good idea to change the format of the table to something different than the tables in the SMPTE VC-1 documentation. People fluent in this documentation have a hard time correlating the new tables to the 'official' ones. --- Regards, Jerome This has been achieved by switching those VLCs that still used ff_init_vlc_sparse() to ff_init_vlc_lengths() even though the codes tables used uint8_t in these cases. But it allows to use one auxiliary function to initialize the VLCs and by using tables that interleave symbols and lengths said function only needs one parameter for the tables, not two. The only table that uses an uint16_t symbols table still has to be treated specially for this reason. The offsets table has been removed as a byproduct of these changes. Signed-off-by: Andreas Rheinhardt --- libavcodec/vc1.c | 158 +++--- libavcodec/vc1data.c | 159 +-- libavcodec/vc1data.h | 21 ++ 3 files changed, 138 insertions(+), 200 deletions(-) ... /* 4MV Block pattern VLC tables */ -const uint8_t ff_vc1_4mv_block_pattern_codes[4][16] = { -{ 14, 58, 59, 25, 12, 26, 15, 15, 13, 24, 27, 0, 28, 1, 2, 2 }, -{ 8, 18, 19, 4, 20, 5, 30, 11, 21, 31, 6, 12, 7, 13, 14, 0 }, -{ 15, 6, 7, 2, 8, 3, 28, 9, 10, 29, 4, 11, 5, 12, 13, 0 }, -{ 0, 11, 12, 4, 13, 5, 30, 16, 14, 31, 6, 17, 7, 18, 19, 10 } -}; -const uint8_t ff_vc1_4mv_block_pattern_bits[4][16] = { -{ 5, 6, 6, 5, 5, 5, 5, 4, 5, 5, 5, 3, 5, 3, 3, 2 }, -{ 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2 }, -{ 4, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3 }, -{ 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4 } +const uint8_t ff_vc1_4mv_block_pattern_tabs[4][16][2] = { +{ +{ 0x0B, 3 }, { 0x0D, 3 }, { 0x0E, 3 }, { 0x04, 5 }, { 0x08, 5 }, +{ 0x00, 5 }, { 0x06, 5 }, { 0x0F, 2 }, { 0x09, 5 }, { 0x03, 5 }, +{ 0x05, 5 }, { 0x0A, 5 }, { 0x0C, 5 }, { 0x01, 6 }, { 0x02, 6 }, +{ 0x07, 4 }, +}, +{ +{ 0x0F, 2 }, { 0x03, 4 }, { 0x05, 4 }, { 0x0A, 4 }, { 0x0C, 4 }, +{ 0x00, 4 }, { 0x01, 5 }, { 0x02, 5 }, { 0x04, 5 }, { 0x08, 5 }, +{ 0x07, 4 }, { 0x0B, 4 }, { 0x0D, 4 }, { 0x0E, 4 }, { 0x06, 5 }, +{ 0x09, 5 }, +}, +{ +{ 0x0F, 3 }, { 0x03, 4 }, { 0x05, 4 }, { 0x0A, 4 }, { 0x0C, 4 }, +{ 0x01, 4 }, { 0x02, 4 }, { 0x04, 4 }, { 0x07, 4 }, { 0x08, 4 }, +{ 0x0B, 4 }, { 0x0D, 4 }, { 0x0E, 4 }, { 0x06, 5 }, { 0x09, 5 }, +{ 0x00, 4 }, +}, +{ +{ 0x00, 2 }, { 0x03, 4 }, { 0x05, 4 }, { 0x0A, 4 }, { 0x0C, 4 }, +{ 0x07, 5 }, { 0x0B, 5 }, { 0x0D, 5 }, { 0x0E, 5 }, { 0x0F, 4 }, +{ 0x01, 4 }, { 0x02, 4 }, { 0x04, 4 }, { 0x08, 4 }, { 0x06, 5 }, +{ 0x09, 5 }, +}, }; /* 2MV Block pattern VLC tables */ -const uint8_t ff_vc1_2mv_block_pattern_codes[4][4] = { -{ 2, 1, 0, 3 }, { 1, 0, 2, 3 }, { 2, 0, 3, 1 }, { 1, 3, 2, 0 } -}; - -const uint8_t ff_vc1_2mv_block_pattern_bits[4][4] = { -{ 2, 2, 2, 2 }, { 1, 2, 3, 3 }, { 3, 2, 3, 1 }, { 1, 3, 3, 2 } +const uint8_t ff_vc1_2mv_block_pattern_tabs[4][4][2] = { +{ { 0x02, 2 }, { 0x01, 2 }, { 0x00, 2 }, { 0x03, 2 } }, +{ { 0x01, 2 }, { 0x02, 3 }, { 0x03, 3 }, { 0x00, 1 } }, +{ { 0x01, 2 }, { 0x00, 3 }, { 0x02, 3 }, { 0x03, 1 } }, +{ { 0x03, 2 }, { 0x02, 3 }, { 0x01, 3 }, { 0x00, 1 } }, }; /* Interlaced frame picture 4MV MBMODE VLC tables (tables 160-163) */ @@ -350,46 +349,42 @@ const uint8_t ff_vc1_intfr_non4mv_mbmode_tabs[4][9][2] = { /* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */ /* mixed-MV */ -const uint8_t ff_vc1_if_mmv_mbmode_codes[8][8] = { -{ 16, 17, 3, 3, 0, 5, 9, 2 }, -{ 8, 9, 3, 6, 7, 0, 5, 2 }, -{ 16, 17, 5, 3, 0, 3, 9, 2 }, -{ 56, 57, 15, 4, 5, 6, 29, 0 }, -{ 52, 53, 27, 14, 15, 2, 12, 0 }, -{ 56, 57, 29, 5, 6, 0, 15, 4 }, -{ 16, 17, 6, 7, 0, 1, 9, 5 }, -{ 56, 57, 0, 5, 6, 29, 4, 15 } -}; -const uint8_t ff_vc1_if_mmv_mbmode_bits[8][8] = { -{ 6, 6, 2, 3, 2, 4, 5, 2 }, -{ 5, 5, 3, 3, 3, 2, 4, 2 }, -{ 6, 6, 4, 3, 2, 2, 5, 2 }, -{ 6, 6, 4, 3, 3, 3, 5, 1 }, -{ 6, 6, 5, 4, 4, 2, 4, 1 }, -{ 6, 6, 5, 3, 3, 1, 4, 3 }, -{ 5, 5, 3, 3, 2, 2, 4, 3 }, -{ 6, 6, 1, 3, 3, 5, 3, 4 } +const uint8_t ff_vc1_if_mmv_mbmode_tabs[8][8][2] = { +{ { 0x04, 2 }, { 0x00, 6 }, { 0x01, 6 }, { 0x06, 5 }, + { 0x05, 4 }, { 0x03, 3 }, { 0x07, 2 }, { 0x02, 2 } }, +{ { 0x05, 2 }, { 0x00, 5 }, { 0x01, 5 }, { 0x06, 4 }, + { 0x02, 3 }, { 0x07, 2 }, { 0x03, 3 }, { 0x04, 3 } }, +{ { 0x04, 2 }, { 0x00, 6 }, { 0x01, 6 }, { 0x06, 5 }, + { 0x02, 4 }, { 0x03, 3 }, { 0x07, 2 }, { 0x05, 2 } }, +{ { 0x07, 1 }, { 0x03, 3 }, { 0x04, 3 }, { 0x05, 3 }, + { 0x00, 6 }, { 0x01, 6 }, { 0x06, 5 }, { 0x02, 4 } }, +{ { 0x07, 1 }, { 0x05, 2 }, { 0x06, 4 }, { 0x00, 6 }, + { 0x01,
Re: [FFmpeg-devel] [PATCH] avcodec/vc1: fix B predictor validity for 4-MV MBs
> 2019-01-14 9:05 GMT+01:00, Jerome Borsboom : >> The B predictor for 4-MV MBs in interlace field pictures is not used >> for blocks 0 and 2 when the picture is 1 MB wide. >> >> Signed-off-by: Jerome Borsboom >> --- >> My 'shuffle calculation of MV predictor candidates' patch overlooked the >> corner case of 1 MB wide field interlace pictures. According to VC-1 spec >> and the reference decoder, the B predictor is not used for for block 0 and >> block 2 when the picture is 1 MB wide. This patch corrects this. >> >> libavcodec/vc1_pred.c | 2 ++ >> 1 file changed, 2 insertions(+) >> >> diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c >> index e1758a3817..77dda86cd0 100644 >> --- a/libavcodec/vc1_pred.c >> +++ b/libavcodec/vc1_pred.c >> @@ -289,6 +289,8 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int >> dmv_y, >> case 3: >> off = -1; >> } >> +if (v->field_mode && s->mb_width == 1) >> +b_valid = b_valid && c_valid; > > I will push this if you don't request commit rights > but shouldn't this be "b_valid &= c_valid;"? > > Carl Eugen Please push. As b_valid and c_valid both expressions would give the same result. I really meant logical comparison, so 'b_valid = b_valid && c_valid' is correct and will short-circuit where &= would not. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vc1: fix B predictor validity for 4-MV MBs
The B predictor for 4-MV MBs in interlace field pictures is not used for blocks 0 and 2 when the picture is 1 MB wide. Signed-off-by: Jerome Borsboom --- My 'shuffle calculation of MV predictor candidates' patch overlooked the corner case of 1 MB wide field interlace pictures. According to VC-1 spec and the reference decoder, the B predictor is not used for for block 0 and block 2 when the picture is 1 MB wide. This patch corrects this. libavcodec/vc1_pred.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c index e1758a3817..77dda86cd0 100644 --- a/libavcodec/vc1_pred.c +++ b/libavcodec/vc1_pred.c @@ -289,6 +289,8 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, case 3: off = -1; } +if (v->field_mode && s->mb_width == 1) +b_valid = b_valid && c_valid; } if (v->field_mode) { -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/2 v3] avcodec/vc1: fix decoding of old WMV3 format
The position of the second MV predicitor candidate is slightly different for the old WMV3 format indicated by RES_RTM_FLAG. This patch fixes decoding of niceday.wmv on the samples server. Fixes: #6641 Signed-off-by: Jerome Borsboom --- This revision removes a spurious whitespace that was left behind. libavcodec/vc1.c | 5 - libavcodec/vc1_pred.c | 5 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 3581d87b57..e102b931d8 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -379,11 +379,6 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo } else { v->res_rtm_flag = get_bits1(gb); //reserved } -if (!v->res_rtm_flag) { -av_log(avctx, AV_LOG_ERROR, - "Old WMV3 version detected, some frames may be decoded incorrectly\n"); -//return -1; -} //TODO: figure out what they mean (always 0x402F) if (!v->res_fasttx) skip_bits(gb, 16); diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c index 0b22d9916c..e1758a3817 100644 --- a/libavcodec/vc1_pred.c +++ b/libavcodec/vc1_pred.c @@ -275,7 +275,10 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, //in 4-MV mode different blocks have different B predictor position switch (n) { case 0: -off = (s->mb_x > 0) ? -1 : 1; +if (v->res_rtm_flag) +off = s->mb_x ? -1 : 1; +else +off = s->mb_x ? -1 : 2 * s->mb_width - wrap - 1; break; case 1: off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/2 v2] avcodec/vc1: fix decoding of old WMV3 format
The position of the second MV predicitor candidate is slightly different for the old WMV3 format indicated by RES_RTM_FLAG. This patch fixes decoding of niceday.wmv on the samples server. Fixes: #6641 Signed-off-by: Jerome Borsboom --- libavcodec/vc1.c | 5 - libavcodec/vc1_pred.c | 5 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 3581d87b57..e102b931d8 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -379,11 +379,6 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo } else { v->res_rtm_flag = get_bits1(gb); //reserved } -if (!v->res_rtm_flag) { -av_log(avctx, AV_LOG_ERROR, - "Old WMV3 version detected, some frames may be decoded incorrectly\n"); -//return -1; -} //TODO: figure out what they mean (always 0x402F) if (!v->res_fasttx) skip_bits(gb, 16); diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c index 0b22d9916c..cff87907ec 100644 --- a/libavcodec/vc1_pred.c +++ b/libavcodec/vc1_pred.c @@ -275,7 +275,10 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, //in 4-MV mode different blocks have different B predictor position switch (n) { case 0: -off = (s->mb_x > 0) ? -1 : 1; +if (v->res_rtm_flag) +off = s->mb_x ? -1 : 1; +else +off = s->mb_x ? -1 : 2 * s->mb_width - wrap - 1; break; case 1: off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] avcodec/vc1: fix decoding of old WMV3 format
The position of the B MV predicitor candidate is slightly different for the old WMV3 format that is indicated by RES_RTM_FLAG. This patch fixes the decoding artifacts in the niceday.wmv sample. Signed-off-by: Jerome Borsboom --- libavcodec/vc1.c | 5 - libavcodec/vc1_pred.c | 7 ++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 3581d87b57..e102b931d8 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -379,11 +379,6 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo } else { v->res_rtm_flag = get_bits1(gb); //reserved } -if (!v->res_rtm_flag) { -av_log(avctx, AV_LOG_ERROR, - "Old WMV3 version detected, some frames may be decoded incorrectly\n"); -//return -1; -} //TODO: figure out what they mean (always 0x402F) if (!v->res_fasttx) skip_bits(gb, 16); diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c index 0b22d9916c..1ae1e33fbe 100644 --- a/libavcodec/vc1_pred.c +++ b/libavcodec/vc1_pred.c @@ -275,7 +275,12 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, //in 4-MV mode different blocks have different B predictor position switch (n) { case 0: -off = (s->mb_x > 0) ? -1 : 1; +if (v->res_rtm_flag) +off = s->mb_x ? -1 : 1; +else { +off = s->mb_x ? -1 : 2 * s->mb_width - wrap - 1; +b_valid = b_valid && (s->mb_x || s->mb_y > 1); +} break; case 1: off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] avcodec/vc1: shuffle calculation of MV predictor candidates
The B predictor for 4-MV macroblocks is only out of bounds when the A predictor is also out of bounds. Signed-off-by: Jerome Borsboom --- This patch set fixes the decoding artifacts in the niceday.wmv file on the samples server. libavcodec/vc1_pred.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c index de736ec775..0b22d9916c 100644 --- a/libavcodec/vc1_pred.c +++ b/libavcodec/vc1_pred.c @@ -262,13 +262,15 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, return; } -C = s->current_picture.motion_val[dir][xy -1 + v->blocks_off]; -A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off]; +a_valid = !s->first_slice_line || (n == 2 || n == 3); +b_valid = a_valid; +c_valid = s->mb_x || (n == 1 || n == 3); if (mv1) { if (v->field_mode && mixedmv_pic) off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; else off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2; +b_valid = b_valid && s->mb_width > 1; } else { //in 4-MV mode different blocks have different B predictor position switch (n) { @@ -285,11 +287,7 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, off = -1; } } -B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off]; -a_valid = !s->first_slice_line || (n == 2 || n == 3); -b_valid = a_valid && (s->mb_width > 1); -c_valid = s->mb_x || (n == 1 || n == 3); if (v->field_mode) { a_valid = a_valid && !is_intra[xy - wrap]; b_valid = b_valid && !is_intra[xy - wrap + off]; @@ -297,6 +295,7 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, } if (a_valid) { +A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off]; a_f = v->mv_f[dir][xy - wrap + v->blocks_off]; num_oppfield += a_f; num_samefield += 1 - a_f; @@ -307,6 +306,7 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, a_f = 0; } if (b_valid) { +B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off]; b_f = v->mv_f[dir][xy - wrap + off + v->blocks_off]; num_oppfield += b_f; num_samefield += 1 - b_f; @@ -317,6 +317,7 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, b_f = 0; } if (c_valid) { +C = s->current_picture.motion_val[dir][xy - 1 + v->blocks_off]; c_f = v->mv_f[dir][xy - 1 + v->blocks_off]; num_oppfield += c_f; num_samefield += 1 - c_f; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2] avcodec/vc1: correct aspect ratio calculation
According to VC-1 spec: * Display size defaults to max coded size when not explicitly set in sequence header * Aspect ratio in the sequence header refers to the display size elements. Therefore, the aspect ratio for the coded samples (SAR) needs to take into account the scaling from coded size to display size, and the aspect ratio of the display size elements. Signed-off-by: Jerome Borsboom --- libavcodec/vc1.c | 42 +- libavcodec/vc1.h | 2 ++ tests/ref/fate/vc1-ism | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 3581d87b57..51ad665f4b 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -442,30 +442,28 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) } v->s.max_b_frames = v->s.avctx->max_b_frames = 7; if (get_bits1(gb)) { //Display Info - decoding is not affected by it -int w, h, ar = 0; +int ar = 0; av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n"); -w = get_bits(gb, 14) + 1; -h = get_bits(gb, 14) + 1; -av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h); +v->disp_horiz_size = get_bits(gb, 14) + 1; +v->disp_vert_size = get_bits(gb, 14) + 1; +av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", + v->disp_horiz_size, v->disp_vert_size); if (get_bits1(gb)) ar = get_bits(gb, 4); if (ar && ar < 14) { -v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar]; +v->aspect_ratio = ff_vc1_pixel_aspect[ar]; } else if (ar == 15) { -w = get_bits(gb, 8) + 1; -h = get_bits(gb, 8) + 1; -v->s.avctx->sample_aspect_ratio = (AVRational){w, h}; +v->aspect_ratio.num = get_bits(gb, 8) + 1; +v->aspect_ratio.den = get_bits(gb, 8) + 1; +av_reduce(>aspect_ratio.num, >aspect_ratio.den, + v->aspect_ratio.num, v->aspect_ratio.den, + 256); } else { -av_reduce(>s.avctx->sample_aspect_ratio.num, - >s.avctx->sample_aspect_ratio.den, - v->s.avctx->height * w, - v->s.avctx->width * h, - 1 << 30); +v->aspect_ratio = (AVRational){1, 1}; } -ff_set_sar(v->s.avctx, v->s.avctx->sample_aspect_ratio); -av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", - v->s.avctx->sample_aspect_ratio.num, - v->s.avctx->sample_aspect_ratio.den); +av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect ratio: %i:%i\n", + v->aspect_ratio.num, + v->aspect_ratio.den); if (get_bits1(gb)) { //framerate stuff if (get_bits1(gb)) { @@ -490,6 +488,10 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->transfer_char = get_bits(gb, 8); v->matrix_coef = get_bits(gb, 8); } +} else { +v->disp_horiz_size = v->max_coded_width; +v->disp_vert_size = v->max_coded_height; +v->aspect_ratio = (AVRational){1, 1}; } v->hrd_param_flag = get_bits1(gb); @@ -544,6 +546,12 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex av_log(avctx, AV_LOG_ERROR, "Failed to set dimensions %d %d\n", w, h); return ret; } +av_reduce(>sample_aspect_ratio.num, + >sample_aspect_ratio.den, + v->disp_horiz_size * v->aspect_ratio.num * h, + v->disp_vert_size * v->aspect_ratio.den * w, + 1 << 30); +ff_set_sar(avctx, avctx->sample_aspect_ratio); if (v->extended_mv) v->extended_dmv = get_bits1(gb); diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 69f6ca9e4d..7674b0f9a1 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -209,6 +209,8 @@ typedef struct VC1Context{ int hrd_param_flag; ///< Presence of Hypothetical Reference ///< Decoder parameters int psf; ///< Progressive Segmented Frame +int disp_horiz_size, disp_vert_size; +AVRational aspect_ratio; //@} /** Sequence header data for all Profiles diff --git a/tests/ref/fate/vc1-ism b/tests/ref/fate/vc1-ism index 1bd6c643d9..4f460f6754 100644 --- a/tests/ref/fate/vc1-ism +++ b/tests/ref/fate/vc1-ism @@ -2,7 +2,7 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 240x104 -#sar 0: 156/156 +#sar 0: 13/30 0, 0, 0,1,37440, 0xd1bc5235 0, 2, 2,1,37440, 0x158e6167 0, 3, 3,1,37440, 0x0faa4481 -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avcodec/vc1: correct aspect ratio calculation
> Hi > [...] > > iam not sure this is valid C and not undefined > > but either way this patch breaks fate > > TESTvc1-ism > --- ./tests/ref/fate/vc1-ism 2018-11-13 19:52:23.489023763 +0100 > +++ tests/data/fate/vc1-ism 2018-11-14 21:50:11.522992878 +0100 > @@ -2,7 +2,7 @@ > #media_type 0: video > #codec_id 0: rawvideo > #dimensions 0: 240x104 > -#sar 0: 156/156 > +#sar 0: 13/30 > 0, 0, 0,1,37440, 0xd1bc5235 > 0, 2, 2,1,37440, 0x158e6167 > 0, 3, 3,1,37440, 0x0faa4481 > Test vc1-ism failed. Look at tests/data/fate/vc1-ism.err for details. > make: *** [fate-vc1-ism] Error 1 > Thank you for the catch. Although v->aspect_ratio = (AVRational){get_bits(gb, 8) + 1, get_bits(gb, 8) + 1}; is valid in C99, the order of evaluation of the initialization arguments is indeed undefined. In C90 the arguments must be constant expressions, so the previous line in which variables were used was not allowed either according to the developer documentation. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avcodec/vc1: correct aspect ratio calculation
>> +av_reduce(>sample_aspect_ratio.num, >> + >sample_aspect_ratio.den, >> + v->disp_horiz_size * v->aspect_ratio.num * h, >> + v->disp_vert_size * v->aspect_ratio.den * w, >> + 1 << 30); > >> +ff_set_sar(avctx, avctx->sample_aspect_ratio); > > I would have expected these two statements to be redundant - > am I wrong? > > Carl Eugen I am not fully sure that I understand your comment. av_reduce takes out the greatest common divisor and puts a bound on the individual fraction numbers. ff_set_sar checks that the SAR makes sense in relation to the image size. Although, the code is reassigning avctx->sample_aspect_ratio to itself in ff_set_sar, the different checks make both statements necessary. In addition, the large values that results from 'v->disp_horiz_size * v->aspect_ratio.num * h' and 'v->disp_vert_size * v->aspect_ratio.den * w', can in most cases be efficiently reduced. These two statements are moved to the entrypoint parser, because the coded size is an entrypoint element. At the position where the av_reduce statement was previously located, the v->s.avctx->height and v->s.avctx->width could contain values from the previous entrypoint header or be zero when parsing the first sequence header. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vc1: correct aspect ratio calculation
According to VC-1 spec: * Display size defaults to max coded size when not explicitly set in sequence header * Aspect ratio in the sequence header refers to the Display size elements. Therefore, the aspect ratio for the coded samples (SAR) needs to take into account the scaling from coded size to display size, and the aspect ratio of the display size elements. Signed-off-by: Jerome Borsboom --- VC-1 spec assumes that the output of the decoder, i.e. the pixel matrix with dimensions coded_width x coded_height, is scaled to display size, i.e. a pixel matrix of display_horiz_size x display_vert_size. This may introduce part of the sample aspect ratio when the sizes of the two pixel matrices are not equal. A further part of the sample aspect ratio is optionally specified in the sequence header as the aspect ratio of the display size pixels. This patch takes both aspect ratios into account and aims to be correct even when the coded image includes overscan regions. libavcodec/vc1.c | 38 +- libavcodec/vc1.h | 2 ++ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 3581d87b57..efc6edc4b0 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -442,30 +442,24 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) } v->s.max_b_frames = v->s.avctx->max_b_frames = 7; if (get_bits1(gb)) { //Display Info - decoding is not affected by it -int w, h, ar = 0; +int ar = 0; av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n"); -w = get_bits(gb, 14) + 1; -h = get_bits(gb, 14) + 1; -av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h); +v->disp_horiz_size = get_bits(gb, 14) + 1; +v->disp_vert_size = get_bits(gb, 14) + 1; +av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", + v->disp_horiz_size, v->disp_vert_size); if (get_bits1(gb)) ar = get_bits(gb, 4); if (ar && ar < 14) { -v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar]; +v->aspect_ratio = ff_vc1_pixel_aspect[ar]; } else if (ar == 15) { -w = get_bits(gb, 8) + 1; -h = get_bits(gb, 8) + 1; -v->s.avctx->sample_aspect_ratio = (AVRational){w, h}; +v->aspect_ratio = (AVRational){get_bits(gb, 8) + 1, get_bits(gb, 8) + 1}; } else { -av_reduce(>s.avctx->sample_aspect_ratio.num, - >s.avctx->sample_aspect_ratio.den, - v->s.avctx->height * w, - v->s.avctx->width * h, - 1 << 30); +v->aspect_ratio = (AVRational){1, 1}; } -ff_set_sar(v->s.avctx, v->s.avctx->sample_aspect_ratio); -av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", - v->s.avctx->sample_aspect_ratio.num, - v->s.avctx->sample_aspect_ratio.den); +av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect ratio: %i:%i\n", + v->aspect_ratio.num, + v->aspect_ratio.den); if (get_bits1(gb)) { //framerate stuff if (get_bits1(gb)) { @@ -490,6 +484,10 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->transfer_char = get_bits(gb, 8); v->matrix_coef = get_bits(gb, 8); } +} else { +v->disp_horiz_size = v->max_coded_width; +v->disp_vert_size = v->max_coded_height; +v->aspect_ratio = (AVRational){1, 1}; } v->hrd_param_flag = get_bits1(gb); @@ -544,6 +542,12 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex av_log(avctx, AV_LOG_ERROR, "Failed to set dimensions %d %d\n", w, h); return ret; } +av_reduce(>sample_aspect_ratio.num, + >sample_aspect_ratio.den, + v->disp_horiz_size * v->aspect_ratio.num * h, + v->disp_vert_size * v->aspect_ratio.den * w, + 1 << 30); +ff_set_sar(avctx, avctx->sample_aspect_ratio); if (v->extended_mv) v->extended_dmv = get_bits1(gb); diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 69f6ca9e4d..7674b0f9a1 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -209,6 +209,8 @@ typedef struct VC1Context{ int hrd_param_flag; ///< Presence of Hypothetical Reference ///< Decoder parameters int psf; ///< Progressive Segmented Frame +int disp_horiz_size, disp_vert_size; +AVRational aspect_ratio; //@} /** Sequence header data for all Profiles -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avcodec/vc1: set ticks_per_frame irrespective of FRAMERATE_FLAG
> 2018-10-23 14:50 GMT+02:00, Jerome Borsboom : >> vc1_decode_frame assumes that ticks_per_frame is set to two when RFF >> or RPTFRM is set. When FRAMERATE_FLAG is zero, this may not be the case >> as the setting of ticks_per_frame is guarded by FRAMERATE_FLAG. > > Is there a specific sample that gets fixed? > > Carl Eugen Please compare ffprobe -i SA10160.vc1 -show_packets and ffprobe -i SA10161.vc1 -show_packets SA10160.vc1 repeats each frame by setting RPTFRM to 1 for each frame, while SA10161.vc1 has RPTFRM set to 0 for each frame. Both files do not have a framerate encoded (FRAMERATE_FLAG = 0). Without the patch, both files produce frames with duration_time=0.04. With the patch, the SA10160.vc1 file produces frames with duration_time=0.08, which is double the duration_time of the SA10161.vc1 file and, hence, honours the RPTFRM flag. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vc1: set ticks_per_frame irrespective of FRAMERATE_FLAG
vc1_decode_frame assumes that ticks_per_frame is set to two when RFF or RPTFRM is set. When FRAMERATE_FLAG is zero, this may not be the case as the setting of ticks_per_frame is guarded by FRAMERATE_FLAG. Signed-off-by: Jerome Borsboom --- libavcodec/vc1.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 3581d87b57..09433ad3e9 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -422,6 +422,9 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->max_coded_width = (get_bits(gb, 12) + 1) << 1; v->max_coded_height = (get_bits(gb, 12) + 1) << 1; v->broadcast = get_bits1(gb); +if (v->broadcast) // Pulldown may be present +v->s.avctx->ticks_per_frame = 2; + v->interlace = get_bits1(gb); v->tfcntrflag= get_bits1(gb); v->finterpflag = get_bits1(gb); @@ -480,9 +483,6 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->s.avctx->framerate.num = ff_vc1_fps_nr[nr - 1] * 1000; } } -if (v->broadcast) { // Pulldown may be present -v->s.avctx->ticks_per_frame = 2; -} } if (get_bits1(gb)) { -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH V3 1/2] lavf/vc1test: fix vc1test can't probe some RCV file.
> case 1: > use the hexdump -C SMM0005.rcv get: > size skip (size - 4) > || > VV > 18 00 00 c5 05 00 00 00 4d f1 0a 11 00 e0 01 00 > 0010 00 d0 02 00 00 0c 00 00 00 88 13 00 00 c0 65 52 > ^ >| >size + 16 > case 2: > same the command for SMM0015.rcv get: > size > | > V > 19 00 00 c5 04 00 00 00 41 f3 80 01 40 02 00 00 > 0010 d0 02 00 00 0c 00 00 00 00 00 00 10 00 00 00 00 > ^ > | > size + 16 > > There are different the RCV file format for VC-1, vc1test > just handle the case 2 now, this fix will support the case 1. > (Both of test clips come from: SMPTE Recommended Practice - > VC-1 Decoder and Bitstream Conformance). And I think I got > a older VC-1 test clip in the case 1. > > Reviewed-by: Carl Eugen Hoyos > Reviewed-by: Jerome Borsboom > Reviewed-by: Michael Niedermayer > Signed-off-by: Jun Zhao > Signed-off-by: Yan, FengX > --- > libavformat/vc1test.c | 11 +-- > 1 files changed, 9 insertions(+), 2 deletions(-) > > diff --git a/libavformat/vc1test.c b/libavformat/vc1test.c > index a801f4b..e029ff4 100644 > --- a/libavformat/vc1test.c > +++ b/libavformat/vc1test.c > @@ -34,9 +34,13 @@ > > static int vc1t_probe(AVProbeData *p) > { > +int size; > + > if (p->buf_size < 24) > return 0; > -if (p->buf[3] != 0xC5 || AV_RL32(>buf[4]) != 4 || AV_RL32(>buf[20]) != 0xC) > + > +size = AV_RL32(>buf[4]); > +if (p->buf[3] != 0xC5 || size < 4 || AV_RL32(>buf[size+16]) != 0xC) > return 0; > > return AVPROBE_SCORE_EXTENSION; > @@ -48,9 +52,10 @@ static int vc1t_read_header(AVFormatContext *s) > AVStream *st; > int frames; > uint32_t fps; > +int size; > > frames = avio_rl24(pb); > -if(avio_r8(pb) != 0xC5 || avio_rl32(pb) != 4) > +if (avio_r8(pb) != 0xC5 || ((size = avio_rl32(pb)) < 4)) > return AVERROR_INVALIDDATA; > > /* init video codec */ > @@ -63,6 +68,8 @@ static int vc1t_read_header(AVFormatContext *s) > > if (ff_get_extradata(s, st->codecpar, pb, VC1_EXTRADATA_SIZE) < 0) > return AVERROR(ENOMEM); > + > +avio_skip(pb, size - 4); > st->codecpar->height = avio_rl32(pb); > st->codecpar->width = avio_rl32(pb); > if(avio_rl32(pb) != 0xC) > -- > 1.7.1 You may still overread the buffer as the first check on buf_size only checks for at least 24 bytes. The following p->buf[size+16] may read beyond the end of the buffer. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH V2 1/2] lavf/vc1test: fix vc1test can't probe some RCV file.
> On Sat, Oct 13, 2018 at 12:55 AM mypopy at gmail.com > wrote: >> >> On Fri, Oct 12, 2018 at 10:35 PM Carl Eugen Hoyos > wrote: >> > >> > 2018-10-12 15:41 GMT+02:00, Jun Zhao : >> > > case 1: >> > > use the hexdump -C SMM0005.rcv get: >> > > size skip (size - 4) >> > > || >> > > VV >> > > 18 00 00 c5 05 00 00 00 4d f1 0a 11 00 e0 01 00 >> > > 0010 00 d0 02 00 00 0c 00 00 00 88 13 00 00 c0 65 52 >> > > ^ >> > >| >> > >size + 16 >> > > case 2: >> > > same the command for SMM0015.rcv get: >> > > size >> > > | >> > > V >> > > 19 00 00 c5 04 00 00 00 41 f3 80 01 40 02 00 00 >> > > 0010 d0 02 00 00 0c 00 00 00 00 00 00 10 00 00 00 00 >> > > ^ >> > > | >> > > size + 16 >> > > >> > > There are different the RCV file format for VC-1, vc1test >> > > just handle the case 2 now, this fix will support the case 1. >> > >> > Both with and without your patch, I get identical output from >> > FFmpeg's decoder for both SSM0015.rcv and SMM0005.rcv. >> > What exactly is your patch supposed to change? >> > >> > $ md5sum SMM0005.rcv >> > abd0fa5ec90d44f7b4865c6930d65ff2 SMM0005.rcv >> > $ md5sum SSM0015.rcv >> > 21a0281f83b7f2e99a048b180dd3347f SSM0015.rcv >> >> In my test clips, I get md5 like this >> $ md5sum SMM0005.rcv >> 39eb225dbfafacea3e3737deba789530 SMM0005.rcv >> $ md5sum SMM0015.rcv >> 78e45e50079e143e69f69d677c37ac3b SMM0015.rcv > RCV format have a different version, you can google the rcv1 rcv2 for VC-1. > (e,g: > http://www.ti.com/lit/ml/sprs363a/sprs363a.pdf), I think we use a different > RCV format for test clips SMM0005.rcv This has nothing to do with the version. Version is coded as the sixth bit in the initial byte, i.e. 0x85 = version 1, 0xc5 = version 2. VC-1(2006) is quite clear in Annex L that the second dword should be a 0x0004. The reference decoder, however, is more lenient and gives more insight. The 0x0004, and the 0x000c in the seventh dword, seem to be meant as a length indicator for the STRUCT_C and the STRUCT_B, respectively. This may be a leftover from older versions. I think it won't hurt to follow the reference decoder here and interpret these dwords as length indicators. The patch could be adjusted to do this for the 0x000c as well. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avcodec/mips: fix conflicting types error of ff_vc1_h_s_overlap_mmi.
> In commit 975a1a8,function ff_vc1_h_s_overlap_mmi was refactored, > but the declaration in libavcodec/mips/vc1dsp_mips.h was unchanged. > > Change-Id: I90beae683511622a0cc1130ab1660ac8669ec3ef > Signed-off-by: Shiyou Yin > --- > libavcodec/mips/vc1dsp_mips.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/libavcodec/mips/vc1dsp_mips.h b/libavcodec/mips/vc1dsp_mips.h > index b9b07e1..0db85fa 100644 > --- a/libavcodec/mips/vc1dsp_mips.h > +++ b/libavcodec/mips/vc1dsp_mips.h > @@ -169,7 +169,7 @@ void ff_vc1_inv_trans_8x8_dc_mmi(uint8_t *dest, ptrdiff_t > linesize, int16_t *blo > void ff_vc1_v_overlap_mmi(uint8_t *src, int stride); > void ff_vc1_h_overlap_mmi(uint8_t *src, int stride); > void ff_vc1_v_s_overlap_mmi(int16_t *top, int16_t *bottom); > -void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right); > +void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right, int left_stride, > int right_stride, int flags); > > void ff_vc1_v_loop_filter4_mmi(uint8_t *src, int stride, int pq); > void ff_vc1_h_loop_filter4_mmi(uint8_t *src, int stride, int pq); > -- > 2.1.0 LGTM. My bad, sorry. Regards, Jerome Borsboom ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avcodec/vc1_block: Fix mqaunt check for negative values
> Fixes: out of array access > Fixes: ffmpeg_bof_4.avi > Fixes: ffmpeg_bof_5.avi > Fixes: ffmpeg_bof_6.avi > > Found-by: Thuan Pham, Marcel Böhme, Andrew Santosa and Alexandru Razvan > Caciulescu with AFLSmart > Signed-off-by: Michael Niedermayer > --- > libavcodec/vc1_block.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c > index 5427de4ec6..74d5e27803 100644 > --- a/libavcodec/vc1_block.c > +++ b/libavcodec/vc1_block.c > @@ -204,7 +204,7 @@ static void vc1_put_blocks_clamped(VC1Context *v, int > put_signed) > if ((edges&8) && \ > s->mb_y == ((s->mb_height >> v->field_mode) - 1)) \ > mquant = -v->altpq;\ > -if (!mquant || mquant > 31) { \ > +if (!mquant || mquant > 31 || mquant < -31) { > \ > av_log(v->s.avctx, AV_LOG_ERROR, \ > "Overriding invalid mquant %d\n", mquant); \ > mquant = 1;\ > -- > 2.18.0 LGTM However, we could consider to use saturation for invalid mquant values. Something like: mquant = mquant ? av_clip(mquant, -31, 31) : 1; I would prefer to catch illegal values at the earliest occasion. Illegal v->pq or v->altpq should be catched earlier, in my view. A the current implementation is technically correct, this can wait for another time. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/3] avcodec/vc1: fix condition guarding overlap filter on I picture
> SA10178.vc1: 18 frames ok, last 7 frames are different this one decodes correctly when you force bitexact decoding: ffmpeg -bitexact -i SA10178.vc1 SA10178_s.yuv This is caused by the issue that my rejected patch 'avcodec/x86/hpeldsp: fix half pel interpolation' tried to resolve. The proposed solution to make bitexact decoding the default for VC-1 seems right. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vc1: fix check for missing CBPTAB
CBPTAB must be present in (non skipped) P and B pictures. Signed-off-by: Jerome Borsboom --- This patch set should fix decoding of the SA10135.vc1 test file to make it bit-equal to the reference decoder. libavcodec/vc1dec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index fdbc852ec2..9519864c55 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -1088,7 +1088,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y); continue; } -if (!v->p_frame_skipped && s->pict_type != AV_PICTURE_TYPE_I && !v->cbpcy_vlc) { +if (((s->pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || + (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)) && +!v->cbpcy_vlc) { av_log(v->s.avctx, AV_LOG_ERROR, "missing cbpcy_vlc\n"); continue; } -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] avcodec/vc1: fix condition guarding overlap filter on I picture
The overlap filter needs to run when PQUANT is 9 or higher, irrespective of CONDOVER. Signed-off-by: Jerome Borsboom --- This patch set should fix decoding of the SA10125.vc1 test file to make it bit-equal to the reference decoder. libavcodec/vc1_block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index c620566f78..b58b71b3e0 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -2726,7 +2726,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) v->vc1dsp.vc1_inv_trans_8x8(block[k]); } -if (v->overlap && v->condover != CONDOVER_NONE) +if (v->overlap && (v->pq >= 9 || v->condover != CONDOVER_NONE)) ff_vc1_i_overlap_filter(v); vc1_put_blocks_clamped(v, 1); if (v->s.loop_filter) -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/3] avcodec/vc1: change the internal ordering of blocks within a macroblock
The overlap filter needs to cover a full macroblock vertical edge when the FIELDTX value for two neighbouring macroblocks is not equal. By changing the internal ordering of the blocks from row major to column major, we do not need to reinterlace a FIELDTX coded macroblock before running the overlap filter. Signed-off-by: Jerome Borsboom --- libavcodec/vc1_block.c | 65 +- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index b58b71b3e0..a2321eddb9 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -45,6 +45,9 @@ static const uint8_t offset_table[2][9] = { { 0, 1, 3, 7, 15, 31, 63, 127, 255 }, }; +// mapping table for internal block representation +static const int block_map[6] = {0, 2, 1, 3, 4, 5}; + /***/ /** * @name VC-1 Bitplane decoding @@ -86,11 +89,11 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed) v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i] - 2]) { dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + ((i & 1) - 2) * 8; if (put_signed) - s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][i], + s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][block_map[i]], i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, i > 3 ? s->uvlinesize : s->linesize); else - s->idsp.put_pixels_clamped(v->block[v->topleft_blk_idx][i], + s->idsp.put_pixels_clamped(v->block[v->topleft_blk_idx][block_map[i]], i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, i > 3 ? s->uvlinesize : s->linesize); } @@ -102,11 +105,11 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed) v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i]]) { dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + (i & 1) * 8; if (put_signed) - s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][i], + s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][block_map[i]], i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, i > 3 ? s->uvlinesize : s->linesize); else -s->idsp.put_pixels_clamped(v->block[v->top_blk_idx][i], + s->idsp.put_pixels_clamped(v->block[v->top_blk_idx][block_map[i]], i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, i > 3 ? s->uvlinesize : s->linesize); } @@ -125,11 +128,11 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed) else dest = s->dest[0] + (i & 2) * 4 * s->linesize + ((i & 1) - 2) * 8; if (put_signed) - s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][i], + s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][block_map[i]], i > 3 ? s->dest[i - 3] - 8 : dest, i > 3 ? s->uvlinesize : s->linesize << fieldtx); else - s->idsp.put_pixels_clamped(v->block[v->left_blk_idx][i], + s->idsp.put_pixels_clamped(v->block[v->left_blk_idx][block_map[i]], i > 3 ? s->dest[i - 3] - 8 : dest, i > 3 ? s->uvlinesize : s->linesize << fieldtx); } @@ -145,11 +148,11 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed) else dest = s->dest[0] + (i & 2) * 4 * s->linesize + (i & 1) * 8; if (put_signed) - s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i], + s->idsp.put_signed_pixels_clamped(v->block[v->
[FFmpeg-devel] [PATCH 3/3] avcodec/vc1: fix overlap filter for frame interlaced pictures
The overlap filter is not correct for vertical edges in frame interlaced I and P pictures. When filtering macroblocks with different FIELDTX values, we have to match the lines at both sides of the vertical border. In addition, we have to use the correct rounding values, depending on the line we are filtering. Signed-off-by: Jerome Borsboom --- libavcodec/mips/vc1dsp_mmi.c | 15 libavcodec/vc1_loopfilter.c | 86 libavcodec/vc1dsp.c | 15 libavcodec/vc1dsp.h | 2 +- 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/libavcodec/mips/vc1dsp_mmi.c b/libavcodec/mips/vc1dsp_mmi.c index 01e7f9f32c..ec2fdca987 100644 --- a/libavcodec/mips/vc1dsp_mmi.c +++ b/libavcodec/mips/vc1dsp_mmi.c @@ -1019,12 +1019,13 @@ void ff_vc1_h_overlap_mmi(uint8_t *src, int stride) } } -void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right) +void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right, int left_stride, int right_stride, int flags) { int i; int a, b, c, d; int d1, d2; -int rnd1 = 4, rnd2 = 3; +int rnd1 = flags & 2 ? 3 : 4; +int rnd2 = 7 - rnd1; for (i = 0; i < 8; i++) { a = left[6]; b = left[7]; @@ -1038,10 +1039,12 @@ void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right) right[0] = ((c << 3) + d2 + rnd1) >> 3; right[1] = ((d << 3) + d1 + rnd2) >> 3; -right += 8; -left += 8; -rnd2 = 7 - rnd2; -rnd1 = 7 - rnd1; +right += right_stride; +left += left_stride; +if (flags & 1) { +rnd2 = 7 - rnd2; +rnd1 = 7 - rnd1; +} } } diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 5d5630db67..d43fa5b3ae 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -32,25 +32,74 @@ #include "vc1dsp.h" static av_always_inline void vc1_h_overlap_filter(VC1Context *v, int16_t (*left_block)[64], - int16_t (*right_block)[64], int block_num) + int16_t (*right_block)[64], int left_fieldtx, + int right_fieldtx, int block_num) { -if (block_num > 3) -v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num]); -else if (block_num & 1) -v->vc1dsp.vc1_h_s_overlap(right_block[block_num - 1], right_block[block_num]); -else -v->vc1dsp.vc1_h_s_overlap(left_block[block_num + 1], right_block[block_num]); +switch (block_num) { +case 0: +v->vc1dsp.vc1_h_s_overlap(left_block[2], + right_block[0], + left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8, + left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8, + left_fieldtx || right_fieldtx ? 0 : 1); +break; + +case 1: +v->vc1dsp.vc1_h_s_overlap(right_block[0], + right_block[2], + 8, + 8, + right_fieldtx ? 0 : 1); +break; + +case 2: +v->vc1dsp.vc1_h_s_overlap(!left_fieldtx && right_fieldtx ? left_block[2] + 8 : left_block[3], + left_fieldtx && !right_fieldtx ? right_block[0] + 8 : right_block[1], + left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8, + left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8, + left_fieldtx || right_fieldtx ? 2 : 1); +break; + +case 3: +v->vc1dsp.vc1_h_s_overlap(right_block[1], + right_block[3], + 8, + 8, + right_fieldtx ? 2 : 1); +break; + +case 4: +case 5: +v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num], 8, 8, 1); +break; +} } static av_always_inline void vc1_v_overlap_filter(VC1Context *v, int16_t (*top_block)[64], int16_t (*bottom_block)[64], int block_num) { -if (block_num > 3) +switch (block_num) { +case 0: +v->vc1dsp.vc1_v_s_overlap(top_block[1], bottom_block[0]); +break; + +case 1: +v->vc1dsp.vc1_v_s_overlap(top_block[3], bottom_block[2]); +break; + +case 2: +v->vc1dsp.vc1_v_s_overlap(bottom_block[0], bottom_block[1]); +break; + +case 3: +v->vc1dsp.vc1_v_s_overlap(bottom_block[2], bottom_block[3]); +break; +
Re: [FFmpeg-devel] [PATCH 3/4 v3] avcodec/vc1: rewrite vc1_decode_i_blocks to align with VC-1 spec
Commit 2065317db6dc3a219f8ed2de427fe7e19e02eb68 is the initial version of the patch. The devel-mailing has a v2 version: '[PATCH 2/4 v2] avcodec/vc1: add Simple and Main profile to vc1_put_signed_blocks_clamped' dated Fri Jun 8 12:01:26 EEST 2018. Regards, Jerome On 18-6-2018 1:00, Michael Niedermayer wrote: > On Tue, Jun 12, 2018 at 11:34:58AM +0200, Jerome Borsboom wrote: >> Change vc1_decode_i_blocks to use vc1_put_blocks_clamped and >> ff_vc1_i_loop_filter. >> >> Signed-off-by: Jerome Borsboom >> --- >> The v3 patch should resolve the crashing that was seen on corrupted source >> files. > > This (commit 77a3dfb328df535fb98d43ed2204fc6a42d6dd5e) broke fate > that is fate-mss2-wmv > fate-suite//mss2/msscreencodec.wmv with this shows a large green column and > checksums > changed > > --- ./tests/ref/fate/mss2-wmv 2018-06-15 22:31:04.412555973 +0200 > +++ tests/data/fate/mss2-wmv 2018-06-18 00:54:56.484378249 +0200 > @@ -36,70 +36,70 @@ > 0, 36, 36,1, 230400, 0x08bb41ee > 0, 37, 37,1, 230400, 0x43ccbd29 > 0, 38, 38,1, 230400, 0x4ee3 > -0, 39, 39,1, 230400, 0xbfd2ef29 > -0, 40, 40,1, 230400, 0x6504545f > -0, 41, 41,1, 230400, 0x8fb86901 > +0, 39, 39,1, 230400, 0x527879e5 > +0, 40, 40,1, 230400, 0x1cc7e329 > +0, 41, 41,1, 230400, 0xde1706ab > 0, 42, 42,1, 230400, 0xc95f0917 > -0, 43, 43,1, 230400, 0x21f6a54b > -0, 44, 44,1, 230400, 0xf808106b > -0, 45, 45,1, 230400, 0x34150020 > -0, 46, 46,1, 230400, 0x50fdfe89 > +0, 43, 43,1, 230400, 0x81353456 > +0, 44, 44,1, 230400, 0x8a15a752 > +0, 45, 45,1, 230400, 0xede88dbb > +0, 46, 46,1, 230400, 0xb22fa577 > 0, 47, 47,1, 230400, 0x920b7708 > -0, 48, 48,1, 230400, 0xed64fcc4 > -0, 49, 49,1, 230400, 0x6291a170 > -0, 50, 50,1, 230400, 0x20524643 > +0, 48, 48,1, 230400, 0x581c924c > +0, 49, 49,1, 230400, 0x18952c56 > +0, 50, 50,1, 230400, 0x45d9e3f3 > 0, 51, 51,1, 230400, 0x92aafecd > -0, 52, 52,1, 230400, 0xf00ee14d > -0, 53, 53,1, 230400, 0xfa3113ea > -0, 54, 54,1, 230400, 0x99c06df1 > -0, 55, 55,1, 230400, 0x625c6918 > +0, 52, 52,1, 230400, 0x1f789647 > +0, 53, 53,1, 230400, 0x12ba8c93 > +0, 54, 54,1, 230400, 0x6aabb970 > +0, 55, 55,1, 230400, 0x1b3e003d > 0, 56, 56,1, 230400, 0xb277b25e > -0, 57, 57,1, 230400, 0x2e913006 > -0, 58, 58,1, 230400, 0x3f6f1d99 > -0, 59, 59,1, 230400, 0x100ab60f > +0, 57, 57,1, 230400, 0x511eb729 > +0, 58, 58,1, 230400, 0x7328a657 > +0, 59, 59,1, 230400, 0xfa2d5eed > 0, 60, 60,1, 230400, 0x9b73d0bf > -0, 61, 61,1, 230400, 0xda0df2ce > -0, 62, 62,1, 230400, 0x67f7ca24 > -0, 63, 63,1, 230400, 0xbde9b3d0 > -0, 64, 64,1, 230400, 0x92e14d07 > +0, 61, 61,1, 230400, 0xd5698c41 > +0, 62, 62,1, 230400, 0xa9c332d7 > +0, 63, 63,1, 230400, 0x22451f10 > +0, 64, 64,1, 230400, 0x6fc0b571 > 0, 65, 65,1, 230400, 0x9426c3d9 > -0, 66, 66,1, 230400, 0x6104be70 > -0, 67, 67,1, 230400, 0xc4d1078a > -0, 68, 68,1, 230400, 0x89426a42 > -0, 69, 69,1, 230400, 0x5271324a > +0, 66, 66,1, 230400, 0x375932bf > +0, 67, 67,1, 230400, 0xaf3f9d2e > +0, 68, 68,1, 230400, 0xefced725 > +0, 69, 69,1, 230400, 0xaa85d8b3 > 0, 70, 70,1, 230400, 0x1cb1c735 > -0, 71, 71,1, 230400, 0x4249b8c6 > -0, 72, 72,1, 230400
Re: [FFmpeg-devel] [PATCH 1/2] avcodec/vaapi: slice_vertical_position starts from zero for the second field
Is your VAAPI library and VAAPI driver new enough? You need at least libva-2.1.0 (VA-API version 1.1.0) and intel-vaapi-driver-2.1.0 for interlaced VC-1 decoding. From the output, I think you are using an older version and the error is just the libva library bailing out for not supporting interlaced VC-1. Regards, Jerome > are these 2 patches enough or something else ? > It feels like iam missing something but > > i tried > ./ffmpeg -hwaccel vaapi -i SA10180.vc1 -pix_fmt yuv420p -f framecrc crcpatch12 > > but ffmpeg spews errors at me: > > ibva info: VA-API version 0.39.0 > libva info: va_getDriverName() returns 0 > libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so > libva info: Found init function __vaDriverInit_0_39 > libva info: va_openDriver() returns 0 > Stream mapping: > Stream #0:0 -> #0:0 (vc1 (native) -> rawvideo (native)) > Press [q] to stop, [?] for help > Output #0, framecrc, to 'crcpatch12': > Metadata: > encoder : Lavf58.17.100 > Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 720x480 [SAR > 1:1 DAR 3:2], q=2-31, 103680 kb/s, 25 fps, 25 tbn, 25 tbc > Metadata: > encoder : Lavc58.20.102 rawvideo > [vc1 @ 0x3d430c0] Failed to end picture decode issue: 23 (unknown libva error > / description missing). > Error while decoding stream #0:0: Input/output error ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/4 v3] avcodec/vc1: rewrite vc1_decode_i_blocks to align with VC-1 spec
Change vc1_decode_i_blocks to use vc1_put_blocks_clamped and ff_vc1_i_loop_filter. Signed-off-by: Jerome Borsboom --- The v3 patch should resolve the crashing that was seen on corrupted source files. libavcodec/vc1_block.c | 79 +++--- 1 file changed, 30 insertions(+), 49 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 1dc8c6422d..c620566f78 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -2537,30 +2537,28 @@ static void vc1_decode_i_blocks(VC1Context *v) s->mb_x = s->mb_y = 0; s->mb_intra = 1; s->first_slice_line = 1; -for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) { +for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; init_block_index(v); for (; s->mb_x < v->end_mb_x; s->mb_x++) { -uint8_t *dst[6]; +int16_t (*block)[64] = v->block[v->cur_blk_idx]; ff_update_block_index(s); -dst[0] = s->dest[0]; -dst[1] = dst[0] + 8; -dst[2] = s->dest[0] + s->linesize * 8; -dst[3] = dst[2] + 8; -dst[4] = s->dest[1]; -dst[5] = s->dest[2]; -s->bdsp.clear_blocks(s->block[0]); +s->bdsp.clear_blocks(block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_width; s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; s->current_picture.qscale_table[mb_pos]= v->pq; -s->current_picture.motion_val[1][s->block_index[0]][0] = 0; -s->current_picture.motion_val[1][s->block_index[0]][1] = 0; +for (int i = 0; i < 4; i++) { +s->current_picture.motion_val[1][s->block_index[i]][0] = 0; +s->current_picture.motion_val[1][s->block_index[i]][1] = 0; +} // do actual MB decoding and displaying cbp = get_vlc2(>s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); v->s.ac_pred = get_bits1(>s.gb); for (k = 0; k < 6; k++) { +v->mb_type[0][s->block_index[k]] = 1; + val = ((cbp >> (5 - k)) & 1); if (k < 4) { @@ -2570,52 +2568,30 @@ static void vc1_decode_i_blocks(VC1Context *v) } cbp |= val << (5 - k); -vc1_decode_i_block(v, s->block[k], k, val, (k < 4) ? v->codingset : v->codingset2); +vc1_decode_i_block(v, block[k], k, val, (k < 4) ? v->codingset : v->codingset2); if (CONFIG_GRAY && k > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; -v->vc1dsp.vc1_inv_trans_8x8(s->block[k]); -if (v->pq >= 9 && v->overlap) { -if (v->rangeredfrm) +v->vc1dsp.vc1_inv_trans_8x8(block[k]); +} + +if (v->overlap && v->pq >= 9) { +ff_vc1_i_overlap_filter(v); +if (v->rangeredfrm) +for (k = 0; k < 6; k++) for (j = 0; j < 64; j++) -s->block[k][j] <<= 1; -s->idsp.put_signed_pixels_clamped(s->block[k], dst[k], - k & 4 ? s->uvlinesize -: s->linesize); -} else { -if (v->rangeredfrm) +block[k][j] <<= 1; +vc1_put_blocks_clamped(v, 1); +} else { +if (v->rangeredfrm) +for (k = 0; k < 6; k++) for (j = 0; j < 64; j++) -s->block[k][j] = (s->block[k][j] - 64) << 1; -s->idsp.put_pixels_clamped(s->block[k], dst[k], - k & 4 ? s->uvlinesize - : s->linesize); -} +block[k][j] = (block[k][j] - 64) << 1; +vc1_put_blocks_clamped(v, 0); } -if (v->pq >= 9 && v->overlap) { -if (s->mb_x) { -v->vc1dsp.vc1_h_overlap(s->dest[0], s->linesize); -v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { -v->vc1dsp.vc1_h_overlap(s->dest[1]
Re: [FFmpeg-devel] [PATCH 3/4 v2] avcodec/vc1: rewrite vc1_decode_i_blocks to align with VC-1 spec
Thank you for the rigorous testing of my patches. I try to be careful when changing things, but every now and then I unwittingly may break things that do not surface in setup. There is something strange with the backtraces. The 'Slice header damaged' error indicates that the source file is coded with slices. Slices, however, only occur in VC-1 advanced profile. The backtrace with the invalid read contains vc1_decode_i_blocks which is only used in Simple and Main profile. I currently do not see how this adds up. Is this crash related to a specific source file? If so, could you share it? Regards, Jerome > > crashes: > > [vc1 @ 0x11b77200] Slice header damaged > ==2065==at 0x120D69C: VALGRIND_PRINTF_BACKTRACE (valgrind.h:4550) > ==2065==by 0x120E11C: av_log_default_callback (log.c:351) > ==2065==by 0x120E2BB: av_vlog (log.c:377) > ==2065==by 0x120E27B: av_log (log.c:369) > ==2065==by 0xC3B5B5: vc1_decode_frame (vc1dec.c:1014) > ==2065==by 0x8A6BAB: decode_simple_internal (decode.c:398) > ==2065==by 0x8A7832: decode_simple_receive_frame (decode.c:594) > ==2065==by 0x8A78FD: decode_receive_frame_internal (decode.c:612) > ==2065==by 0x8A7B75: avcodec_send_packet (decode.c:674) > ==2065==by 0x43373E: decode (ffmpeg.c:2238) > ==2065==by 0x433F98: decode_video (ffmpeg.c:2382) > ==2065==by 0x434FE0: process_input_packet (ffmpeg.c:2623) > ==2065==by 0x43C207: process_input (ffmpeg.c:4461) > ==2065==by 0x43C7B0: transcode_step (ffmpeg.c:4581) > ==2065==by 0x43C92C: transcode (ffmpeg.c:4635) > ==2065==by 0x43D199: main (ffmpeg.c:4842) > ==2065== Invalid read of size 8 > ==2065==at 0xD790BD: ??? (libavcodec/x86/vc1dsp_loopfilter.asm:302) > ==2065==by 0xC26AA6: vc1_i_v_loop_filter (vc1_loopfilter.c:239) > ==2065==by 0xC26BFB: ff_vc1_i_loop_filter (vc1_loopfilter.c:266) > ==2065==by 0xC23C72: vc1_decode_i_blocks (vc1_block.c:2594) > ==2065==by 0xC259D4: ff_vc1_decode_blocks (vc1_block.c:2969) > ==2065==by 0xC3B7D6: vc1_decode_frame (vc1dec.c:1042) > ==2065==by 0x8A6BAB: decode_simple_internal (decode.c:398) > ==2065==by 0x8A7832: decode_simple_receive_frame (decode.c:594) > ==2065==by 0x8A78FD: decode_receive_frame_internal (decode.c:612) > ==2065==by 0x8A7B75: avcodec_send_packet (decode.c:674) > ==2065==by 0x43373E: decode (ffmpeg.c:2238) > ==2065==by 0x433F98: decode_video (ffmpeg.c:2382) > ==2065==by 0x434FE0: process_input_packet (ffmpeg.c:2623) > ==2065==by 0x43C207: process_input (ffmpeg.c:4461) > ==2065==by 0x43C7B0: transcode_step (ffmpeg.c:4581) > ==2065==by 0x43C92C: transcode (ffmpeg.c:4635) > ==2065==by 0x43D199: main (ffmpeg.c:4842) > ==2065== Address 0x11f25100 is not stack'd, malloc'd or (recently) free'd > > > > ==2065== Process terminating with default action of signal 11 (SIGSEGV) > ==2065== General Protection Fault > ==2065==at 0x13786A6: ??? (in ffmpeg/ffmpeg_g) > ==2065==by 0x11F8D78: av_buffer_pool_uninit (buffer.c:285) > ==2065==by 0xBF5F7B: avcodec_close (utils.c:1089) > ==2065==by 0x43CCB5: transcode (ffmpeg.c:4697) > ==2065==by 0x43D199: main (ffmpeg.c:4842) > > [...] ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/2] avcodec/vaapi: slice_vertical_position starts from zero for the second field
If there are no more issues or remarks with these two patches, could someone please commit them? Thanks! Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/4 v2] avcodec/vc1: rewrite vc1_decode_i_blocks to align with VC-1 spec
Change vc1_decode_i_blocks to use vc1_put_blocks_clamped and ff_vc1_i_loop_filter. Signed-off-by: Jerome Borsboom --- libavcodec/vc1_block.c | 77 +++--- 1 file changed, 29 insertions(+), 48 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 1dc8c6422d..a7ba261ccb 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -2541,26 +2541,24 @@ static void vc1_decode_i_blocks(VC1Context *v) s->mb_x = 0; init_block_index(v); for (; s->mb_x < v->end_mb_x; s->mb_x++) { -uint8_t *dst[6]; +int16_t (*block)[64] = v->block[v->cur_blk_idx]; ff_update_block_index(s); -dst[0] = s->dest[0]; -dst[1] = dst[0] + 8; -dst[2] = s->dest[0] + s->linesize * 8; -dst[3] = dst[2] + 8; -dst[4] = s->dest[1]; -dst[5] = s->dest[2]; -s->bdsp.clear_blocks(s->block[0]); +s->bdsp.clear_blocks(block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_width; s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; s->current_picture.qscale_table[mb_pos]= v->pq; -s->current_picture.motion_val[1][s->block_index[0]][0] = 0; -s->current_picture.motion_val[1][s->block_index[0]][1] = 0; +for (int i = 0; i < 4; i++) { +s->current_picture.motion_val[1][s->block_index[i]][0] = 0; +s->current_picture.motion_val[1][s->block_index[i]][1] = 0; +} // do actual MB decoding and displaying cbp = get_vlc2(>s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); v->s.ac_pred = get_bits1(>s.gb); for (k = 0; k < 6; k++) { +v->mb_type[0][s->block_index[k]] = 1; + val = ((cbp >> (5 - k)) & 1); if (k < 4) { @@ -2570,52 +2568,30 @@ static void vc1_decode_i_blocks(VC1Context *v) } cbp |= val << (5 - k); -vc1_decode_i_block(v, s->block[k], k, val, (k < 4) ? v->codingset : v->codingset2); +vc1_decode_i_block(v, block[k], k, val, (k < 4) ? v->codingset : v->codingset2); if (CONFIG_GRAY && k > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; -v->vc1dsp.vc1_inv_trans_8x8(s->block[k]); -if (v->pq >= 9 && v->overlap) { -if (v->rangeredfrm) +v->vc1dsp.vc1_inv_trans_8x8(block[k]); +} + +if (v->overlap && v->pq >= 9) { +ff_vc1_i_overlap_filter(v); +if (v->rangeredfrm) +for (k = 0; k < 6; k++) for (j = 0; j < 64; j++) -s->block[k][j] <<= 1; -s->idsp.put_signed_pixels_clamped(s->block[k], dst[k], - k & 4 ? s->uvlinesize -: s->linesize); -} else { -if (v->rangeredfrm) +block[k][j] <<= 1; +vc1_put_blocks_clamped(v, 1); +} else { +if (v->rangeredfrm) +for (k = 0; k < 6; k++) for (j = 0; j < 64; j++) -s->block[k][j] = (s->block[k][j] - 64) << 1; -s->idsp.put_pixels_clamped(s->block[k], dst[k], - k & 4 ? s->uvlinesize - : s->linesize); -} +block[k][j] = (block[k][j] - 64) << 1; +vc1_put_blocks_clamped(v, 0); } -if (v->pq >= 9 && v->overlap) { -if (s->mb_x) { -v->vc1dsp.vc1_h_overlap(s->dest[0], s->linesize); -v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { -v->vc1dsp.vc1_h_overlap(s->dest[1], s->uvlinesize); -v->vc1dsp.vc1_h_overlap(s->dest[2], s->uvlinesize); -} -} -v->vc1dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize); -v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize); -
Re: [FFmpeg-devel] [PATCH 1/4 v2] avcodec/vc1: fix overlap and loop filtering for Simple and Main profile
Overlap filtering I and BI frames for Simple and Main profile is only dependent on PQUANT. Restrict testing for CONDOVER and OVERFLAGS to advanced profile. Change from mb_width to end_mb_x in ff_vc1_i_loop_filter to avoid breaking the Microsoft Screen 2 decoder. Signed-off-by: Jerome Borsboom --- The v2 patches should resolve the issue with fate-mss2-wmv. libavcodec/vc1_loopfilter.c | 35 --- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index aceb1f77ff..cea7dae7f8 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -108,8 +108,10 @@ void ff_vc1_i_overlap_filter(VC1Context *v) if (s->mb_x == 0 && (i & 5) != 1) continue; -if (v->pq >= 9 || v->condover == CONDOVER_ALL || -(v->over_flags_plane[mb_pos] && ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1]))) +if (v->pq >= 9 || (v->profile == PROFILE_ADVANCED && + (v->condover == CONDOVER_ALL || +(v->over_flags_plane[mb_pos] && + ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1]) vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk, i); } @@ -118,15 +120,18 @@ void ff_vc1_i_overlap_filter(VC1Context *v) if (s->first_slice_line && !(i & 2)) continue; -if (s->mb_x && (v->pq >= 9 || v->condover == CONDOVER_ALL || -(v->over_flags_plane[mb_pos - 1] && - ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride] +if (s->mb_x && +(v->pq >= 9 || (v->profile == PROFILE_ADVANCED && +(v->condover == CONDOVER_ALL || + (v->over_flags_plane[mb_pos - 1] && + ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride])) vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i); -if (s->mb_x == s->mb_width - 1) -if (v->pq >= 9 || v->condover == CONDOVER_ALL || -(v->over_flags_plane[mb_pos] && - ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride]))) -vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i); +if (s->mb_x == s->mb_width - 1 && +(v->pq >= 9 || (v->profile == PROFILE_ADVANCED && +(v->condover == CONDOVER_ALL || + (v->over_flags_plane[mb_pos] && + ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride])) +vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i); } } @@ -260,7 +265,7 @@ void ff_vc1_i_loop_filter(VC1Context *v) for (i = 0; i < block_count; i++) vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, flags, fieldtx, i); } -if (s->mb_x == s->mb_width - 1) { +if (s->mb_x == v->end_mb_x - 1) { dest += 16; fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride]; for (i = 0; i < block_count; i++) @@ -275,7 +280,7 @@ void ff_vc1_i_loop_filter(VC1Context *v) for (i = 0; i < block_count; i++) vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, flags, fieldtx, i); } -if (s->mb_x == s->mb_width - 1) { +if (s->mb_x == v->end_mb_x - 1) { dest += 16; fieldtx = v->fieldtx_plane[mb_pos]; for (i = 0; i < block_count; i++) @@ -290,7 +295,7 @@ void ff_vc1_i_loop_filter(VC1Context *v) for (i = 0; i < block_count; i++) vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest, flags, i); } -if (s->mb_x == s->mb_width - 1) { +if (s->mb_x == v->end_mb_x - 1) { dest += 16; flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE; for (i = 0; i < block_count; i++) @@ -305,7 +310,7 @@ void ff_vc1_i_loop_filter(VC1Context *v) for (i = 0; i < block_count; i++) vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, flags, i); } -if (s->mb_x == s->mb_width - 1) { +if (s->mb_x == v->end_mb_x - 1) { flags = s->mb_x
Re: [FFmpeg-devel] [PATCH 2/4 v2] avcodec/vc1: add Simple and Main profile to vc1_put_signed_blocks_clamped
Simple and Main Profile also need unsigned put_pixels_clamped. Add an argument to choose between signed and unsigned put_pixels and change function name to vc1_put_blocks_clamped. Signed-off-by: Jerome Borsboom --- libavcodec/vc1_block.c | 58 +- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index caf1596812..1dc8c6422d 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -66,7 +66,7 @@ static inline void init_block_index(VC1Context *v) /** @} */ //Bitplane group -static void vc1_put_signed_blocks_clamped(VC1Context *v) +static void vc1_put_blocks_clamped(VC1Context *v, int put_signed) { MpegEncContext *s = >s; uint8_t *dest; @@ -85,20 +85,30 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) if (i > 3 ? v->mb_type[0][s->block_index[i] - s->block_wrap[i] - 1] : v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i] - 2]) { dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + ((i & 1) - 2) * 8; - s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, - i > 3 ? s->uvlinesize : s->linesize); +if (put_signed) + s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, + i > 3 ? s->uvlinesize : s->linesize); +else + s->idsp.put_pixels_clamped(v->block[v->topleft_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, + i > 3 ? s->uvlinesize : s->linesize); } } } -if (s->mb_x == s->mb_width - 1) { +if (s->mb_x == v->end_mb_x - 1) { for (i = 0; i < block_count; i++) { if (i > 3 ? v->mb_type[0][s->block_index[i] - s->block_wrap[i]] : v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i]]) { dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + (i & 1) * 8; - s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, - i > 3 ? s->uvlinesize : s->linesize); +if (put_signed) + s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, + i > 3 ? s->uvlinesize : s->linesize); +else +s->idsp.put_pixels_clamped(v->block[v->top_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, + i > 3 ? s->uvlinesize : s->linesize); } } } @@ -114,13 +124,18 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) dest = s->dest[0] + ((i & 2) >> 1) * s->linesize + ((i & 1) - 2) * 8; else dest = s->dest[0] + (i & 2) * 4 * s->linesize + ((i & 1) - 2) * 8; - s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 : dest, - i > 3 ? s->uvlinesize : s->linesize << fieldtx); +if (put_signed) + s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 : dest, + i > 3 ? s->uvlinesize : s->linesize << fieldtx); +else + s->idsp.put_pixels_clamped(v->block[v->left_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 : dest, +
[FFmpeg-devel] [PATCH 4/4] avcodec/vc1: remove unused ff_vc1_loop_filter_iblk
Signed-off-by: Jerome Borsboom --- libavcodec/vc1.h| 1 - libavcodec/vc1_loopfilter.c | 30 -- 2 files changed, 31 deletions(-) diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 1d283f8589..69f6ca9e4d 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -422,7 +422,6 @@ void ff_vc1_init_transposed_scantables(VC1Context *v); int ff_vc1_decode_end(AVCodecContext *avctx); void ff_vc1_decode_blocks(VC1Context *v); -void ff_vc1_loop_filter_iblk(VC1Context *v, int pq); void ff_vc1_i_overlap_filter(VC1Context *v); void ff_vc1_p_overlap_filter(VC1Context *v); void ff_vc1_i_loop_filter(VC1Context *v); diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 39b298cd28..fd83eaa7f5 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -31,36 +31,6 @@ #include "vc1.h" #include "vc1dsp.h" -void ff_vc1_loop_filter_iblk(VC1Context *v, int pq) -{ -MpegEncContext *s = >s; -int j; -if (!s->first_slice_line) { -v->vc1dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq); -if (s->mb_x) -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq); -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) -for (j = 0; j < 2; j++) { -v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1], s->uvlinesize, pq); -if (s->mb_x) -v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq); -} -} -v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8 * s->linesize, s->linesize, pq); - -if (s->mb_y == s->end_mb_y - 1) { -if (s->mb_x) { -v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { -v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq); -v->vc1dsp.vc1_h_loop_filter8(s->dest[2], s->uvlinesize, pq); -} -} -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] + 8, s->linesize, pq); -} -} - static av_always_inline void vc1_h_overlap_filter(VC1Context *v, int16_t (*left_block)[64], int16_t (*right_block)[64], int block_num) { -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] avcodec/vc1: add Simple and Main profile to vc1_put_signed_blocks_clamped
Simple and Main profile also need unsigned put_pixels_clamped. Add an argument to choose between signed and unsigned put_pixels and change function name to vc1_put_blocks_clamped. Signed-off-by: Jerome Borsboom --- libavcodec/vc1_block.c | 54 ++ 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index caf1596812..ae179a15cc 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -66,7 +66,7 @@ static inline void init_block_index(VC1Context *v) /** @} */ //Bitplane group -static void vc1_put_signed_blocks_clamped(VC1Context *v) +static void vc1_put_blocks_clamped(VC1Context *v, int put_signed) { MpegEncContext *s = >s; uint8_t *dest; @@ -85,9 +85,14 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) if (i > 3 ? v->mb_type[0][s->block_index[i] - s->block_wrap[i] - 1] : v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i] - 2]) { dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + ((i & 1) - 2) * 8; - s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, - i > 3 ? s->uvlinesize : s->linesize); +if (put_signed) + s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, + i > 3 ? s->uvlinesize : s->linesize); +else + s->idsp.put_pixels_clamped(v->block[v->topleft_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, + i > 3 ? s->uvlinesize : s->linesize); } } } @@ -96,9 +101,14 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) if (i > 3 ? v->mb_type[0][s->block_index[i] - s->block_wrap[i]] : v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i]]) { dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + (i & 1) * 8; - s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, - i > 3 ? s->uvlinesize : s->linesize); +if (put_signed) + s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, + i > 3 ? s->uvlinesize : s->linesize); +else +s->idsp.put_pixels_clamped(v->block[v->top_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, + i > 3 ? s->uvlinesize : s->linesize); } } } @@ -114,9 +124,14 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) dest = s->dest[0] + ((i & 2) >> 1) * s->linesize + ((i & 1) - 2) * 8; else dest = s->dest[0] + (i & 2) * 4 * s->linesize + ((i & 1) - 2) * 8; - s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 : dest, - i > 3 ? s->uvlinesize : s->linesize << fieldtx); +if (put_signed) + s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 : dest, + i > 3 ? s->uvlinesize : s->linesize << fieldtx); +else + s->idsp.put_pixels_clamped(v->block[v->left_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 : dest, + i > 3 ? s->uvlinesize : s->linesize <<
[FFmpeg-devel] [PATCH 3/4] avcodec/vc1: rewrite vc1_decode_i_blocks to align with VC-1 spec
Change vc1_decode_i_blocks to use vc1_put_blocks_clamped and ff_vc1_i_loop_filter. Signed-off-by: Jerome Borsboom --- libavcodec/vc1_block.c | 77 ++ 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index ae179a15cc..1890ee8901 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -2541,26 +2541,24 @@ static void vc1_decode_i_blocks(VC1Context *v) s->mb_x = 0; init_block_index(v); for (; s->mb_x < v->end_mb_x; s->mb_x++) { -uint8_t *dst[6]; +int16_t (*block)[64] = v->block[v->cur_blk_idx]; ff_update_block_index(s); -dst[0] = s->dest[0]; -dst[1] = dst[0] + 8; -dst[2] = s->dest[0] + s->linesize * 8; -dst[3] = dst[2] + 8; -dst[4] = s->dest[1]; -dst[5] = s->dest[2]; -s->bdsp.clear_blocks(s->block[0]); +s->bdsp.clear_blocks(block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_width; s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; s->current_picture.qscale_table[mb_pos]= v->pq; -s->current_picture.motion_val[1][s->block_index[0]][0] = 0; -s->current_picture.motion_val[1][s->block_index[0]][1] = 0; +for (int i = 0; i < 4; i++) { +s->current_picture.motion_val[1][s->block_index[i]][0] = 0; +s->current_picture.motion_val[1][s->block_index[i]][1] = 0; +} // do actual MB decoding and displaying cbp = get_vlc2(>s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); v->s.ac_pred = get_bits1(>s.gb); for (k = 0; k < 6; k++) { +v->mb_type[0][s->block_index[k]] = 1; + val = ((cbp >> (5 - k)) & 1); if (k < 4) { @@ -2570,52 +2568,28 @@ static void vc1_decode_i_blocks(VC1Context *v) } cbp |= val << (5 - k); -vc1_decode_i_block(v, s->block[k], k, val, (k < 4) ? v->codingset : v->codingset2); +vc1_decode_i_block(v, block[k], k, val, (k < 4) ? v->codingset : v->codingset2); if (CONFIG_GRAY && k > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; -v->vc1dsp.vc1_inv_trans_8x8(s->block[k]); -if (v->pq >= 9 && v->overlap) { -if (v->rangeredfrm) -for (j = 0; j < 64; j++) -s->block[k][j] <<= 1; -s->idsp.put_signed_pixels_clamped(s->block[k], dst[k], - k & 4 ? s->uvlinesize -: s->linesize); -} else { -if (v->rangeredfrm) -for (j = 0; j < 64; j++) -s->block[k][j] = (s->block[k][j] - 64) << 1; -s->idsp.put_pixels_clamped(s->block[k], dst[k], - k & 4 ? s->uvlinesize - : s->linesize); -} +v->vc1dsp.vc1_inv_trans_8x8(block[k]); } -if (v->pq >= 9 && v->overlap) { -if (s->mb_x) { -v->vc1dsp.vc1_h_overlap(s->dest[0], s->linesize); -v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { -v->vc1dsp.vc1_h_overlap(s->dest[1], s->uvlinesize); -v->vc1dsp.vc1_h_overlap(s->dest[2], s->uvlinesize); -} -} -v->vc1dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize); -v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize); -if (!s->first_slice_line) { -v->vc1dsp.vc1_v_overlap(s->dest[0], s->linesize); -v->vc1dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { -v->vc1dsp.vc1_v_overlap(s->dest[1], s->uvlinesize); -v->vc1dsp.vc1_v_overlap(s->dest[2], s->uvlinesize); -} -} -v->vc1dsp.
[FFmpeg-devel] [PATCH 1/4] avcodec/vc1: fix overlap filtering for Simple and Main profile
Overlap filtering I and BI frames for Simple and Main profile is only dependent on PQUANT. Restrict testing for CONDOVER and OVERFLAGS to advanced profile. Signed-off-by: Jerome Borsboom --- This patch set should fix decoding of the SSL0015.rcv test file to make it bit-equal to the reference decoder. libavcodec/vc1_loopfilter.c | 25 +++-- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index aceb1f77ff..39b298cd28 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -108,8 +108,10 @@ void ff_vc1_i_overlap_filter(VC1Context *v) if (s->mb_x == 0 && (i & 5) != 1) continue; -if (v->pq >= 9 || v->condover == CONDOVER_ALL || -(v->over_flags_plane[mb_pos] && ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1]))) +if (v->pq >= 9 || (v->profile == PROFILE_ADVANCED && + (v->condover == CONDOVER_ALL || +(v->over_flags_plane[mb_pos] && + ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1]) vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk, i); } @@ -118,15 +120,18 @@ void ff_vc1_i_overlap_filter(VC1Context *v) if (s->first_slice_line && !(i & 2)) continue; -if (s->mb_x && (v->pq >= 9 || v->condover == CONDOVER_ALL || -(v->over_flags_plane[mb_pos - 1] && - ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride] +if (s->mb_x && +(v->pq >= 9 || (v->profile == PROFILE_ADVANCED && +(v->condover == CONDOVER_ALL || + (v->over_flags_plane[mb_pos - 1] && + ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride])) vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i); -if (s->mb_x == s->mb_width - 1) -if (v->pq >= 9 || v->condover == CONDOVER_ALL || -(v->over_flags_plane[mb_pos] && - ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride]))) -vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i); +if (s->mb_x == s->mb_width - 1 && +(v->pq >= 9 || (v->profile == PROFILE_ADVANCED && +(v->condover == CONDOVER_ALL || + (v->over_flags_plane[mb_pos] && + ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride])) +vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i); } } -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v2] avcodec/vc1: fix overlap smoothing filter for P frames
> The patch also fixes SSL0014.rcv, the only sample in this directory > that still doesn't decode bit-exact is SSL0015.rcv, I don't know if the > issue is also loopfilter-related. > > Thank you, Carl Eugen Could someone with access to the test files check the output of the Intel hardware decoder through VAAPI for file SSL0015.rcv? I am running into an issue that may be a hardware bug, but I only have Haswell platform to test on. It looks like the hardware tries to read beyond the end of the slice data and subsequently fails to output the last macroblock of the image. ffmpeg -hwaccel vaapi -i SSL0015.rcv -pix_fmt yuv420p -f framecrc - The frames of interest are frames 221 and 301. The CRCs from the reference decoder are: 0,221,221,1,38016, 0x0c2f9de6 0,301,301,1,38016, 0x6877442f My Haswell gives: 0,221,221,1,38016, 0xd8709e80 0,301,301,1,38016, 0x20bd44e7 Thanks, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v2] avcodec/vc1: fix overlap smoothing filter for P frames
The v_overlap_filter needs to run on the colocated block of the previous macroblock. For the luma plane, the colocated block is located two blocks on the left instead of one. In addition, the overlap filter needs to run on the non-edge blocks of the first macroblock row and column. Signed-off-by: Jerome Borsboom --- This is an improved patch that should also fix the remaining frames in SSL0013.rcv. libavcodec/vc1_loopfilter.c | 60 ++--- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 4c0de7c025..aceb1f77ff 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -64,27 +64,23 @@ void ff_vc1_loop_filter_iblk(VC1Context *v, int pq) static av_always_inline void vc1_h_overlap_filter(VC1Context *v, int16_t (*left_block)[64], int16_t (*right_block)[64], int block_num) { -if (left_block != right_block || (block_num & 5) == 1) { -if (block_num > 3) -v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num]); -else if (block_num & 1) -v->vc1dsp.vc1_h_s_overlap(right_block[block_num - 1], right_block[block_num]); -else -v->vc1dsp.vc1_h_s_overlap(left_block[block_num + 1], right_block[block_num]); -} +if (block_num > 3) +v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num]); +else if (block_num & 1) +v->vc1dsp.vc1_h_s_overlap(right_block[block_num - 1], right_block[block_num]); +else +v->vc1dsp.vc1_h_s_overlap(left_block[block_num + 1], right_block[block_num]); } static av_always_inline void vc1_v_overlap_filter(VC1Context *v, int16_t (*top_block)[64], int16_t (*bottom_block)[64], int block_num) { -if (top_block != bottom_block || block_num & 2) { -if (block_num > 3) -v->vc1dsp.vc1_v_s_overlap(top_block[block_num], bottom_block[block_num]); -else if (block_num & 2) -v->vc1dsp.vc1_v_s_overlap(bottom_block[block_num - 2], bottom_block[block_num]); -else -v->vc1dsp.vc1_v_s_overlap(top_block[block_num + 2], bottom_block[block_num]); -} +if (block_num > 3) +v->vc1dsp.vc1_v_s_overlap(top_block[block_num], bottom_block[block_num]); +else if (block_num & 2) +v->vc1dsp.vc1_v_s_overlap(bottom_block[block_num - 2], bottom_block[block_num]); +else +v->vc1dsp.vc1_v_s_overlap(top_block[block_num + 2], bottom_block[block_num]); } void ff_vc1_i_overlap_filter(VC1Context *v) @@ -108,21 +104,28 @@ void ff_vc1_i_overlap_filter(VC1Context *v) * borders. Therefore, the H overlap trails by one MB col and the * V overlap trails by one MB row. This is reflected in the time at which * we run the put_pixels loop, i.e. delayed by one row and one column. */ -for (i = 0; i < block_count; i++) +for (i = 0; i < block_count; i++) { +if (s->mb_x == 0 && (i & 5) != 1) +continue; + if (v->pq >= 9 || v->condover == CONDOVER_ALL || -(v->over_flags_plane[mb_pos] && ((i & 5) == 1 || (s->mb_x && v->over_flags_plane[mb_pos - 1] +(v->over_flags_plane[mb_pos] && ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1]))) vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk, i); +} if (v->fcm != ILACE_FRAME) for (i = 0; i < block_count; i++) { +if (s->first_slice_line && !(i & 2)) +continue; + if (s->mb_x && (v->pq >= 9 || v->condover == CONDOVER_ALL || (v->over_flags_plane[mb_pos - 1] && - ((i & 2) || (!s->first_slice_line && v->over_flags_plane[mb_pos - 1 - s->mb_stride]) + ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride] vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i); if (s->mb_x == s->mb_width - 1) if (v->pq >= 9 || v->condover == CONDOVER_ALL || (v->over_flags_plane[mb_pos] && - ((i & 2) || (!s->first_slice_line && v->over_flags_plane[mb_pos - s->mb_stride] + ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride]))) vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i); } } @@ -139,18 +142,25 @@ void ff_vc1_p_overlap_filter(VC1Context *v) left_blk = v->block[v->left_blk_idx]; cur_blk = v->block[v->cur_blk_idx
[FFmpeg-devel] [PATCH] avcodec/vc1: fix overlap smoothing filter for P frames
The v_overlap_filter needs to run on the colocated block of the previous macroblock. For the luma plane, the colocated block is located two blocks on the left instead of one. Signed-off-by: Jerome Borsboom --- This should fix the issue with the SA10100.vc1 test file. libavcodec/vc1_loopfilter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 4c0de7c025..676922aa18 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -145,8 +145,8 @@ void ff_vc1_p_overlap_filter(VC1Context *v) if (v->fcm != ILACE_FRAME) for (i = 0; i < block_count; i++) { -if (s->mb_x && v->mb_type[0][s->block_index[i] - 1] && -(s->first_slice_line || v->mb_type[0][s->block_index[i] - s->block_wrap[i] - 1])) +if (s->mb_x && v->mb_type[0][s->block_index[i] - 2 + (i > 3)] && +(s->first_slice_line || v->mb_type[0][s->block_index[i] - s->block_wrap[i] - 2 + (i > 3)])) vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i); if (s->mb_x == s->mb_width - 1) if (v->mb_type[0][s->block_index[i]] && -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v3] avcodec/vc1: fix out-of-bounds reference pixel replication
Out-of-bounds reference pixel replication should take into account the frame coding mode of the reference frame(s), not the frame coding mode of the current frame. Signed-off-by: Jerome Borsboom --- Even more corrections. The starting line must also be adjusted by one for an opposite refence field. libavcodec/vc1_mc.c | 668 ++-- 1 file changed, 385 insertions(+), 283 deletions(-) diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c index 04b359204c..1b8d8799b3 100644 --- a/libavcodec/vc1_mc.c +++ b/libavcodec/vc1_mc.c @@ -179,12 +179,17 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) int i; uint8_t (*luty)[256], (*lutuv)[256]; int use_ic; +int interlace; +int linesize, uvlinesize; if ((!v->field_mode || (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && !v->s.last_picture.f->data[0]) return; +linesize = s->current_picture_ptr->f->linesize[0]; +uvlinesize = s->current_picture_ptr->f->linesize[1]; + mx = s->mv[dir][0][0]; my = s->mv[dir][0][1]; @@ -220,6 +225,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->curr_luty; lutuv = v->curr_lutuv; use_ic = *v->curr_use_ic; +interlace = 1; } else { srcY = s->last_picture.f->data[0]; srcU = s->last_picture.f->data[1]; @@ -227,6 +233,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->last_luty; lutuv = v->last_lutuv; use_ic = v->last_use_ic; +interlace = s->last_picture.f->interlaced_frame; } } else { srcY = s->next_picture.f->data[0]; @@ -235,6 +242,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->next_luty; lutuv = v->next_lutuv; use_ic = v->next_use_ic; +interlace = s->next_picture.f->interlaced_frame; } if (!srcY || !srcU) { @@ -269,9 +277,9 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) srcV += uvsrc_y * s->uvlinesize + uvsrc_x; if (v->field_mode && v->ref_field_type[dir]) { -srcY += s->current_picture_ptr->f->linesize[0]; -srcU += s->current_picture_ptr->f->linesize[1]; -srcV += s->current_picture_ptr->f->linesize[2]; +srcY += linesize; +srcU += uvlinesize; +srcV += uvlinesize; } /* for grayscale we should not try to read from unknown area */ @@ -289,112 +297,105 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) const int k = 17 + s->mspel * 2; srcY -= s->mspel * (1 + s->linesize); -if (v->fcm == ILACE_FRAME) { -if (src_y - s->mspel & 1) { -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos + 1 >> 1); -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, - 2 * s->linesize, - 2 * s->linesize, - k, - k >> 1, - src_x - s->mspel, - src_y - s->mspel + 1 >> 1, - s->h_edge_pos, - v_edge_pos >> 1); -} else { -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos >> 1); -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, - 2
Re: [FFmpeg-devel] [PATCH v2] avcodec/vc1: fix out-of-bounds reference pixel replication
Out-of-bounds reference pixel replication should take into account the frame coding mode of the reference frame(s), not the frame coding mode of the current frame. Signed-off-by: Jerome Borsboom --- Does this resolve the SIGSEGV? I think I made a mistake in the calculation of the starting line for progressive reference pictures when the current picture is a field interlaced picture. Instead of adjusting the edge position, the starting line must be adjusted as the vertical stride for replication is half the stride of the field interlaced picture. libavcodec/vc1_mc.c | 659 ++-- 1 file changed, 379 insertions(+), 280 deletions(-) diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c index 04b359204c..16fc531712 100644 --- a/libavcodec/vc1_mc.c +++ b/libavcodec/vc1_mc.c @@ -179,12 +179,17 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) int i; uint8_t (*luty)[256], (*lutuv)[256]; int use_ic; +int interlace; +int linesize, uvlinesize; if ((!v->field_mode || (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && !v->s.last_picture.f->data[0]) return; +linesize = s->current_picture_ptr->f->linesize[0]; +uvlinesize = s->current_picture_ptr->f->linesize[1]; + mx = s->mv[dir][0][0]; my = s->mv[dir][0][1]; @@ -220,6 +225,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->curr_luty; lutuv = v->curr_lutuv; use_ic = *v->curr_use_ic; +interlace = 1; } else { srcY = s->last_picture.f->data[0]; srcU = s->last_picture.f->data[1]; @@ -227,6 +233,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->last_luty; lutuv = v->last_lutuv; use_ic = v->last_use_ic; +interlace = s->last_picture.f->interlaced_frame; } } else { srcY = s->next_picture.f->data[0]; @@ -235,6 +242,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->next_luty; lutuv = v->next_lutuv; use_ic = v->next_use_ic; +interlace = s->next_picture.f->interlaced_frame; } if (!srcY || !srcU) { @@ -269,9 +277,9 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) srcV += uvsrc_y * s->uvlinesize + uvsrc_x; if (v->field_mode && v->ref_field_type[dir]) { -srcY += s->current_picture_ptr->f->linesize[0]; -srcU += s->current_picture_ptr->f->linesize[1]; -srcV += s->current_picture_ptr->f->linesize[2]; +srcY += linesize; +srcU += uvlinesize; +srcV += uvlinesize; } /* for grayscale we should not try to read from unknown area */ @@ -289,112 +297,104 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) const int k = 17 + s->mspel * 2; srcY -= s->mspel * (1 + s->linesize); -if (v->fcm == ILACE_FRAME) { -if (src_y - s->mspel & 1) { -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos + 1 >> 1); -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, - 2 * s->linesize, - 2 * s->linesize, - k, - k >> 1, - src_x - s->mspel, - src_y - s->mspel + 1 >> 1, - s->h_edge_pos, - v_edge_pos >> 1); -} else { -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, -
Re: [FFmpeg-devel] [PATCH] avcodec/vc1: fix out-of-bounds reference pixel replication
>> Out-of-bounds reference pixel replication should take into account >> the frame coding mode of the reference frame(s), not the frame >> coding mode of the current frame. >> >> Signed-off-by: Jerome Borsboom >> --- >> This should fix the remaining issue with the SA10180.vc1 test file. > > With this patch, the first 601 frames are decoded bit-exact, the > following frame is not decoded correctly. > > Carl Eugen Are you sure you have applied all five patches of my previous patch set? The set has only been partially applied to the master branch. My output is fully equal to the output of the reference decoder. You could also specify -bitexact on the command line when decoding as I have previously run into issues with non-bitexact decoding. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vc1: fix out-of-bounds reference pixel replication
Out-of-bounds reference pixel replication should take into account the frame coding mode of the reference frame(s), not the frame coding mode of the current frame. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- This should fix the remaining issue with the SA10180.vc1 test file. libavcodec/vc1_mc.c | 659 ++-- 1 file changed, 379 insertions(+), 280 deletions(-) diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c index 04b359204c..b0f246eb4d 100644 --- a/libavcodec/vc1_mc.c +++ b/libavcodec/vc1_mc.c @@ -179,12 +179,17 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) int i; uint8_t (*luty)[256], (*lutuv)[256]; int use_ic; +int interlace; +int linesize, uvlinesize; if ((!v->field_mode || (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && !v->s.last_picture.f->data[0]) return; +linesize = s->current_picture_ptr->f->linesize[0]; +uvlinesize = s->current_picture_ptr->f->linesize[1]; + mx = s->mv[dir][0][0]; my = s->mv[dir][0][1]; @@ -220,6 +225,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->curr_luty; lutuv = v->curr_lutuv; use_ic = *v->curr_use_ic; +interlace = 1; } else { srcY = s->last_picture.f->data[0]; srcU = s->last_picture.f->data[1]; @@ -227,6 +233,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->last_luty; lutuv = v->last_lutuv; use_ic = v->last_use_ic; +interlace = s->last_picture.f->interlaced_frame; } } else { srcY = s->next_picture.f->data[0]; @@ -235,6 +242,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) luty = v->next_luty; lutuv = v->next_lutuv; use_ic = v->next_use_ic; +interlace = s->next_picture.f->interlaced_frame; } if (!srcY || !srcU) { @@ -269,9 +277,9 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) srcV += uvsrc_y * s->uvlinesize + uvsrc_x; if (v->field_mode && v->ref_field_type[dir]) { -srcY += s->current_picture_ptr->f->linesize[0]; -srcU += s->current_picture_ptr->f->linesize[1]; -srcV += s->current_picture_ptr->f->linesize[2]; +srcY += linesize; +srcU += uvlinesize; +srcV += uvlinesize; } /* for grayscale we should not try to read from unknown area */ @@ -289,112 +297,104 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) const int k = 17 + s->mspel * 2; srcY -= s->mspel * (1 + s->linesize); -if (v->fcm == ILACE_FRAME) { -if (src_y - s->mspel & 1) { -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos + 1 >> 1); -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, - 2 * s->linesize, - 2 * s->linesize, - k, - k >> 1, - src_x - s->mspel, - src_y - s->mspel + 1 >> 1, - s->h_edge_pos, - v_edge_pos >> 1); -} else { -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, - srcY, - 2 * s->linesize, - 2 * s->linesize, - k, - k + 1 >> 1, - src_x - s->mspel, - src_y - s->mspel >> 1, - s->h_edge_pos, - v_edge_pos >> 1); -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, - srcY + s->linesize, -
Re: [FFmpeg-devel] [PATCH v2 1/5] avcodec/vc1: FIELDTX is only present in interlaced frame I/BI pictures
If v->fieldtx_is_raw is not reset to zero, it may spill over from a previous interlaced frame I/BI picture. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- This may address the concerns. Will make a mental note to clean up the parser at a later time. Thank you for the review. libavcodec/vc1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 949fec6bee..98b24e8e57 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -1010,7 +1010,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) return -1; av_log(v->s.avctx, AV_LOG_DEBUG, "FIELDTX plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); -} +} else +v->fieldtx_is_raw = 0; status = bitplane_decoding(v->acpred_plane, >acpred_is_raw, v); if (status < 0) return -1; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 5/5] avcodec/vc1: store zero MVs for all blocks in a MB
>> Direct prediction for interlace frame B pictures references the mv in the >> second block in an MB in the backward reference frame for the twomv case. >> When the backward reference frame is an I frame, this value may be unset. >> >> Signed-off-by: Jerome Borsboom >> --- >> libavcodec/vc1_block.c | 6 -- >> 1 file changed, 4 insertions(+), 2 deletions(-) >> >> diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c >> index 74935ec9e9..9c170a1e3c 100644 >> --- a/libavcodec/vc1_block.c >> +++ b/libavcodec/vc1_block.c >> @@ -2678,8 +2678,10 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) >> s->bdsp.clear_blocks(block[0]); >> mb_pos = s->mb_x + s->mb_y * s->mb_stride; >> s->current_picture.mb_type[mb_pos + v->mb_off] >>= MB_TYPE_INTRA; >> -s->current_picture.motion_val[1][s->block_index[0] + >> v->blocks_off][0] = 0; >> -s->current_picture.motion_val[1][s->block_index[0] + >> v->blocks_off][1] = 0; >> +for (int i = 0; i < 4; i++) { >> +s->current_picture.motion_val[1][s->block_index[i] + >> v->blocks_off][0] = 0; >> +s->current_picture.motion_val[1][s->block_index[i] + >> v->blocks_off][1] = 0; >> +} > > see AV_ZERO* This style of setting motion_val to zero is used all over the VC-1 decoder. vc1_decode_p_mb_intfr uses the exact same code. Changing to AV_ZERO may certainly a good point for improvement, however, for the sake of consistency the proposed code might be preferable. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/5] avcodec/vc1: fix mquant calculation for interlace field pictures
>> On Fri, May 18, 2018 at 05:06:23PM +0200, Jerome Borsboom wrote: >>> For interlace field pictures s->mb_height indicates the height of the >>> full >>> picture in MBs, i.e. the two fields combined. A single field is half this >>> size. When calculating mquant for interlace field pictures, the bottom >>> edge >>> is the last MB row of the field. >>> >>> Signed-off-by: Jerome Borsboom >>> --- >>> libavcodec/vc1_block.c | 3 ++- >>> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> for patch 1 you list a file that it improves. > > The file - afaict - is related to the patchset as a whole. > The current version of the patchset does not fix the > file though, so I believe we should wait for a new > version of the patchset. > > The sample is >20MB, most of the reference files are > very small, so perhaps we can avoid using this one. > > Carl Eugen The issue that remains is not related to this patch set. In my view, there is no need to wait for a new patch set. I will just submit a new patch for that issue. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/5] avcodec/vc1: FIELDTX is only coded raw in interlaced frame I pictures
>> libavcodec/vc1_block.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c >> index f59c440943..daf30fdbfe 100644 >> --- a/libavcodec/vc1_block.c >> +++ b/libavcodec/vc1_block.c >> @@ -2680,7 +2680,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) >> s->current_picture.motion_val[1][s->block_index[0] + >> v->blocks_off][1] = 0; >> >> // do actual MB decoding and displaying >> -if (v->fieldtx_is_raw) >> +if (v->fcm == ILACE_FRAME && v->fieldtx_is_raw) >> v->fieldtx_plane[mb_pos] = get_bits1(>s.gb); > > fieldtx_is_raw is only set when fcm == ILACE_FRAME > I suspect the intend was it is unset otherwise. This would avoid the extra > check I think this may be a design decision. You can either set the decoding context, 'v' in this case, to a sane default or only use syntax elements where appropriate. The current state of the bitstream decoder for VC-1 is not very clean in this regard. But it does certainly not reset the decoding context for each frame and even depends on this behaviour for at least one case. While I think it may be better to reset the decoding context to sane defaults for each frame for the applicable variables, for now, I would like to propose to leave the bitstream decoder as is and use this patch. Currently, I am focusing on compliance to the VC-1 spec and a cleanup of the bitstream decoder may be something down the road. A trac issue might be appropriate to remember this issue, although the decoder in general could use a good cleanup. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/5] avcodec/vc1: FIELDTX is only coded raw in interlaced frame I pictures
> 2018-05-18 17:06 GMT+02:00, Jerome Borsboom : > >> This patch set solves various issues that affected the SA10180.vc1 >> test file. With these patches applied, this file decodes bitequal to >> the Intel VAAPI decoder on Haswell. > > I still see artefacts beginning after ~22 seconds that are not visible > with the reference decoder, the first 547 frames are bit-exact. > > Carl Eugen I have found the issue that produces the artifacts. I need to update both ffmpeg and the Intel VAAPI driver as both make the same wrong assumption. Please expect at least one more patch in the coming days to resolve this issue. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/5] avcodec/vc1: fix mquant calculation for interlace field pictures
For interlace field pictures s->mb_height indicates the height of the full picture in MBs, i.e. the two fields combined. A single field is half this size. When calculating mquant for interlace field pictures, the bottom edge is the last MB row of the field. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index daf30fdbfe..aa2ea5024e 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -181,7 +181,8 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) mquant = -v->altpq;\ if ((edges&4) && s->mb_x == (s->mb_width - 1)) \ mquant = -v->altpq;\ -if ((edges&8) && s->mb_y == (s->mb_height - 1))\ +if ((edges&8) && \ +s->mb_y == ((s->mb_height >> v->field_mode) - 1)) \ mquant = -v->altpq;\ if (!mquant || mquant > 31) { \ av_log(v->s.avctx, AV_LOG_ERROR, \ -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/5] avcodec/vc1: DIRECTBIT is only present in inter MBs
DIRECTBIT was decoded before the intra/inter MB branching when decoding interlace frame B pictures. Resulting in mistakenly also decoding it for intra MBs where this syntax element is not present. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 71 +- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index aa2ea5024e..74935ec9e9 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -2173,41 +2173,6 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) } } -if (v->dmb_is_raw) -direct = get_bits1(gb); -else -direct = v->direct_mb_plane[mb_pos]; - -if (direct) { -if (s->next_picture_ptr->field_picture) -av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n"); -s->mv[0][0][0] = s->current_picture.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample); -s->mv[0][0][1] = s->current_picture.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample); -s->mv[1][0][0] = s->current_picture.motion_val[1][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 1, s->quarter_sample); -s->mv[1][0][1] = s->current_picture.motion_val[1][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 1, s->quarter_sample); - -if (twomv) { -s->mv[0][2][0] = s->current_picture.motion_val[0][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 0, s->quarter_sample); -s->mv[0][2][1] = s->current_picture.motion_val[0][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 0, s->quarter_sample); -s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample); -s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample); - -for (i = 1; i < 4; i += 2) { -s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0]; -s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1]; -s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0]; -s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][i-1][1]; -} -} else { -for (i = 1; i < 4; i++) { -s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][0][0]; -s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][0][1]; -s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][0][0]; -s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][0][1]; -} -} -} - if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB for (i = 0; i < 4; i++) { s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = 0; @@ -2258,6 +2223,42 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) } } else { s->mb_intra = v->is_intra[s->mb_x] = 0; + +if (v->dmb_is_raw) +direct = get_bits1(gb); +else +direct = v->direct_mb_plane[mb_pos]; + +if (direct) { +if (s->next_picture_ptr->field_picture) +av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n"); +s->mv[0][0][0] = s->current_picture.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample); +s->mv[0][0][1] = s->current_picture.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample); +s->mv[1][0][0] = s->current_picture.motion_val[1][s->block_inde
[FFmpeg-devel] [PATCH 4/5] avcodec/vc1: fix calculation of the last line of a slice
Only for the last slice of the first field is the last line of the slice equal to the height of the field. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 750f4dff1c..fdbc852ec2 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -1082,7 +1082,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, av_log(v->s.avctx, AV_LOG_ERROR, "first field slice count too large\n"); continue; } -s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); +s->end_mb_y = (i == n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); } if (s->end_mb_y <= s->start_mb_y) { av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y); -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 5/5] avcodec/vc1: store zero MVs for all blocks in a MB
Direct prediction for interlace frame B pictures references the mv in the second block in an MB in the backward reference frame for the twomv case. When the backward reference frame is an I frame, this value may be unset. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 74935ec9e9..9c170a1e3c 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -2678,8 +2678,10 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->bdsp.clear_blocks(block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_stride; s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; -s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; -s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; +for (int i = 0; i < 4; i++) { +s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = 0; +s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = 0; +} // do actual MB decoding and displaying if (v->fcm == ILACE_FRAME && v->fieldtx_is_raw) -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/5] avcodec/vc1: FIELDTX is only coded raw in interlaced frame I pictures
FIELDTX bitplane is only present in interlace frame I pictures. v->fieldtx_is_raw may spill over from a previous interlaced frame I picture while decoding a non-interlace frame I picture. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- This patch set solves various issues that affected the SA10180.vc1 test file. With these patches applied, this file decodes bitequal to the Intel VAAPI decoder on Haswell. Please also review my patch set of May 9th that enables hwaccel decode of the SA10180.vc1 file. libavcodec/vc1_block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index f59c440943..daf30fdbfe 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -2680,7 +2680,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; // do actual MB decoding and displaying -if (v->fieldtx_is_raw) +if (v->fcm == ILACE_FRAME && v->fieldtx_is_raw) v->fieldtx_plane[mb_pos] = get_bits1(>s.gb); cbp = get_vlc2(>s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); if (v->acpred_is_raw) -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/2] avcodec/vaapi: slice_vertical_position starts from zero for the second field
>> Contrary to VC-1 spec, VAAPI expects the row address of the first >> macroblock row in the first slice to start from zero for the second >> field in a field interlaced picture. >> >> Signed-off-by: Jerome Borsboom >> --- >> This patch set adds support for hardware decoding multi-slice field >> interlaced >> pictures. With this patch set, the SA10180 test file decodes correctly with >> VAAPI hardware acceleration. This was succesfully tested on Intel Haswell >> platform. >> > > I still see lots of artifacts for a multi-slice field interfaced VC-1 video on > Coffee Lake, maybe we should fix it in the driver > > Thanks > Haihao I suppose you also applied the second part of this patch and still see artifacts. I cannot check for Coffee Lake, but there may be issues with the VAAPI driver for CL platform. The patches are just a copy of the multi-slice support for frame interlaced images, so nothing special there. Could you share (part of) the video you used to check on Coffee Lake so that I can see how Haswell performs? Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] avcodec/vc1: support multi-slice field interlaced pictures with hwaccel
When using hardware accelerated decoding for multi-slice field interlaced pictures, only the first slice was decoded. This patch adds the neccesary looping over the remaining slices that may exist in field interlaced pictures. Additionally, we align the calculation of mby_start for the second field with the method given in VC-1 spec. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1dec.c | 67 +++-- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 40a3e501dd..750f4dff1c 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -698,9 +698,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, slices[n_slices].buf); init_get_bits([n_slices].gb, slices[n_slices].buf, buf_size3 << 3); -/* assuming that the field marker is at the exact middle, - hope it's correct */ -slices[n_slices].mby_start = s->mb_height + 1 >> 1; +slices[n_slices].mby_start = avctx->coded_height + 31 >> 5; slices[n_slices].rawbuf = start; slices[n_slices].raw_size = size + 4; n_slices1 = n_slices - 1; // index of the last slice of the first field @@ -903,13 +901,41 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, s->picture_structure = PICT_BOTTOM_FIELD - v->tff; if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, buf_start_second_field - buf_start)) < 0) goto err; -if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, buf_start_second_field - buf_start)) < 0) -goto err; + +if (n_slices1 == -1) { +// no slices, decode the field as-is +if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, buf_start_second_field - buf_start)) < 0) +goto err; +} else { +if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, slices[0].rawbuf - buf_start)) < 0) +goto err; + +for (i = 0 ; i < n_slices1 + 1; i++) { +s->gb = slices[i].gb; +s->mb_y = slices[i].mby_start; + +v->pic_header_flag = get_bits1(>gb); +if (v->pic_header_flag) { +if (ff_vc1_parse_frame_header_adv(v, >gb) < 0) { +av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); +ret = AVERROR_INVALIDDATA; +if (avctx->err_recognition & AV_EF_EXPLODE) +goto err; +continue; +} +} + +if ((ret = avctx->hwaccel->decode_slice(avctx, slices[i].rawbuf, slices[i].raw_size)) < 0) +goto err; +} +} + if ((ret = avctx->hwaccel->end_frame(avctx)) < 0) goto err; // decode second field s->gb = slices[n_slices1 + 1].gb; +s->mb_y = slices[n_slices1 + 1].mby_start; s->picture_structure = PICT_TOP_FIELD + v->tff; v->second_field = 1; v->pic_header_flag = 0; @@ -922,8 +948,35 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if ((ret = avctx->hwaccel->start_frame(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field)) < 0) goto err; -if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field)) < 0) -goto err; + +if (n_slices - n_slices1 == 2) { +// no slices, decode the field as-is +if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field)) < 0) +goto err; +} else { +if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start_second_field, slices[n_slices1 + 2].rawbuf - buf_start_second_field)) < 0) +goto err; + +for (i = n_slices1 + 2; i < n_slices; i++) { +s->gb = slices[i].gb; +s->mb_y = slices[i].mby_start; + +v->pic_header_flag = get_bits1(>gb); +if (v->pic_header_flag) { +if (ff_vc1_parse_frame_header_adv(v, >gb) < 0) { +av_log(v->s.
[FFmpeg-devel] [PATCH 1/2] avcodec/vaapi: slice_vertical_position starts from zero for the second field
Contrary to VC-1 spec, VAAPI expects the row address of the first macroblock row in the first slice to start from zero for the second field in a field interlaced picture. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- This patch set adds support for hardware decoding multi-slice field interlaced pictures. With this patch set, the SA10180 test file decodes correctly with VAAPI hardware acceleration. This was succesfully tested on Intel Haswell platform. libavcodec/vaapi_vc1.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index bdb5e24cc5..921ca6391b 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -467,6 +467,7 @@ static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, const MpegEncContext *s = >s; VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; VASliceParameterBufferVC1 slice_param; +int mb_height; int err; /* Current bit buffer is beyond any marker for VC-1, so skip it */ @@ -475,12 +476,17 @@ static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, size -= 4; } +if (v->fcm == ILACE_FIELD) +mb_height = avctx->coded_height + 31 >> 5; +else +mb_height = avctx->coded_height + 15 >> 4; + slice_param = (VASliceParameterBufferVC1) { .slice_data_size = size, .slice_data_offset = 0, .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, .macroblock_offset = get_bits_count(>gb), -.slice_vertical_position = s->mb_y, +.slice_vertical_position = s->mb_y % mb_height, }; err = ff_vaapi_decode_make_slice_buffer(avctx, pic, -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vc1: fix mquant calculation
In vc1_decode_i_blocks_adv mquant needs to be reset to its default value for each macroblock, instead of once at the beginning of the slice. DQPROFILE specifies which macroblocks can have an alternative quantizer step size. When DQPROFILE specifies edges, the selection is applicable to the edges of the picture. Slice edges are not selected by DQPROFILE. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 0caa5ebb85..f59c440943 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -177,7 +177,7 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) edges = 15;\ if ((edges&1) && !s->mb_x) \ mquant = -v->altpq;\ -if ((edges&2) && s->first_slice_line) \ +if ((edges&2) && !s->mb_y) \ mquant = -v->altpq;\ if ((edges&4) && s->mb_x == (s->mb_width - 1)) \ mquant = -v->altpq;\ @@ -2626,7 +2626,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) int cbp, val; uint8_t *coded_val; int mb_pos; -int mquant = v->pq; +int mquant; int mqdiff; GetBitContext *gb = >gb; @@ -2671,6 +2671,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) init_block_index(v); for (;s->mb_x < s->mb_width; s->mb_x++) { int16_t (*block)[64] = v->block[v->cur_blk_idx]; +mquant = v->pq; ff_update_block_index(s); s->bdsp.clear_blocks(block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_stride; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avcodec/x86/hpeldsp: fix half pel interpolation
> This patch is not correct. > > this code is not used if AV_CODEC_FLAG_BITEXACT is set, because it is > not bit exact ... > > Also the case where the off by 1 error occurs is a rare corner case, > Compared to the errors introduced by the IDCT this is not significant > > If you want to optimize the bit exact version, feel free to do so. > It may be faster to use xor -1 before and after avg for this though Thank you for the review. VC-1 spec is defined bit exact, including the inverse transform. This code is used by the VC-1 decoder and as I was under the impression that the VC-1 decoder ought to be bit exact without any additional command line options, I tried to resolve the issue. As this code is guarded by AV_CODEC_FLAG_BITEXACT, i agree that the proposed solution is not appropriate. The underlying question remains though. Should the VC-1 decoder fully conform to spec or do we allow small deviations? In addition, the VC-1 fate tests put the -bitexact option after the input file (-i). I could only get the bitexeact working if it was put before the input file. Thus, I think the current vc-1 fate-tests do not use the bit exact version. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/x86/hpeldsp: fix half pel interpolation
The assembly optimized half pel interpolation in some cases rounds the interpolated value when no rounding is requested. The result is a off by one error when one of the pixel values is zero. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- In the put_no_rnd_pixels functions, the psubusb instruction subtracts one from each unsigned byte to correct for the rouding that the PAVGB instruction performs. The psubusb instruction, however, uses saturation when the value does not fit in the operand type, i.e. an unsigned byte. In this particular case, this means that when the value of a pixel is 0, the psubusb instruction will return 0 instead of -1 as this value does not fit in an unsigned byte and is saturated to 0. The result is that the interpolated value is not corrected for the rounding that PAVGB performs and that the result will be off by one. The corrections below solved the issues for me, but I do not a lot of experience in optimizing assembly. A good check for the correctness of the solution might be advisable. Furthermore, I have not checked the other assembly, but there may be more cases where the psubusb instruction does not provide the desired results. A good check by the owner/maintainer of the assembly code might be appropriate. libavcodec/x86/hpeldsp.asm | 38 -- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/libavcodec/x86/hpeldsp.asm b/libavcodec/x86/hpeldsp.asm index ce5d7a4e28..bae2ba9880 100644 --- a/libavcodec/x86/hpeldsp.asm +++ b/libavcodec/x86/hpeldsp.asm @@ -145,10 +145,16 @@ cglobal put_no_rnd_pixels8_x2, 4,5 mova m1, [r1+1] mova m3, [r1+r2+1] add r1, r4 -psubusb m0, m6 -psubusb m2, m6 +mova m4, m0 +pxor m4, m1 +pand m4, m6 PAVGBm0, m1 +psubbm0, m4 +mova m4, m2 +pxor m4, m3 +pand m4, m6 PAVGBm2, m3 +psubbm2, m4 mova [r0], m0 mova[r0+r2], m2 mova m0, [r1] @@ -157,10 +163,16 @@ cglobal put_no_rnd_pixels8_x2, 4,5 mova m3, [r1+r2+1] add r0, r4 add r1, r4 -psubusb m0, m6 -psubusb m2, m6 +mova m4, m0 +pxor m4, m1 +pand m4, m6 PAVGBm0, m1 +psubbm0, m4 +mova m4, m2 +pxor m4, m3 +pand m4, m6 PAVGBm2, m3 +psubbm2, m4 mova [r0], m0 mova[r0+r2], m2 add r0, r4 @@ -227,18 +239,32 @@ cglobal put_no_rnd_pixels8_y2, 4,5 mova m1, [r1+r2] mova m2, [r1+r4] add r1, r4 -psubusb m1, m6 +mova m3, m0 +pxor m3, m1 +pand m3, m6 PAVGBm0, m1 +psubbm0, m3 +mova m3, m1 +pxor m3, m2 +pand m3, m6 PAVGBm1, m2 +psubbm1, m3 mova[r0+r2], m0 mova[r0+r4], m1 mova m1, [r1+r2] mova m0, [r1+r4] add r0, r4 add r1, r4 -psubusb m1, m6 +mova m3, m2 +pxor m3, m1 +pand m3, m6 PAVGBm2, m1 +psubbm2, m3 +mova m3, m1 +pxor m3, m0 +pand m3, m6 PAVGBm1, m0 +psubbm1, m3 mova[r0+r2], m2 mova[r0+r4], m1 add r0, r4 -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vc1: fix out of bounds access of overlap filter
Overlap filtering of the first row and first column must be guarded for out of bounds access of v->over_flags_plane. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_loopfilter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index bab28a649f..4c0de7c025 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -110,19 +110,19 @@ void ff_vc1_i_overlap_filter(VC1Context *v) * we run the put_pixels loop, i.e. delayed by one row and one column. */ for (i = 0; i < block_count; i++) if (v->pq >= 9 || v->condover == CONDOVER_ALL || -(v->over_flags_plane[mb_pos] && ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1]))) +(v->over_flags_plane[mb_pos] && ((i & 5) == 1 || (s->mb_x && v->over_flags_plane[mb_pos - 1] vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk, i); if (v->fcm != ILACE_FRAME) for (i = 0; i < block_count; i++) { if (s->mb_x && (v->pq >= 9 || v->condover == CONDOVER_ALL || (v->over_flags_plane[mb_pos - 1] && - ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride] + ((i & 2) || (!s->first_slice_line && v->over_flags_plane[mb_pos - 1 - s->mb_stride]) vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i); if (s->mb_x == s->mb_width - 1) if (v->pq >= 9 || v->condover == CONDOVER_ALL || (v->over_flags_plane[mb_pos] && - ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride]))) + ((i & 2) || (!s->first_slice_line && v->over_flags_plane[mb_pos - s->mb_stride] vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i); } } -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vc1: more corrections for AC inverse quantization scaling
HALFQP should only be added to the inverse quantizer when the block is coded with PQUANT. When PQUANT is equal to ALTPQUANT, the original test for the addition of HALFQP fails. A negative value for mquant indicates that the value was derived from VOPDQUANT. Fixes #4372 Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1.c | 1 + libavcodec/vc1_block.c | 129 ++--- 2 files changed, 69 insertions(+), 61 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 20cc84eb8e..949fec6bee 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -991,6 +991,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->pquantizer = 1; break; } +v->dquantfrm = 0; if (v->postprocflag) v->postproc = get_bits(gb, 2); diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index af40fbd21d..0caa5ebb85 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -160,13 +160,13 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) int edges = 0; \ if (v->dqprofile == DQPROFILE_ALL_MBS) { \ if (v->dqbilevel) {\ -mquant = (get_bits1(gb)) ? v->altpq : v->pq; \ +mquant = (get_bits1(gb)) ? -v->altpq : v->pq; \ } else { \ mqdiff = get_bits(gb, 3); \ if (mqdiff != 7) \ -mquant = v->pq + mqdiff; \ +mquant = -v->pq - mqdiff; \ else \ -mquant = get_bits(gb, 5); \ +mquant = -get_bits(gb, 5); \ } \ } \ if (v->dqprofile == DQPROFILE_SINGLE_EDGE) \ @@ -176,13 +176,13 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) else if (v->dqprofile == DQPROFILE_FOUR_EDGES) \ edges = 15;\ if ((edges&1) && !s->mb_x) \ -mquant = v->altpq; \ +mquant = -v->altpq;\ if ((edges&2) && s->first_slice_line) \ -mquant = v->altpq; \ +mquant = -v->altpq;\ if ((edges&4) && s->mb_x == (s->mb_width - 1)) \ -mquant = v->altpq; \ +mquant = -v->altpq;\ if ((edges&8) && s->mb_y == (s->mb_height - 1))\ -mquant = v->altpq; \ +mquant = -v->altpq;\ if (!mquant || mquant > 31) { \ av_log(v->s.avctx, AV_LOG_ERROR, \ "Overriding invalid mquant %d\n", mquant); \ @@ -388,7 +388,7 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, int dqscale_index; /* scale predictors if needed */ -q1 = s->current_picture.qscale_table[mb_pos]; +q1 = FFABS(s->current_picture.qscale_table[mb_pos]); dqscale_index = s->y_dc_scale_table[q1] - 1; if (dqscale_index < 0) return 0; @@ -404,12 +404,12 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, a = dc_val[ - wrap]; if (c_avail && (n != 1 && n != 3)) { -q2 = s->current_picture.qscale_table[mb_pos - 1]; +q2 = FFABS(s->current_picture.qscale_table[mb_pos - 1]); if (q2 && q2 != q1) c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x2) >> 18; } if (a_avail && (n != 2 && n != 3)) { -q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; +q2 = FFABS(s->current_picture.qscale_table[mb_pos - s->mb_stride]); if (q2 && q2 != q1) a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x2) >> 18; } @@ -419,7 +419,7 @@ static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, off--; if (n != 2) off -= s->mb_stride; -q2 = s->current_picture.qscale_table[off]; +q2 = FFABS(s->curr
[FFmpeg-devel] [PATCH 14/14] avcodec/vc1: correct forgotten v->blocks_off
correct forgotten v->blocks_off Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_pred.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c index 3a52a22bc6..de736ec775 100644 --- a/libavcodec/vc1_pred.c +++ b/libavcodec/vc1_pred.c @@ -254,7 +254,7 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0] = 0; s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1] = 0; -s->current_picture.motion_val[1][xy + wrap][0] = 0; +s->current_picture.motion_val[1][xy + wrap + v->blocks_off][0] = 0; s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1] = 0; s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0; s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 12/14] avcodec/vc1: correct mspel for field-interlace B frames
mspel indicates the use of bicubic interpolation. The check wrongly included MVMODE MV_PMODE_1MV_HPEL as using bilinear interpolation. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 2b9f8db3ee..20cc84eb8e 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -1224,7 +1224,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->mv_mode = ff_vc1_mv_pmode_table2[lowquant][mvmode]; v->qs_last = v->s.quarter_sample; v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV || v->mv_mode == MV_PMODE_MIXED_MV); -v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || v->mv_mode == MV_PMODE_1MV_HPEL); +v->s.mspel = (v->mv_mode != MV_PMODE_1MV_HPEL_BILIN); status = bitplane_decoding(v->forward_mb_plane, >fmb_is_raw, v); if (status < 0) return -1; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 10/14] avcodec/vc1: add overlap smooting and loop filter for frame/field-interlace
Add previously omitted overlap smooting and loop filtering for frame/field-interlace pictures. For progressive pictures switch to the re-implemented versions of overlap smooting and loop filtering. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 111 +++- tests/ref/fate/vc1_ilaced_twomv | 26 +- tests/ref/fate/vc1_sa10143 | 60 +++--- 3 files changed, 83 insertions(+), 114 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index f2f5c7f88b..7d6d5c781c 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -1328,16 +1328,6 @@ static int vc1_decode_p_mb(VC1Context *v) if (v->rangeredfrm) for (j = 0; j < 64; j++) v->block[v->cur_blk_idx][i][j] <<= 1; - s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i], - s->dest[dst_idx] + off, - i & 4 ? s->uvlinesize -: s->linesize); -if (v->pq >= 9 && v->overlap) { -if (v->c_avail) -v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize); -if (v->a_avail) -v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize); -} block_cbp |= 0xF << (i << 2); block_intra |= 1 << i; } else if (val) { @@ -1439,16 +1429,6 @@ static int vc1_decode_p_mb(VC1Context *v) if (v->rangeredfrm) for (j = 0; j < 64; j++) v->block[v->cur_blk_idx][i][j] <<= 1; - s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i], - s->dest[dst_idx] + off, - (i & 4) ? s->uvlinesize - : s->linesize); -if (v->pq >= 9 && v->overlap) { -if (v->c_avail) -v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize); -if (v->a_avail) -v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize); -} block_cbp |= 0xF << (i << 2); block_intra |= 1 << i; } else if (is_coded[i]) { @@ -1479,6 +1459,10 @@ static int vc1_decode_p_mb(VC1Context *v) } } end: +if (v->overlap && v->pq >= 9) +ff_vc1_p_overlap_filter(v); +vc1_put_signed_blocks_clamped(v); + v->cbp[s->mb_x] = block_cbp; v->ttblk[s->mb_x]= block_tt; v->is_intra[s->mb_x] = block_intra; @@ -1506,7 +1490,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) int skipped, fourmv = 0, twomv = 0; int block_cbp = 0, pat, block_tt = 0; int idx_mbmode = 0, mvbp; -int stride_y, fieldtx; +int fieldtx; mquant = v->pq; /* Lossy initialization */ @@ -1584,17 +1568,10 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]); -if (i < 4) { -stride_y = s->linesize << fieldtx; +if (i < 4) off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize; -} else { -stride_y = s->uvlinesize; +else off = 0; -} -s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i], - s->dest[dst_idx] + off, - stride_y); -//TODO: loop filter block_cbp |= 0xf << (i << 2); } @@ -1693,6 +1670,10 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) ff_vc1_mc_1mv(v, 0); v->fieldtx_plane[mb_pos] = 0; } +if (v->overlap && v->pq >= 9) +ff_vc1_p_o
[FFmpeg-devel] [PATCH 11/14] avcodec/vc1: remove unused overlap smooting and loop filter
remove unused overlap smooting and loop filter Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1.h| 3 - libavcodec/vc1_loopfilter.c | 297 2 files changed, 300 deletions(-) diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 0dfdef78cd..1d283f8589 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -423,11 +423,8 @@ int ff_vc1_decode_end(AVCodecContext *avctx); void ff_vc1_decode_blocks(VC1Context *v); void ff_vc1_loop_filter_iblk(VC1Context *v, int pq); -void ff_vc1_loop_filter_iblk_delayed(VC1Context *v, int pq); -void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v); void ff_vc1_i_overlap_filter(VC1Context *v); void ff_vc1_p_overlap_filter(VC1Context *v); -void ff_vc1_apply_p_loop_filter(VC1Context *v); void ff_vc1_i_loop_filter(VC1Context *v); void ff_vc1_p_loop_filter(VC1Context *v); void ff_vc1_p_intfr_loop_filter(VC1Context *v); diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 7ef0fd1ea2..bab28a649f 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -61,153 +61,6 @@ void ff_vc1_loop_filter_iblk(VC1Context *v, int pq) } } -void ff_vc1_loop_filter_iblk_delayed(VC1Context *v, int pq) -{ -MpegEncContext *s = >s; -int j; - -/* The loopfilter runs 1 row and 1 column behind the overlap filter, which - * means it runs two rows/cols behind the decoding loop. */ -if (!s->first_slice_line) { -if (s->mb_x) { -if (s->mb_y >= s->start_mb_y + 2) { -v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq); - -if (s->mb_x >= 2) -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 16, s->linesize, pq); -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 8, s->linesize, pq); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) -for (j = 0; j < 2; j++) { -v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq); -if (s->mb_x >= 2) { -v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize - 8, s->uvlinesize, pq); -} -} -} -v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize - 16, s->linesize, pq); -} - -if (s->mb_x == s->mb_width - 1) { -if (s->mb_y >= s->start_mb_y + 2) { -v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq); - -if (s->mb_x) -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize, s->linesize, pq); -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize + 8, s->linesize, pq); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) -for (j = 0; j < 2; j++) { -v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq); -if (s->mb_x >= 2) { -v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize, s->uvlinesize, pq); -} -} -} -v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize, s->linesize, pq); -} - -if (s->mb_y == s->end_mb_y) { -if (s->mb_x) { -if (s->mb_x >= 2) -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq); -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 8, s->linesize, pq); -if (s->mb_x >= 2 && (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))) { -for (j = 0; j < 2; j++) { -v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq); -} -} -} - -if (s->mb_x == s->mb_width - 1) { -if (s->mb_x) -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq); -v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq); -if (s->mb_x && (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))) { -for (j = 0; j < 2; j++) { -v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq); -
[FFmpeg-devel] [PATCH 13/14] avcodec/vc1: correct AC inverse quantization scaling
HALFQP should only be added to the inverse quantizer when the block is coded with PQUANT. See 8.1.3.8 in VC-1 spec. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 7d6d5c781c..af40fbd21d 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -944,7 +944,7 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n, ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val2 = ac_val; -scale = mquant * 2 + v->halfpq; +scale = mquant * 2 + ((mquant == v->pq) ? v->halfpq : 0); if (dc_pred_dir) //left ac_val -= 16; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 09/14] avcodec/vc1: re-implement vc1_put_signed_blocks_clamped
The existing implementation only used vc1_put_signed_blocks_clamped for I and BI frames. This rewritten version is also applicable to P frame both progressive and frame/field-interlace. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 116 - 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index f641a011f2..f2f5c7f88b 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -69,70 +69,70 @@ static inline void init_block_index(VC1Context *v) static void vc1_put_signed_blocks_clamped(VC1Context *v) { MpegEncContext *s = >s; -int topleft_mb_pos, top_mb_pos; -int stride_y, fieldtx = 0; -int v_dist; - -/* The put pixels loop is always one MB row behind the decoding loop, - * because we can only put pixels when overlap filtering is done, and - * for filtering of the bottom edge of a MB, we need the next MB row - * present as well. - * Within the row, the put pixels loop is also one MB col behind the - * decoding loop. The reason for this is again, because for filtering - * of the right MB edge, we need the next MB present. */ -if (!s->first_slice_line) { +uint8_t *dest; +int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6; +int fieldtx = 0; +int i; + +/* The put pixels loop is one MB row and one MB column behind the decoding + * loop because we can only put pixels when overlap filtering is done. For + * interlaced frame pictures, however, the put pixels loop is only one + * column behind the decoding loop as interlaced frame pictures only need + * horizontal overlap filtering. */ +if (!s->first_slice_line && v->fcm != ILACE_FRAME) { +if (s->mb_x) { +for (i = 0; i < block_count; i++) { +if (i > 3 ? v->mb_type[0][s->block_index[i] - s->block_wrap[i] - 1] : +v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i] - 2]) { +dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + ((i & 1) - 2) * 8; + s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, + i > 3 ? s->uvlinesize : s->linesize); +} +} +} +if (s->mb_x == s->mb_width - 1) { +for (i = 0; i < block_count; i++) { +if (i > 3 ? v->mb_type[0][s->block_index[i] - s->block_wrap[i]] : +v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i]]) { +dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + (i & 1) * 8; + s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][i], + i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, + i > 3 ? s->uvlinesize : s->linesize); +} +} +} +} +if (s->mb_y == s->end_mb_y - 1 || v->fcm == ILACE_FRAME) { if (s->mb_x) { -topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1; if (v->fcm == ILACE_FRAME) -fieldtx = v->fieldtx_plane[topleft_mb_pos]; -stride_y = s->linesize << fieldtx; -v_dist = (16 - fieldtx) >> (fieldtx == 0); -s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0], - s->dest[0] - 16 * s->linesize - 16, - stride_y); -s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1], - s->dest[0] - 16 * s->linesize - 8, - stride_y); -s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2], - s->dest[0] - v_dist * s->linesize - 16, - stride_y); -s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][3], - s->dest[0] - v_dist * s->linesize - 8, - stride_y); -if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { -s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][4], -
[FFmpeg-devel] [PATCH 08/14] avcodec/vc1: implement interlaced out-of-bounds reference pixel replication
The existing implementation did out-of-bounds reference pixel replication for progressive reference frames. In interlaced reference frames both the even and odd line on the horizontal edges need to be replicated. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_mc.c | 376 +--- tests/ref/fate/vc1_ilaced_twomv | 18 +- 2 files changed, 318 insertions(+), 76 deletions(-) diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c index 5eacaaa8ee..04b359204c 100644 --- a/libavcodec/vc1_mc.c +++ b/libavcodec/vc1_mc.c @@ -254,9 +254,14 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); } else { src_x = av_clip( src_x, -17, s->avctx->coded_width); -src_y = av_clip( src_y, -18, s->avctx->coded_height + 1); uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); -uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); +if (v->fcm == ILACE_FRAME) { +src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); +uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); +} else { +src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); +uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); +} } srcY += src_y * s->linesize + src_x; @@ -284,22 +289,113 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) const int k = 17 + s->mspel * 2; srcY -= s->mspel * (1 + s->linesize); -s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, - s->linesize, s->linesize, - k, k, - src_x - s->mspel, src_y - s->mspel, - s->h_edge_pos, v_edge_pos); +if (v->fcm == ILACE_FRAME) { +if (src_y - s->mspel & 1) { +s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcY, + 2 * s->linesize, + 2 * s->linesize, + k, + k + 1 >> 1, + src_x - s->mspel, + src_y - s->mspel >> 1, + s->h_edge_pos, + v_edge_pos + 1 >> 1); +s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, + srcY + s->linesize, + 2 * s->linesize, + 2 * s->linesize, + k, + k >> 1, + src_x - s->mspel, + src_y - s->mspel + 1 >> 1, + s->h_edge_pos, + v_edge_pos >> 1); +} else { +s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, + srcY, + 2 * s->linesize, + 2 * s->linesize, + k, + k + 1 >> 1, + src_x - s->mspel, + src_y - s->mspel >> 1, + s->h_edge_pos, + v_edge_pos >> 1); +s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, + srcY + s->linesize, + 2 * s->linesize, + 2 * s->linesize, + k, + k >> 1, + src_x - s->mspel, + src_y - s->mspel + 1 >> 1, + s->h_edge_pos, + v_edge_pos + 1 >> 1); +} +} else +s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, + s->linesize, s->linesize, + k, k, + src_x - s->mspel, src_y
[FFmpeg-devel] [PATCH 07/14] avcodec/vc1: correct ff_vc1_dqscale
According to VC-1 spec table 74, the last value in ff_vc1_dqscale should be 0x1041 instead of 0x1000. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c index 0df7d4d666..19f1cad45f 100644 --- a/libavcodec/vc1data.c +++ b/libavcodec/vc1data.c @@ -1090,7 +1090,7 @@ const int32_t ff_vc1_dqscale[63] = { 0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A, 0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555, 0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249, - 0x11F7, 0x11A8, 0x115B, 0x, 0x10C9, 0x1084, 0x1000 + 0x11F7, 0x11A8, 0x115B, 0x, 0x10C9, 0x1084, 0x1041 }; /* P Interlaced field picture MV predictor scaling values (Table 114) */ -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 06/14] avcodec/vc1: correct ff_vc1_mbmode_intfrp
According to VC-1 spec 10.7.3.4, FIELDTX shall be set to the same type as the motion vector for zero-coded blocks. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1data.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c index fc9ba6da13..0df7d4d666 100644 --- a/libavcodec/vc1data.c +++ b/libavcodec/vc1data.c @@ -61,7 +61,7 @@ const uint8_t ff_vc1_mbmode_intfrp[2][15][4] = { { MV_PMODE_INTFR_1MV , 1, 0, 1 }, { MV_PMODE_INTFR_2MV_FIELD, 0, 0, 1 }, { MV_PMODE_INTFR_2MV_FIELD, 1, 0, 1 }, -{ MV_PMODE_INTFR_2MV_FIELD, 0, 0, 0 }, +{ MV_PMODE_INTFR_2MV_FIELD, 1, 0, 0 }, { MV_PMODE_INTFR_INTRA, 0, 0, 0 } }, { @@ -73,13 +73,13 @@ const uint8_t ff_vc1_mbmode_intfrp[2][15][4] = { { MV_PMODE_INTFR_1MV , 1, 0, 1 }, { MV_PMODE_INTFR_2MV_FIELD, 0, 0, 1 }, { MV_PMODE_INTFR_2MV_FIELD, 1, 0, 1 }, -{ MV_PMODE_INTFR_2MV_FIELD, 0, 0, 0 }, +{ MV_PMODE_INTFR_2MV_FIELD, 1, 0, 0 }, { MV_PMODE_INTFR_4MV , 0, 0, 1 }, { MV_PMODE_INTFR_4MV , 1, 0, 1 }, { MV_PMODE_INTFR_4MV , 0, 0, 0 }, { MV_PMODE_INTFR_4MV_FIELD, 0, 0, 1 }, { MV_PMODE_INTFR_4MV_FIELD, 1, 0, 1 }, -{ MV_PMODE_INTFR_4MV_FIELD, 0, 0, 0 }, +{ MV_PMODE_INTFR_4MV_FIELD, 1, 0, 0 }, { MV_PMODE_INTFR_INTRA, 0, 0, 0 } } }; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 04/14] avcodec/vc1: store additional bitstream elements during MB decoding
The new loop filter needs additional MB properties to make its filtering decisions. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 58 +- libavcodec/vc1dec.c| 16 +++--- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 1c3577796e..f641a011f2 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -1595,6 +1595,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) s->dest[dst_idx] + off, stride_y); //TODO: loop filter +block_cbp |= 0xf << (i << 2); } } else { // inter MB @@ -1690,9 +1691,11 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) v->blk_mv_type[s->block_index[3]] = 0; ff_vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0); ff_vc1_mc_1mv(v, 0); +v->fieldtx_plane[mb_pos] = 0; } -if (s->mb_x == s->mb_width - 1) -memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride); +v->cbp[s->mb_x] = block_cbp; +v->ttblk[s->mb_x]= block_tt; + return 0; } @@ -1756,6 +1759,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) (i & 4) ? s->uvlinesize : s->linesize); // TODO: loop filter +block_cbp |= 0xf << (i << 2); } } else { s->mb_intra = v->is_intra[s->mb_x] = 0; @@ -1810,8 +1814,9 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) } } } -if (s->mb_x == s->mb_width - 1) -memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride); +v->cbp[s->mb_x] = block_cbp; +v->ttblk[s->mb_x]= block_tt; + return 0; } @@ -1988,6 +1993,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) int fwd; int dmv_x[2], dmv_y[2], pred_flag[2]; int bmvtype = BMV_TYPE_BACKWARD; +int block_cbp = 0, pat, block_tt = 0; int idx_mbmode; mquant = v->pq; /* Lossy initialization */ @@ -2118,16 +2124,19 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; if (val) { -vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, - first_block, s->dest[dst_idx] + off, - (i & 4) ? s->uvlinesize : s->linesize, - CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), NULL); +pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, + first_block, s->dest[dst_idx] + off, + (i & 4) ? s->uvlinesize : s->linesize, + CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), _tt); +block_cbp |= pat << (i << 2); if (!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; } } } +v->cbp[s->mb_x] = block_cbp; +v->ttblk[s->mb_x]= block_tt; } /** Decode one B-frame MB (in interlaced frame B picture) @@ -2468,12 +2477,12 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) if (direct || bmvtype == BMV_TYPE_INTERPOLATED) { ff_vc1_interp_mc(v); } +v->fieldtx_plane[mb_pos] = 0; } } -if (s->mb_x == s->mb_width - 1) -memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride); v->cbp[s->mb_x] = block_cbp; v->ttblk[s->mb_x]= block_tt; + return 0; } @@ -2703,6 +2712,8 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->c_dc_scale = s->c_dc_scale_table[mquant]; for (k = 0; k < 6; k++) { +v->mb_type[0][s->block_index[k]] = 1; + val = ((cbp >> (5 - k)) & 1); if (k < 4) { @@ -2799,7 +2810,7 @@ static void vc1_decode_p_blocks(VC1Context *v) apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) && v->fcm == PROGRESSIVE; s->first_slice_line = 1; -memset(v->cbp_base, 0, si
[FFmpeg-devel] [PATCH 05/14] avcodec/vc1: store color-difference reference field type
The loop filter for P interlace field pictures needs the reference field type. For luma, the reference field type was already available. Store the reference field type for color-difference as well. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_mc.c | 8 1 file changed, 8 insertions(+) diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c index 75c74cad8d..5eacaaa8ee 100644 --- a/libavcodec/vc1_mc.c +++ b/libavcodec/vc1_mc.c @@ -344,6 +344,10 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir) v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } +if (v->field_mode) { +v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir]; +v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir]; +} } /** Do motion compensation for 4-MV macroblock - luminance block @@ -636,6 +640,10 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir) v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); } +if (v->field_mode) { +v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != chroma_ref_type; +v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != chroma_ref_type; +} } /** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V) -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 03/14] avcodec/vc1: re-implement and expand VC-1 loop filtering
The existing implementation did loop filtering for progressive frames only. This rewritten version implements loop filtering for all applicable frame types for both progessive and frame/field-interlace. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1.h|4 + libavcodec/vc1_loopfilter.c | 1042 +++ 2 files changed, 1046 insertions(+) diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 85504c2f9f..0dfdef78cd 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -428,6 +428,10 @@ void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v); void ff_vc1_i_overlap_filter(VC1Context *v); void ff_vc1_p_overlap_filter(VC1Context *v); void ff_vc1_apply_p_loop_filter(VC1Context *v); +void ff_vc1_i_loop_filter(VC1Context *v); +void ff_vc1_p_loop_filter(VC1Context *v); +void ff_vc1_p_intfr_loop_filter(VC1Context *v); +void ff_vc1_b_intfi_loop_filter(VC1Context *v); void ff_vc1_mc_1mv(VC1Context *v, int dir); void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg); diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 3122b1a258..7ef0fd1ea2 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -451,3 +451,1045 @@ void ff_vc1_apply_p_loop_filter(VC1Context *v) } } } + +#define LEFT_EDGE (1 << 0) +#define RIGHT_EDGE (1 << 1) +#define TOP_EDGE(1 << 2) +#define BOTTOM_EDGE (1 << 3) + +static av_always_inline void vc1_i_h_loop_filter(VC1Context *v, uint8_t *dest, + uint32_t flags, int block_num) +{ +MpegEncContext *s = >s; +int pq = v->pq; +uint8_t *dst; + +if (block_num & 2) +return; + +if (!(flags & LEFT_EDGE) || (block_num & 5) == 1) { +if (block_num > 3) +dst = dest; +else +dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8; + +if (v->fcm == ILACE_FRAME) +if (block_num > 3) { +v->vc1dsp.vc1_h_loop_filter4(dst, 2 * s->uvlinesize, pq); +v->vc1dsp.vc1_h_loop_filter4(dst + s->uvlinesize, 2 * s->uvlinesize, pq); +} else { +v->vc1dsp.vc1_h_loop_filter8(dst, 2 * s->linesize, pq); +v->vc1dsp.vc1_h_loop_filter8(dst + s->linesize, 2 * s->linesize, pq); +} +else +if (block_num > 3) +v->vc1dsp.vc1_h_loop_filter8(dst, s->uvlinesize, pq); +else +v->vc1dsp.vc1_h_loop_filter16(dst, s->linesize, pq); +} +} + +static av_always_inline void vc1_i_v_loop_filter(VC1Context *v, uint8_t *dest, + uint32_t flags, uint8_t fieldtx, + int block_num) +{ +MpegEncContext *s = >s; +int pq = v->pq; +uint8_t *dst; + +if ((block_num & 5) == 1) +return; + +if (!(flags & TOP_EDGE) || block_num & 2) { +if (block_num > 3) +dst = dest; +else +dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8; + +if (v->fcm == ILACE_FRAME) { +if (block_num > 3) { +v->vc1dsp.vc1_v_loop_filter8(dst, 2 * s->uvlinesize, pq); +v->vc1dsp.vc1_v_loop_filter8(dst + s->uvlinesize, 2 * s->uvlinesize, pq); +} else if (block_num < 2 || !fieldtx) { +v->vc1dsp.vc1_v_loop_filter16(dst, 2 * s->linesize, pq); +v->vc1dsp.vc1_v_loop_filter16(dst + s->linesize, 2 * s->linesize, pq); +} +} else +if (block_num > 3) +v->vc1dsp.vc1_v_loop_filter8(dst, s->uvlinesize, pq); +else +v->vc1dsp.vc1_v_loop_filter16(dst, s->linesize, pq); +} +} + +void ff_vc1_i_loop_filter(VC1Context *v) +{ +MpegEncContext *s = >s; +int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6; +int mb_pos = s->mb_x + s->mb_y * s->mb_stride; +uint8_t *dest, fieldtx; +uint32_t flags = 0; +int i; + +/* Within a MB, the vertical loop filter always runs before the horizontal. + * To accomplish that, we run the V loop filter on top and internal + * horizontal borders of the last overlap filtered MB. Then, we wait for + * the loop filter iteration on the next row to do V loop filter on the + * bottom edge of this MB, before moving over and running the H loop + * filter on the left and internal vertical borders. Therefore, the loop + * filter trails by one row and one column relative to the overlap filter + * and two rows and two colums relative to the decoding loop. */ +if (!s->first_slice_l
Re: [FFmpeg-devel] [PATCH] avcodec/vaapi: do not parse MVMODE for VC-1 interlaced frame pictures
On 29-3-2018 13:43, Jerome Borsboom wrote: > Interlaced frame pictures do not contain the MVMODE or MVMODE2 bitstream > element. Trying to parse this element and passing a nonzero value to the > hardware decoder results in small inaccuracies in the decoded picture. > > Signed-off-by: Jerome Borsboom > --- > With this patch the Intel hardware decoded fate test for ilaced_twomv.vc1 > perfectly matches the output from the Microsoft software decoder. > > libavcodec/vaapi_vc1.c | 8 +--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c > index 74ba783141..bdb5e24cc5 100644 > --- a/libavcodec/vaapi_vc1.c > +++ b/libavcodec/vaapi_vc1.c > @@ -138,8 +138,9 @@ static int vc1_get_FPTYPE(const VC1Context *v) > /** Reconstruct bitstream MVMODE (7.1.1.32) */ > static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) > { > -if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || > -(v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)) > +if ((v->fcm == PROGRESSIVE || v->fcm == ILACE_FIELD) && > +((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || > + (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type))) > return get_VAMvModeVC1(v->mv_mode); > return 0; > } > @@ -147,7 +148,8 @@ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context > *v) > /** Reconstruct bitstream MVMODE2 (7.1.1.33) */ > static inline VAMvModeVC1 vc1_get_MVMODE2(const VC1Context *v) > { > -if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && > +if ((v->fcm == PROGRESSIVE || v->fcm == ILACE_FIELD) && > +(v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && > v->mv_mode == MV_PMODE_INTENSITY_COMP) > return get_VAMvModeVC1(v->mv_mode2); > return 0; > -- > 2.13.6 Could someone please have a look at this patch? ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 02/14] avcodec/vc1: change to using v->block instead of s->block for P frames
The new overlap smooting filter smoothes image pixels stored in v->block. Switch to v->block instead of s->block for storing decoded image pixels for P frames. Additionally, we must take incrementing *_blk_idx out of the vc1_put_signed_blocks_clamped function. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1_block.c | 55 -- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index f9f26f7e42..1c3577796e 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -136,6 +136,7 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) } } } +} #define inc_blk_idx(idx) do { \ idx++; \ @@ -143,12 +144,6 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) idx = 0; \ } while (0) -inc_blk_idx(v->topleft_blk_idx); -inc_blk_idx(v->top_blk_idx); -inc_blk_idx(v->left_blk_idx); -inc_blk_idx(v->cur_blk_idx); -} - /***/ /** * @name VC-1 Block-level functions @@ -1325,15 +1320,15 @@ static int vc1_decode_p_mb(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; -vc1_decode_intra_block(v, s->block[i], i, val, mquant, +vc1_decode_intra_block(v, v->block[v->cur_blk_idx][i], i, val, mquant, (i & 4) ? v->codingset2 : v->codingset); if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; -v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); +v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]); if (v->rangeredfrm) for (j = 0; j < 64; j++) -s->block[i][j] <<= 1; -s->idsp.put_signed_pixels_clamped(s->block[i], +v->block[v->cur_blk_idx][i][j] <<= 1; + s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize); @@ -1346,7 +1341,7 @@ static int vc1_decode_p_mb(VC1Context *v) block_cbp |= 0xF << (i << 2); block_intra |= 1 << i; } else if (val) { -pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, +pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize, CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), _tt); block_cbp |= pat << (i << 2); @@ -1436,15 +1431,15 @@ static int vc1_decode_p_mb(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; -vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant, +vc1_decode_intra_block(v, v->block[v->cur_blk_idx][i], i, is_coded[i], mquant, (i & 4) ? v->codingset2 : v->codingset); if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; -v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); +v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]); if (v->rangeredfrm) for (j = 0; j < 64; j++) -s->block[i][j] <<= 1; -s->idsp.put_signed_pixels_clamped(s->block[i], +v->block[v->cur_blk_idx][i][j] <<= 1; + s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); @@ -1457,7 +1452,7 @@ static int vc1_decode_p_mb(VC1Context *v) block_c
[FFmpeg-devel] [PATCH 01/14] avcodec/vc1: re-implement and expand VC-1 overlap smooting
The existing implementation did overlap smoothing for progressive frames only. This rewritten version implements overlap smoothing for all applicable frame types for both progessive and frame/field-interlace. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- This patch-set improves the VC-1 software decoder to the point where the fate checksums are equal to checksums from the Intel hardware decoded image on Haswell. libavcodec/vc1.h| 2 + libavcodec/vc1_loopfilter.c | 94 + 2 files changed, 96 insertions(+) diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 8fc0729cb8..85504c2f9f 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -425,6 +425,8 @@ void ff_vc1_decode_blocks(VC1Context *v); void ff_vc1_loop_filter_iblk(VC1Context *v, int pq); void ff_vc1_loop_filter_iblk_delayed(VC1Context *v, int pq); void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v); +void ff_vc1_i_overlap_filter(VC1Context *v); +void ff_vc1_p_overlap_filter(VC1Context *v); void ff_vc1_apply_p_loop_filter(VC1Context *v); void ff_vc1_mc_1mv(VC1Context *v, int dir); diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 025776bac9..3122b1a258 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -208,6 +208,100 @@ void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v) } } +static av_always_inline void vc1_h_overlap_filter(VC1Context *v, int16_t (*left_block)[64], + int16_t (*right_block)[64], int block_num) +{ +if (left_block != right_block || (block_num & 5) == 1) { +if (block_num > 3) +v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num]); +else if (block_num & 1) +v->vc1dsp.vc1_h_s_overlap(right_block[block_num - 1], right_block[block_num]); +else +v->vc1dsp.vc1_h_s_overlap(left_block[block_num + 1], right_block[block_num]); +} +} + +static av_always_inline void vc1_v_overlap_filter(VC1Context *v, int16_t (*top_block)[64], + int16_t (*bottom_block)[64], int block_num) +{ +if (top_block != bottom_block || block_num & 2) { +if (block_num > 3) +v->vc1dsp.vc1_v_s_overlap(top_block[block_num], bottom_block[block_num]); +else if (block_num & 2) +v->vc1dsp.vc1_v_s_overlap(bottom_block[block_num - 2], bottom_block[block_num]); +else +v->vc1dsp.vc1_v_s_overlap(top_block[block_num + 2], bottom_block[block_num]); +} +} + +void ff_vc1_i_overlap_filter(VC1Context *v) +{ +MpegEncContext *s = >s; +int16_t (*topleft_blk)[64], (*top_blk)[64], (*left_blk)[64], (*cur_blk)[64]; +int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6; +int mb_pos = s->mb_x + s->mb_y * s->mb_stride; +int i; + +topleft_blk = v->block[v->topleft_blk_idx]; +top_blk = v->block[v->top_blk_idx]; +left_blk = v->block[v->left_blk_idx]; +cur_blk = v->block[v->cur_blk_idx]; + +/* Within a MB, the horizontal overlap always runs before the vertical. + * To accomplish that, we run the H on the left and internal vertical + * borders of the currently decoded MB. Then, we wait for the next overlap + * iteration to do H overlap on the right edge of this MB, before moving + * over and running the V overlap on the top and internal horizontal + * borders. Therefore, the H overlap trails by one MB col and the + * V overlap trails by one MB row. This is reflected in the time at which + * we run the put_pixels loop, i.e. delayed by one row and one column. */ +for (i = 0; i < block_count; i++) +if (v->pq >= 9 || v->condover == CONDOVER_ALL || +(v->over_flags_plane[mb_pos] && ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1]))) +vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk, i); + +if (v->fcm != ILACE_FRAME) +for (i = 0; i < block_count; i++) { +if (s->mb_x && (v->pq >= 9 || v->condover == CONDOVER_ALL || +(v->over_flags_plane[mb_pos - 1] && + ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride] +vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i); +if (s->mb_x == s->mb_width - 1) +if (v->pq >= 9 || v->condover == CONDOVER_ALL || +(v->over_flags_plane[mb_pos] && + ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride]))) +vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i); +} +} + +void ff_vc1_p_over
Re: [FFmpeg-devel] [PATCH] avcodec/vc1_pred: properly clip interlaced motion vectors
> Fixes #2557. > > Signed-off-by: Paul B Mahol > --- > libavcodec/vc1_pred.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c > index 54712f6b7a..9f42a930fe 100644 > --- a/libavcodec/vc1_pred.c > +++ b/libavcodec/vc1_pred.c > @@ -98,9 +98,9 @@ static av_always_inline int scaleforsame_y(VC1Context *v, > int i, int n /* MV */, > } > > if (v->cur_field_type && !v->ref_field_type[dir]) > -return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2); > +return av_clip(scaledvalue, -v->range_y / 2 - 1, v->range_y / 2); > else > -return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1); > +return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 + 1); > } > > static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */) > -- > 2.11.0 scaleforsame_y references ref_field_type. Therefore, it needs to be set before scaleforsame is called. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- I am not sure your patch is correct. The existing implementation agrees with VC-1 spec. See Figure 119 in 10.3.5.4.3.4.2 in particular. Please have a look if the patch below solves the issue. ref_field_type is referenced in scaleforsame_y and needs to be set earlier in ff_vc1_pred_mv to have the desired effect. libavcodec/vc1_pred.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c index 54712f6b7a..3a52a22bc6 100644 --- a/libavcodec/vc1_pred.c +++ b/libavcodec/vc1_pred.c @@ -341,6 +341,8 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, } else opposite = 0; if (opposite) { +v->mv_f[dir][xy + v->blocks_off] = 1; +v->ref_field_type[dir] = !v->cur_field_type; if (a_valid && !a_f) { field_predA[0] = scaleforopp(v, field_predA[0], 0, dir); field_predA[1] = scaleforopp(v, field_predA[1], 1, dir); @@ -353,9 +355,9 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, field_predC[0] = scaleforopp(v, field_predC[0], 0, dir); field_predC[1] = scaleforopp(v, field_predC[1], 1, dir); } -v->mv_f[dir][xy + v->blocks_off] = 1; -v->ref_field_type[dir] = !v->cur_field_type; } else { +v->mv_f[dir][xy + v->blocks_off] = 0; +v->ref_field_type[dir] = v->cur_field_type; if (a_valid && a_f) { field_predA[0] = scaleforsame(v, n, field_predA[0], 0, dir); field_predA[1] = scaleforsame(v, n, field_predA[1], 1, dir); @@ -368,8 +370,6 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, field_predC[0] = scaleforsame(v, n, field_predC[0], 0, dir); field_predC[1] = scaleforsame(v, n, field_predC[1], 1, dir); } -v->mv_f[dir][xy + v->blocks_off] = 0; -v->ref_field_type[dir] = v->cur_field_type; } if (a_valid) { -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/vaapi: do not parse MVMODE for VC-1 interlaced frame pictures
Interlaced frame pictures do not contain the MVMODE or MVMODE2 bitstream element. Trying to parse this element and passing a nonzero value to the hardware decoder results in small inaccuracies in the decoded picture. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- With this patch the Intel hardware decoded fate test for ilaced_twomv.vc1 perfectly matches the output from the Microsoft software decoder. libavcodec/vaapi_vc1.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 74ba783141..bdb5e24cc5 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -138,8 +138,9 @@ static int vc1_get_FPTYPE(const VC1Context *v) /** Reconstruct bitstream MVMODE (7.1.1.32) */ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) { -if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || -(v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)) +if ((v->fcm == PROGRESSIVE || v->fcm == ILACE_FIELD) && +((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || + (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type))) return get_VAMvModeVC1(v->mv_mode); return 0; } @@ -147,7 +148,8 @@ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) /** Reconstruct bitstream MVMODE2 (7.1.1.33) */ static inline VAMvModeVC1 vc1_get_MVMODE2(const VC1Context *v) { -if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && +if ((v->fcm == PROGRESSIVE || v->fcm == ILACE_FIELD) && +(v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && v->mv_mode == MV_PMODE_INTENSITY_COMP) return get_VAMvModeVC1(v->mv_mode2); return 0; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/3 v1.2] avcodec/vaapi: add fields for VAAPI VC-1 interlaced decoding
v1.1->v1.2: Changed ifdefs around vc1_get_INTCOMPFIELD, vc1_get_LUMSCALE2, and vc1_get_LUMSHIFT2 to av_unused. avcodec/vaapi: add fields for VAAPI VC-1 interlaced decoding Pass necessary bitstream elements to the VAAPI VC-1 decoder in order to start doing interlaced decoding in hardware. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vaapi_vc1.c | 163 - 1 file changed, 134 insertions(+), 29 deletions(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 525376790e..97b23917f6 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -44,7 +44,8 @@ static inline int vc1_has_MVTYPEMB_bitplane(const VC1Context *v) { if (v->mv_type_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_P && +return v->fcm == PROGRESSIVE && + (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && (v->mv_mode == MV_PMODE_MIXED_MV || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV)); @@ -55,8 +56,9 @@ static inline int vc1_has_SKIPMB_bitplane(const VC1Context *v) { if (v->skip_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_P || - (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); +return (v->fcm == PROGRESSIVE || v->fcm == ILACE_FRAME) && + ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || +(v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)); } /** Check whether the DIRECTMB bitplane is present */ @@ -64,7 +66,8 @@ static inline int vc1_has_DIRECTMB_bitplane(const VC1Context *v) { if (v->dmb_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type; +return (v->fcm == PROGRESSIVE || v->fcm == ILACE_FRAME) && + (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); } /** Check whether the ACPRED bitplane is present */ @@ -89,6 +92,25 @@ static inline int vc1_has_OVERFLAGS_bitplane(const VC1Context *v) v->condover == CONDOVER_SELECT; } +/** Check whether the FIELDTX bitplane is present */ +static inline int vc1_has_FIELDTX_bitplane(const VC1Context *v) +{ +if (v->fieldtx_is_raw) +return 0; +return v->fcm == ILACE_FRAME && + (v->s.pict_type == AV_PICTURE_TYPE_I || +(v->s.pict_type == AV_PICTURE_TYPE_B && v->bi_type)); +} + +/** Check whether the FORWARDMB bitplane is present */ +static inline int vc1_has_FORWARDMB_bitplane(const VC1Context *v) +{ +if (v->fmb_is_raw) +return 0; +return v->fcm == ILACE_FIELD && + (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); +} + /** Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */ static int vc1_get_PTYPE(const VC1Context *v) { @@ -101,10 +123,22 @@ static int vc1_get_PTYPE(const VC1Context *v) return 0; } +/** Reconstruct bitstream FPTYPE (9.1.1.42, index into Table-105) */ +static int vc1_get_FPTYPE(const VC1Context *v) +{ +const MpegEncContext *s = >s; +switch (s->pict_type) { +case AV_PICTURE_TYPE_I: return 0; +case AV_PICTURE_TYPE_P: return 3; +case AV_PICTURE_TYPE_B: return v->bi_type ? 7 : 4; +} +return 0; +} + /** Reconstruct bitstream MVMODE (7.1.1.32) */ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) { -if (v->s.pict_type == AV_PICTURE_TYPE_P || +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)) return get_VAMvModeVC1(v->mv_mode); return 0; @@ -113,11 +147,77 @@ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) /** Reconstruct bitstream MVMODE2 (7.1.1.33) */ static inline VAMvModeVC1 vc1_get_MVMODE2(const VC1Context *v) { -if (v->s.pict_type == AV_PICTURE_TYPE_P && v->mv_mode == MV_PMODE_INTENSITY_COMP) +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && +v->mv_mode == MV_PMODE_INTENSITY_COMP) return get_VAMvModeVC1(v->mv_mode2); return 0; } +av_unused static inline int vc1_get_INTCOMPFIELD(const VC1Context *v) +{ +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && +v->fcm == ILACE_FIELD && +v->mv_mode == MV_PMODE_INTENSITY_COMP) +switch (v->intcompfield) { +case 1: return 1; +case 2: return 2; +case 3: return 0; +} +return 0; +} + +static inline int vc1_get_LUMSCALE(const VC1Context *v) +{ +if (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_s
Re: [FFmpeg-devel] [PATCH 2/3 v1.1] avcodec/vaapi: add fields for VAAPI VC-1 interlaced decoding
On 25/02/18 19:12, Jerome Borsboom wrote: avcodec/vaapi: add fields for VAAPI VC-1 interlaced decoding Pass necessary bitstream elements to the VAAPI VC-1 decoder in order to start doing interlaced decoding in hardware. Signed-off-by: Jerome Borsboom --- libavcodec/vaapi_vc1.c | 167 - 1 file changed, 138 insertions(+), 29 deletions(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 525376790e..a137979dd4 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -44,7 +44,8 @@ static inline int vc1_has_MVTYPEMB_bitplane(const VC1Context *v) +#if VA_CHECK_VERSION(1, 1, 0) IMO it would be preferable not to guard this function with the libva version check - it doesn't depend on anything about libva (it's only the use of it that does), so it would be better if it's always built and the compiler can eliminate it later. (Mark them with av_unused to avoid the warning.) OK. Will change and resubmit. +static inline int vc1_get_INTCOMPFIELD(const VC1Context *v) +{ +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && +v->fcm == ILACE_FIELD && +v->mv_mode == MV_PMODE_INTENSITY_COMP) +switch (v->intcompfield) { +case 1: return 1; +case 2: return 2; +case 3: return 0; +} +return 0; +} +#endif + > Is this expected to pass the two fate tests for VC-1 interlaced, fate-vc1_sa10143 and fate-vc1_ilaced_twomv? (It doesn't on my system, all output frames are different.) If not, could you explain why not? Thanks, - Mark I have a feeling that the software decoder in FFmpeg is not fully compliant with the VC-1 spec. The loopfilter, as currently implemented, may be wrong for interlaced content. I am still investigating this issue. As far as I can see, there are no visual differences between the output of the software decoded and the hardware decoded images. Regards, Jerome ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/3 v1.1] avcodec/vaapi: mask unused bits in bitplane_present.value
avcodec/vaapi: mask unused bits in bitplane_present.value Due to the union construct, unused bits in bitplane_present.value might be uninitialized even when the used bits are all set to a value. Masking the unused bits prevents spurious true values when all used bits are unset, e.g. skipped pictures. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vaapi_vc1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index a137979dd4..e93b7285e3 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -387,7 +387,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t if (err) goto fail; -if (pic_param.bitplane_present.value) { +if (pic_param.bitplane_present.value & 0x7f) { uint8_t *bitplane; const uint8_t *ff_bp[3]; int x, y, n; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/3 v1.1] avcodec/vaapi: add fields for VAAPI VC-1 interlaced decoding
avcodec/vaapi: add fields for VAAPI VC-1 interlaced decoding Pass necessary bitstream elements to the VAAPI VC-1 decoder in order to start doing interlaced decoding in hardware. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vaapi_vc1.c | 167 - 1 file changed, 138 insertions(+), 29 deletions(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 525376790e..a137979dd4 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -44,7 +44,8 @@ static inline int vc1_has_MVTYPEMB_bitplane(const VC1Context *v) { if (v->mv_type_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_P && +return v->fcm == PROGRESSIVE && + (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && (v->mv_mode == MV_PMODE_MIXED_MV || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV)); @@ -55,8 +56,9 @@ static inline int vc1_has_SKIPMB_bitplane(const VC1Context *v) { if (v->skip_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_P || - (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); +return (v->fcm == PROGRESSIVE || v->fcm == ILACE_FRAME) && + ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || +(v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)); } /** Check whether the DIRECTMB bitplane is present */ @@ -64,7 +66,8 @@ static inline int vc1_has_DIRECTMB_bitplane(const VC1Context *v) { if (v->dmb_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type; +return (v->fcm == PROGRESSIVE || v->fcm == ILACE_FRAME) && + (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); } /** Check whether the ACPRED bitplane is present */ @@ -89,6 +92,25 @@ static inline int vc1_has_OVERFLAGS_bitplane(const VC1Context *v) v->condover == CONDOVER_SELECT; } +/** Check whether the FIELDTX bitplane is present */ +static inline int vc1_has_FIELDTX_bitplane(const VC1Context *v) +{ +if (v->fieldtx_is_raw) +return 0; +return v->fcm == ILACE_FRAME && + (v->s.pict_type == AV_PICTURE_TYPE_I || +(v->s.pict_type == AV_PICTURE_TYPE_B && v->bi_type)); +} + +/** Check whether the FORWARDMB bitplane is present */ +static inline int vc1_has_FORWARDMB_bitplane(const VC1Context *v) +{ +if (v->fmb_is_raw) +return 0; +return v->fcm == ILACE_FIELD && + (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); +} + /** Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */ static int vc1_get_PTYPE(const VC1Context *v) { @@ -101,10 +123,22 @@ static int vc1_get_PTYPE(const VC1Context *v) return 0; } +/** Reconstruct bitstream FPTYPE (9.1.1.42, index into Table-105) */ +static int vc1_get_FPTYPE(const VC1Context *v) +{ +const MpegEncContext *s = >s; +switch (s->pict_type) { +case AV_PICTURE_TYPE_I: return 0; +case AV_PICTURE_TYPE_P: return 3; +case AV_PICTURE_TYPE_B: return v->bi_type ? 7 : 4; +} +return 0; +} + /** Reconstruct bitstream MVMODE (7.1.1.32) */ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) { -if (v->s.pict_type == AV_PICTURE_TYPE_P || +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)) return get_VAMvModeVC1(v->mv_mode); return 0; @@ -113,11 +147,81 @@ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) /** Reconstruct bitstream MVMODE2 (7.1.1.33) */ static inline VAMvModeVC1 vc1_get_MVMODE2(const VC1Context *v) { -if (v->s.pict_type == AV_PICTURE_TYPE_P && v->mv_mode == MV_PMODE_INTENSITY_COMP) +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && +v->mv_mode == MV_PMODE_INTENSITY_COMP) return get_VAMvModeVC1(v->mv_mode2); return 0; } +#if VA_CHECK_VERSION(1, 1, 0) +static inline int vc1_get_INTCOMPFIELD(const VC1Context *v) +{ +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && +v->fcm == ILACE_FIELD && +v->mv_mode == MV_PMODE_INTENSITY_COMP) +switch (v->intcompfield) { +case 1: return 1; +case 2: return 2; +case 3: return 0; +} +return 0; +} +#endif + +static inline int vc1_get_LUMSCALE(const VC1Context *v) +{ +if (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) { +if ((v->fcm == PROGRESSIVE && v->mv_mode ==
[FFmpeg-devel] [PATCH 1/3 v1.1] avcodec/vc1: add bitstream elements for VAAPI VC-1 interlaced decoding
This patch-set adds support for hardware accelerated VC-1 interlaced decoding that was recently added to Intel's libva/intel-vaapi-driver. This version hopefully does not suffer from the word wrapping issue in my previous submission. Please ignore the previous version. avcodec/vc1: add bitstream elements for VAAPI VC-1 interlaced decoding We need to pass more bitstream elements to the VAAPI VC-1 decoder in order to start doing interlaced decoding in hardware. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1.c | 95 +--- libavcodec/vc1.h | 6 2 files changed, 55 insertions(+), 46 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 48a2cc1e48..2b9f8db3ee 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -629,7 +629,7 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) int pqindex, lowquant, status; v->field_mode = 0; -v->fcm = 0; +v->fcm = PROGRESSIVE; if (v->finterpflag) v->interpfrm = get_bits1(gb); if (!v->s.avctx->codec) @@ -766,7 +766,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) /* Hopefully this is correct for P-frames */ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables -v->cbpcy_vlc = _vc1_cbpcy_p_vlc[get_bits(gb, 2)]; +v->cbptab = get_bits(gb, 2); +v->cbpcy_vlc = _vc1_cbpcy_p_vlc[v->cbptab]; if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); @@ -804,7 +805,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) "Imode: %i, Invert: %i\n", status>>1, status&1); v->s.mv_table_index = get_bits(gb, 2); -v->cbpcy_vlc= _vc1_cbpcy_p_vlc[get_bits(gb, 2)]; +v->cbptab = get_bits(gb, 2); +v->cbpcy_vlc= _vc1_cbpcy_p_vlc[v->cbptab]; if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); @@ -845,7 +847,6 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant; int status; -int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */ int field_mode, fcm; v->numref = 0; @@ -1056,21 +1057,21 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) status = bitplane_decoding(v->s.mbskip_table, >skip_is_raw, v); av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); -mbmodetab = get_bits(gb, 2); +v->mbmodetab = get_bits(gb, 2); if (v->fourmvswitch) -v->mbmode_vlc = _vc1_intfr_4mv_mbmode_vlc[mbmodetab]; +v->mbmode_vlc = _vc1_intfr_4mv_mbmode_vlc[v->mbmodetab]; else -v->mbmode_vlc = _vc1_intfr_non4mv_mbmode_vlc[mbmodetab]; -imvtab = get_bits(gb, 2); -v->imv_vlc = _vc1_1ref_mvdata_vlc[imvtab]; +v->mbmode_vlc = _vc1_intfr_non4mv_mbmode_vlc[v->mbmodetab]; +v->imvtab = get_bits(gb, 2); +v->imv_vlc = _vc1_1ref_mvdata_vlc[v->imvtab]; // interlaced p-picture cbpcy range is [1, 63] -icbptab= get_bits(gb, 3); -v->cbpcy_vlc = _vc1_icbpcy_vlc[icbptab]; -twomvbptab = get_bits(gb, 2); -v->twomvbp_vlc = _vc1_2mv_block_pattern_vlc[twomvbptab]; +v->icbptab = get_bits(gb, 3); +v->cbpcy_vlc = _vc1_icbpcy_vlc[v->icbptab]; +v->twomvbptab = get_bits(gb, 2); +v->twomvbp_vlc = _vc1_2mv_block_pattern_vlc[v->twomvbptab]; if (v->fourmvswitch) { -fourmvbptab = get_bits(gb, 2); -v->fourmvbp_vlc = _vc1_4mv_block_pattern_vlc[fourmvbptab]; +v->fourmvbptab = get_bits(gb, 2); +v->fourmvbp_vlc = _vc1_4mv_block_pattern_vlc[v->fourmvbptab]; } } } @@ -1154,27 +1155,28 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) /* Hopefully this is correct for P-frames */ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables -v->cbpcy_vlc= _vc1_cbpcy_p_vlc[get_bits(gb, 2)]; +v->cbptab = get_bits(gb, 2); +v->cbpcy_vlc= _vc1_cbpcy_p_vlc[v->cbptab]; } else if (v->fcm == ILACE_FRAME) { // frame interlaced
[FFmpeg-devel] [PATCH 3/3] avcodec/vaapi: mask unused bits in bitplane_present.value
Due to the union construct, unused bits in bitplane_present.value might be uninitialized even when the used bits are all set to a value. Masking the unused bits prevents spurious true values when all used bits are unset, e.g. skipped pictures. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vaapi_vc1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index a137979dd4..e93b7285e3 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -387,7 +387,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t if (err) goto fail; -if (pic_param.bitplane_present.value) { +if (pic_param.bitplane_present.value & 0x7f) { uint8_t *bitplane; const uint8_t *ff_bp[3]; int x, y, n; -- 2.13.6 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/3] avcodec/vaapi: add fields for VAAPI VC-1 interlaced decoding
avcodec/vaapi: add fields for VAAPI VC-1 interlaced decoding Pass necessary bitstream elements to the VAAPI VC-1 decoder in order to start doing interlaced decoding in hardware. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vaapi_vc1.c | 167 - 1 file changed, 138 insertions(+), 29 deletions(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 525376790e..a137979dd4 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -44,7 +44,8 @@ static inline int vc1_has_MVTYPEMB_bitplane(const VC1Context *v) { if (v->mv_type_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_P && +return v->fcm == PROGRESSIVE && + (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && (v->mv_mode == MV_PMODE_MIXED_MV || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV)); @@ -55,8 +56,9 @@ static inline int vc1_has_SKIPMB_bitplane(const VC1Context *v) { if (v->skip_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_P || - (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); +return (v->fcm == PROGRESSIVE || v->fcm == ILACE_FRAME) && + ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || +(v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)); } /** Check whether the DIRECTMB bitplane is present */ @@ -64,7 +66,8 @@ static inline int vc1_has_DIRECTMB_bitplane(const VC1Context *v) { if (v->dmb_is_raw) return 0; -return v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type; +return (v->fcm == PROGRESSIVE || v->fcm == ILACE_FRAME) && + (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); } /** Check whether the ACPRED bitplane is present */ @@ -89,6 +92,25 @@ static inline int vc1_has_OVERFLAGS_bitplane(const VC1Context *v) v->condover == CONDOVER_SELECT; } +/** Check whether the FIELDTX bitplane is present */ +static inline int vc1_has_FIELDTX_bitplane(const VC1Context *v) +{ +if (v->fieldtx_is_raw) +return 0; +return v->fcm == ILACE_FRAME && + (v->s.pict_type == AV_PICTURE_TYPE_I || +(v->s.pict_type == AV_PICTURE_TYPE_B && v->bi_type)); +} + +/** Check whether the FORWARDMB bitplane is present */ +static inline int vc1_has_FORWARDMB_bitplane(const VC1Context *v) +{ +if (v->fmb_is_raw) +return 0; +return v->fcm == ILACE_FIELD && + (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); +} + /** Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */ static int vc1_get_PTYPE(const VC1Context *v) { @@ -101,10 +123,22 @@ static int vc1_get_PTYPE(const VC1Context *v) return 0; } +/** Reconstruct bitstream FPTYPE (9.1.1.42, index into Table-105) */ +static int vc1_get_FPTYPE(const VC1Context *v) +{ +const MpegEncContext *s = >s; +switch (s->pict_type) { +case AV_PICTURE_TYPE_I: return 0; +case AV_PICTURE_TYPE_P: return 3; +case AV_PICTURE_TYPE_B: return v->bi_type ? 7 : 4; +} +return 0; +} + /** Reconstruct bitstream MVMODE (7.1.1.32) */ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) { -if (v->s.pict_type == AV_PICTURE_TYPE_P || +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)) return get_VAMvModeVC1(v->mv_mode); return 0; @@ -113,11 +147,81 @@ static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) /** Reconstruct bitstream MVMODE2 (7.1.1.33) */ static inline VAMvModeVC1 vc1_get_MVMODE2(const VC1Context *v) { -if (v->s.pict_type == AV_PICTURE_TYPE_P && v->mv_mode == MV_PMODE_INTENSITY_COMP) +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && +v->mv_mode == MV_PMODE_INTENSITY_COMP) return get_VAMvModeVC1(v->mv_mode2); return 0; } +#if VA_CHECK_VERSION(1, 1, 0) +static inline int vc1_get_INTCOMPFIELD(const VC1Context *v) +{ +if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && +v->fcm == ILACE_FIELD && +v->mv_mode == MV_PMODE_INTENSITY_COMP) +switch (v->intcompfield) { +case 1: return 1; +case 2: return 2; +case 3: return 0; +} +return 0; +} +#endif + +static inline int vc1_get_LUMSCALE(const VC1Context *v) +{ +if (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) { +if ((v->fcm == PROGRESSIVE && v->mv_mode == MV
[FFmpeg-devel] [PATCH 1/3] avcodec/vc1: add bitstream elements for VAAPI VC-1 interlaced decoding
This patch-set adds support for hardware accelerated VC-1 interlaced decoding that was recently added to Intel's libva/intel-vaapi-driver. avcodec/vc1: add bitstream elements for VAAPI VC-1 interlaced decoding We need to pass more bitstream elements to the VAAPI VC-1 decoder in order to start doing interlaced decoding in hardware. Signed-off-by: Jerome Borsboom <jerome.borsb...@carpalis.nl> --- libavcodec/vc1.c | 95 +--- libavcodec/vc1.h | 6 2 files changed, 55 insertions(+), 46 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 48a2cc1e48..2b9f8db3ee 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -629,7 +629,7 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) int pqindex, lowquant, status; v->field_mode = 0; -v->fcm = 0; +v->fcm = PROGRESSIVE; if (v->finterpflag) v->interpfrm = get_bits1(gb); if (!v->s.avctx->codec) @@ -766,7 +766,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) /* Hopefully this is correct for P-frames */ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables -v->cbpcy_vlc = _vc1_cbpcy_p_vlc[get_bits(gb, 2)]; +v->cbptab = get_bits(gb, 2); +v->cbpcy_vlc = _vc1_cbpcy_p_vlc[v->cbptab]; if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); @@ -804,7 +805,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) "Imode: %i, Invert: %i\n", status>>1, status&1); v->s.mv_table_index = get_bits(gb, 2); -v->cbpcy_vlc= _vc1_cbpcy_p_vlc[get_bits(gb, 2)]; +v->cbptab = get_bits(gb, 2); +v->cbpcy_vlc= _vc1_cbpcy_p_vlc[v->cbptab]; if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); @@ -845,7 +847,6 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant; int status; -int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */ int field_mode, fcm; v->numref = 0; @@ -1056,21 +1057,21 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) status = bitplane_decoding(v->s.mbskip_table, >skip_is_raw, v); av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); -mbmodetab = get_bits(gb, 2); +v->mbmodetab = get_bits(gb, 2); if (v->fourmvswitch) -v->mbmode_vlc = _vc1_intfr_4mv_mbmode_vlc[mbmodetab]; +v->mbmode_vlc = _vc1_intfr_4mv_mbmode_vlc[v->mbmodetab]; else -v->mbmode_vlc = _vc1_intfr_non4mv_mbmode_vlc[mbmodetab]; -imvtab = get_bits(gb, 2); -v->imv_vlc = _vc1_1ref_mvdata_vlc[imvtab]; +v->mbmode_vlc = _vc1_intfr_non4mv_mbmode_vlc[v->mbmodetab]; +v->imvtab = get_bits(gb, 2); +v->imv_vlc = _vc1_1ref_mvdata_vlc[v->imvtab]; // interlaced p-picture cbpcy range is [1, 63] -icbptab= get_bits(gb, 3); -v->cbpcy_vlc = _vc1_icbpcy_vlc[icbptab]; -twomvbptab = get_bits(gb, 2); -v->twomvbp_vlc = _vc1_2mv_block_pattern_vlc[twomvbptab]; +v->icbptab = get_bits(gb, 3); +v->cbpcy_vlc = _vc1_icbpcy_vlc[v->icbptab]; +v->twomvbptab = get_bits(gb, 2); +v->twomvbp_vlc = _vc1_2mv_block_pattern_vlc[v->twomvbptab]; if (v->fourmvswitch) { -fourmvbptab = get_bits(gb, 2); -v->fourmvbp_vlc = _vc1_4mv_block_pattern_vlc[fourmvbptab]; +v->fourmvbptab = get_bits(gb, 2); +v->fourmvbp_vlc = _vc1_4mv_block_pattern_vlc[v->fourmvbptab]; } } } @@ -1154,27 +1155,28 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) /* Hopefully this is correct for P-frames */ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables -v->cbpcy_vlc= _vc1_cbpcy_p_vlc[get_bits(gb, 2)]; +v->cbptab = get_bits(gb, 2); +v->cbpcy_vlc= _vc1_cbpcy_p_vlc[v->cbptab]; } else if (v->fcm == ILACE_FRAME) { // frame interlaced v->qs_last = v->s.quarter_sample; v->s.quarter_sample = 1; v-