Re: [FFmpeg-devel] [PATCH 087/114] avcodec/vc1: Avoid code duplication when initializing VLCs

2020-11-18 Thread Jerome Borsboom
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 Thread Jerome Borsboom
> 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

2019-01-14 Thread 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;
 }
 
 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

2019-01-12 Thread Jerome Borsboom
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

2019-01-11 Thread Jerome Borsboom
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

2019-01-11 Thread Jerome Borsboom
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

2019-01-11 Thread Jerome Borsboom
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

2018-11-16 Thread Jerome Borsboom
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

2018-11-16 Thread Jerome Borsboom
> 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

2018-11-14 Thread Jerome Borsboom
>> +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

2018-11-14 Thread Jerome Borsboom
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-24 Thread Jerome Borsboom
> 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

2018-10-23 Thread 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.

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.

2018-10-15 Thread Jerome Borsboom
> 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.

2018-10-13 Thread Jerome Borsboom
> 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.

2018-07-13 Thread Jerome Borsboom
> 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

2018-06-29 Thread Jerome Borsboom
> 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

2018-06-20 Thread Jerome Borsboom
> 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

2018-06-20 Thread Jerome Borsboom
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

2018-06-20 Thread Jerome Borsboom
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

2018-06-20 Thread Jerome Borsboom
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

2018-06-20 Thread Jerome Borsboom
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

2018-06-18 Thread Jerome Borsboom
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

2018-06-14 Thread Jerome Borsboom
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

2018-06-12 Thread Jerome Borsboom
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

2018-06-10 Thread Jerome Borsboom
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

2018-06-08 Thread Jerome Borsboom
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

2018-06-08 Thread Jerome Borsboom
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

2018-06-08 Thread Jerome Borsboom
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

2018-06-08 Thread Jerome Borsboom
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

2018-06-06 Thread Jerome Borsboom
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

2018-06-06 Thread Jerome Borsboom
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

2018-06-06 Thread Jerome Borsboom
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

2018-06-06 Thread Jerome Borsboom
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

2018-06-04 Thread Jerome Borsboom
> 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

2018-05-30 Thread Jerome Borsboom
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

2018-05-29 Thread Jerome Borsboom
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

2018-05-29 Thread Jerome Borsboom
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

2018-05-29 Thread Jerome Borsboom
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

2018-05-28 Thread Jerome Borsboom
>> 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

2018-05-27 Thread Jerome Borsboom
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

2018-05-20 Thread Jerome Borsboom
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

2018-05-20 Thread Jerome Borsboom
>> 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

2018-05-20 Thread Jerome Borsboom
>> 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

2018-05-20 Thread Jerome Borsboom
>>  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 Thread Jerome Borsboom
> 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

2018-05-18 Thread Jerome Borsboom
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

2018-05-18 Thread Jerome Borsboom
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

2018-05-18 Thread Jerome Borsboom
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

2018-05-18 Thread Jerome Borsboom
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

2018-05-18 Thread Jerome Borsboom
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

2018-05-09 Thread Jerome Borsboom
>> 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

2018-05-08 Thread Jerome Borsboom
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

2018-05-08 Thread Jerome Borsboom
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

2018-04-28 Thread Jerome Borsboom
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

2018-04-28 Thread Jerome Borsboom
> 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

2018-04-27 Thread Jerome Borsboom
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

2018-04-26 Thread Jerome Borsboom
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

2018-04-25 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-23 Thread Jerome Borsboom
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

2018-04-21 Thread Jerome Borsboom
> 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

2018-03-29 Thread Jerome Borsboom
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

2018-03-01 Thread Jerome Borsboom
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

2018-02-28 Thread Jerome Borsboom

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

2018-02-26 Thread Jerome Borsboom
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

2018-02-26 Thread Jerome Borsboom
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

2018-02-26 Thread Jerome Borsboom
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

2018-02-25 Thread Jerome Borsboom

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

2018-02-25 Thread Jerome Borsboom

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

2018-02-25 Thread Jerome Borsboom
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-