diff --git a/libavformat/mxf.c b/libavformat/mxf.c index c8b57f7f0b..8376a2b9bf 100644 --- a/libavformat/mxf.c +++ b/libavformat/mxf.c @@ -171,3 +171,20 @@ const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, return &mxf_spf[idx]; } + +static const int mxf_content_package_rates[] = { + 3, 2, 7, 13, 4, 10, 12, +}; + +int ff_mxf_get_content_package_rate(AVRational time_base) +{ + int idx = av_find_nearest_q_idx(time_base, mxf_time_base); + AVRational diff = av_sub_q(time_base, mxf_time_base[idx]); + + diff.num = FFABS(diff.num); + + if (av_cmp_q(diff, (AVRational){1, 1000}) >= 0) + return -1; + + return mxf_content_package_rates[idx]; +} diff --git a/libavformat/mxf.h b/libavformat/mxf.h index f6e75919c5..4394450dea 100644 --- a/libavformat/mxf.h +++ b/libavformat/mxf.h @@ -93,6 +93,8 @@ extern const MXFCodecUL ff_mxf_codec_tag_uls[]; int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt); const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base); +int ff_mxf_get_content_package_rate(AVRational time_base); + #define PRIxUID \ "%02x.%02x.%02x.%02x." \ diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index b34ab8ba47..12d99e587d 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -416,6 +416,7 @@ typedef struct MXFContext { AVStream *timecode_track; int timecode_base; ///< rounded time code base (25 or 30) int edit_unit_byte_count; ///< fixed edit unit byte count + int content_package_rate; ///< content package rate in system element, see SMPTE 326M uint64_t body_offset; uint32_t instance_number; uint8_t umid[16]; ///< unique material identifier @@ -2462,6 +2463,7 @@ static int mxf_write_header(AVFormatContext *s) tbc.den, tbc.num); return AVERROR(EINVAL); } + mxf->content_package_rate = ff_mxf_get_content_package_rate(tbc); mxf->time_base = spf->time_base; rate = av_inv_q(mxf->time_base); avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den); @@ -2630,7 +2632,7 @@ static void mxf_write_system_item(AVFormatContext *s) avio_write(pb, system_metadata_pack_key, 16); klv_encode_ber4_length(pb, 57); avio_w8(pb, 0x5c); // UL, user date/time stamp, picture and sound item present - avio_w8(pb, 0x04); // content package rate + avio_w8(pb, mxf->content_package_rate); // content package rate avio_w8(pb, 0x00); // content package type avio_wb16(pb, 0x00); // channel handle avio_wb16(pb, (mxf->tc.start + frame) & 0xFFFF); // continuity count, supposed to overflow diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf index 9ad47e7594..4466685a2d 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,7 +1,7 @@ 649009e3d3d62eb3b6c56334d057cc4d *./tests/data/lavf/lavf.mxf 526393 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0x8dddfaab -5025d7f79b638166b787b3cb8364e5d9 *./tests/data/lavf/lavf.mxf +9076b7015cffe8aa72883e900a2041a5 *./tests/data/lavf/lavf.mxf 561721 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0x96ff1b48 02bf8f0cd8951a49e277306691cb1538 *./tests/data/lavf/lavf.mxf