avformat/mxfenc: fix stored/sampled/displayed width/height

According to MXF specs the Stored Rectangle corresponds to the data which is
passed to the compressor and received from the decompressor, so they should
contain the width / height extended to the macroblock boundary.

In practice however width and height values rounded to the upper 16 multiples
are only seen when muxing MPEG formats. Therefore this patch changes stored
width and height values to unrounded for all non-MPEG formats, even macroblock
based ones.

For DNXHD the specs (ST 2019-4) explicitly indicates to use 1080 for 1088p.
For ProRes the specs (RDD 44) only refer to to ST 377-1 without precision but
no known commercial implementations are using rounded values.
DV is not using 16x16 macroblocks, so 16 rounding makes no sense.

The patch also fixes Sampled Width / Display Width to use unrounded values.

Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
Jerome Martinez 2023-01-14 13:32:36 +01:00 committed by Marton Balint
parent cd954aa3c6
commit 174ca11d91
4 changed files with 27 additions and 8 deletions

View File

@ -1149,8 +1149,9 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
{
MXFStreamContext *sc = st->priv_data;
AVIOContext *pb = s->pb;
int stored_width = 0;
int stored_height = (st->codecpar->height+15)/16*16;
int stored_width = st->codecpar->width;
int stored_height = st->codecpar->height;
int display_width;
int display_height;
int f1, f2;
const MXFCodecUL *color_primaries_ul;
@ -1169,12 +1170,24 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
else if (st->codecpar->height == 720)
stored_width = 1280;
}
if (!stored_width)
stored_width = (st->codecpar->width+15)/16*16;
display_width = stored_width;
switch (st->codecpar->codec_id) {
case AV_CODEC_ID_MPEG2VIDEO:
case AV_CODEC_ID_H264:
//Based on 16x16 macroblocks
stored_width = (stored_width+15)/16*16;
stored_height = (stored_height+15)/16*16;
break;
default:
break;
}
//Stored width
mxf_write_local_tag(s, 4, 0x3203);
avio_wb32(pb, stored_width);
//Stored height
mxf_write_local_tag(s, 4, 0x3202);
avio_wb32(pb, stored_height>>sc->interlaced);
@ -1194,7 +1207,7 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
//Sampled width
mxf_write_local_tag(s, 4, 0x3205);
avio_wb32(pb, stored_width);
avio_wb32(pb, display_width);
//Samples height
mxf_write_local_tag(s, 4, 0x3204);
@ -1208,8 +1221,9 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
mxf_write_local_tag(s, 4, 0x3207);
avio_wb32(pb, 0);
//Display width
mxf_write_local_tag(s, 4, 0x3209);
avio_wb32(pb, stored_width);
avio_wb32(pb, display_width);
if (st->codecpar->height == 608) // PAL + VBI
display_height = 576;
@ -1218,6 +1232,7 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
else
display_height = st->codecpar->height;
//Display height
mxf_write_local_tag(s, 4, 0x3208);
avio_wb32(pb, display_height>>sc->interlaced);

View File

@ -9,7 +9,7 @@ FATE_LAVF_CONTAINER-$(call ENCDEC2, MPEG4, PCM_ALAW, MOV) +
FATE_LAVF_CONTAINER-$(call ENCDEC, MPEG4, MOV) += mp4
FATE_LAVF_CONTAINER-$(call ENCDEC2, MPEG1VIDEO, MP2, MPEG1SYSTEM MPEGPS) += mpg
FATE_LAVF_CONTAINER-$(call ENCDEC , FFV1, MXF) += mxf_ffv1
FATE_LAVF_CONTAINER-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += mxf mxf_dv25 mxf_dvcpro50
FATE_LAVF_CONTAINER-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += mxf mxf_dv25 mxf_dvcpro50 mxf_dvcpro100
FATE_LAVF_CONTAINER-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF_D10 MXF) += mxf_d10
FATE_LAVF_CONTAINER-$(call ENCDEC2, DNXHD, PCM_S16LE, MXF_OPATOM MXF) += mxf_opatom mxf_opatom_audio
FATE_LAVF_CONTAINER-$(call ENCDEC2, MPEG4, MP2, NUT) += nut
@ -56,6 +56,7 @@ fate-lavf-mxf: CMD = lavf_container_timecode "-ar 48000 -bf 2 -threads 1"
fate-lavf-mxf_d10: CMD = lavf_container "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,pad=720:608:0:32 -c:v mpeg2video -g 0 -flags +ildct+low_delay -dc 10 -non_linear_quant 1 -intra_vlc 1 -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10"
fate-lavf-mxf_dv25: CMD = lavf_container "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,setdar=4/3 -c:v dvvideo -pix_fmt yuv420p -b 25000k -top 0 -f mxf"
fate-lavf-mxf_dvcpro50: CMD = lavf_container "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,setdar=16/9 -c:v dvvideo -pix_fmt yuv422p -b 50000k -top 0 -f mxf"
fate-lavf-mxf_dvcpro100: CMD = lavf_container "-ar 48000 -ac 2" "-r 25 -vf scale=1440:1080,setdar=16/9 -c:v dvvideo -pix_fmt yuv422p -b 100000k -top 0 -f mxf"
fate-lavf-mxf_ffv1: CMD = lavf_container "-an" "-r 25 -vf scale=720:576,setdar=4/3 -c:v ffv1 -level 3 -pix_fmt yuv420p -f mxf"
fate-lavf-mxf_opatom: CMD = lavf_container "" "-s 1920x1080 -c:v dnxhd -pix_fmt yuv422p -vb 36M -f mxf_opatom -map 0"
fate-lavf-mxf_opatom_audio: CMD = lavf_container "-ar 48000 -ac 1" "-f mxf_opatom -mxf_audio_edit_rate 25 -map 1"

View File

@ -0,0 +1,3 @@
efa5cdde54ac38b02827ee8b6d7f03a4 *tests/data/lavf/lavf.mxf_dvcpro100
14637613 tests/data/lavf/lavf.mxf_dvcpro100
tests/data/lavf/lavf.mxf_dvcpro100 CRC=0x245e9a5f

View File

@ -1,3 +1,3 @@
215ea72602bfeb70e99fc9d79fef073c *tests/data/lavf/lavf.mxf_opatom
6418766ca9b8b23fae74a80d66f26f3e *tests/data/lavf/lavf.mxf_opatom
4717625 tests/data/lavf/lavf.mxf_opatom
tests/data/lavf/lavf.mxf_opatom CRC=0xb13ba2f8