[FFmpeg-devel] [PATCH 2/2] mxfdec: set audio packets pts
Matthieu Bouron
matthieu.bouron at gmail.com
Thu Sep 20 20:31:29 CEST 2012
Also fix playback of ntsc files.
---
libavformat/mxfdec.c | 84 +++++++++++++++++++++++++++++++++++++++++++--
tests/ref/fate/mxf-demux | 6 ++--
tests/ref/lavf/mxf | 2 +-
tests/ref/seek/lavf_mxf | 18 +++++-----
tests/ref/seek/lavf_mxf_d10 | 30 ++++++++--------
5 files changed, 109 insertions(+), 31 deletions(-)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 16b8c12..eb33b67 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -223,6 +223,8 @@ typedef struct {
int nb_index_tables;
MXFIndexTable *index_tables;
int edit_units_per_packet; ///< how many edit units to read at a time (PCM, OPAtom)
+ AVRational *streams_time_bases;
+ uint64_t *streams_samples;
} MXFContext;
enum MXFWrappingScheme {
@@ -1431,6 +1433,15 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
ret = AVERROR(ENOMEM);
goto fail_and_free;
}
+
+ mxf->streams_time_bases = av_realloc_f(mxf->streams_time_bases, mxf->fc->nb_streams, sizeof(*mxf->streams_time_bases));
+ mxf->streams_samples = av_realloc_f(mxf->streams_samples, mxf->fc->nb_streams, sizeof(*mxf->streams_samples));
+ if (!mxf->streams_time_bases || !mxf->streams_samples) {
+ av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream information\n");
+ ret = AVERROR(ENOMEM);
+ goto fail_and_free;
+ }
+
st->id = source_track->track_id;
st->priv_data = source_track;
st->duration = component->duration;
@@ -1438,6 +1449,8 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
st->duration = AV_NOPTS_VALUE;
st->start_time = component->start_position;
avpriv_set_pts_info(st, 64, material_track->edit_rate.den, material_track->edit_rate.num);
+ mxf->streams_samples[mxf->fc->nb_streams - 1] = 0;
+ mxf->streams_time_bases[mxf->fc->nb_streams - 1] = av_inv_q(material_track->edit_rate);
PRINT_KEY(mxf->fc, "data definition ul", source_track->sequence->data_definition_ul);
codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
@@ -1541,8 +1554,14 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
st->codec->channels = descriptor->channels;
st->codec->bits_per_coded_sample = descriptor->bits_per_sample;
- if (descriptor->sample_rate.den > 0)
+ if (descriptor->sample_rate.den > 0) {
+ st->time_base = av_inv_q(descriptor->sample_rate);
st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
+ } else {
+ av_log(mxf->fc, AV_LOG_WARNING, "invalid sample rate (%d/%d) found for stream #%d, time base forced to 1/48000\n",
+ descriptor->sample_rate.num, descriptor->sample_rate.den, st->index);
+ st->time_base = (AVRational){1, 48000};
+ }
/* TODO: implement AV_CODEC_ID_RAWAUDIO */
if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
@@ -1982,6 +2001,52 @@ static int64_t mxf_set_current_edit_unit(MXFContext *mxf, int64_t current_offset
return next_ofs;
}
+static int mxf_compute_sample_count(MXFContext *mxf, int stream_index, uint64_t *sample_count)
+{
+ int i, total = 0, size = 0;
+ AVRational time_base = mxf->streams_time_bases[stream_index];
+ const MXFSamplesPerFrame *spf;
+
+ spf = ff_mxf_get_samples_per_frame(mxf->fc, time_base);
+ if (!spf) {
+ av_log(mxf->fc, AV_LOG_ERROR, "unsupported codec time base %d/%d",
+ time_base.num, time_base.den);
+ return AVERROR(EINVAL);
+ }
+
+ while (spf->samples_per_frame[size]) {
+ total += spf->samples_per_frame[size];
+ size++;
+ }
+
+ if (!size)
+ return AVERROR(EINVAL);
+
+ *sample_count = (mxf->current_edit_unit / size) * total;
+ for (i = 0; i < mxf->current_edit_unit % size; i++) {
+ *sample_count += spf->samples_per_frame[i];
+ }
+
+ return 0;
+}
+
+static int mxf_set_audio_pts(MXFContext *mxf, AVCodecContext *codec, AVPacket *pkt)
+{
+ int index = pkt->stream_index;
+ uint64_t current_sample_count = 0;
+ int ret = mxf_compute_sample_count(mxf, index, ¤t_sample_count);
+ if (ret < 0)
+ return ret;
+
+ // read sample count and computed sample count max difference is 1 at most
+ if (fabs(current_sample_count - mxf->streams_samples[index]) > 1)
+ mxf->streams_samples[index] = current_sample_count;
+
+ pkt->pts = mxf->streams_samples[index];
+ mxf->streams_samples[index] += pkt->size / (codec->channels * av_get_bits_per_sample(codec->codec_id) / 8);
+ return 0;
+}
+
static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
{
KLVPacket klv;
@@ -2007,6 +2072,7 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
int64_t next_ofs, next_klv;
AVStream *st;
MXFTrack *track;
+ AVCodecContext *codec;
if (index < 0) {
av_log(s, AV_LOG_ERROR, "error getting stream index %d\n", AV_RB32(klv.key+12));
@@ -2045,7 +2111,8 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
pkt->stream_index = index;
pkt->pos = klv.offset;
- if (s->streams[index]->codec->codec_type == AVMEDIA_TYPE_VIDEO && next_ofs >= 0) {
+ codec = s->streams[index]->codec;
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO && next_ofs >= 0) {
/* mxf->current_edit_unit good - see if we have an index table to derive timestamps from */
MXFIndexTable *t = &mxf->index_tables[0];
@@ -2057,6 +2124,10 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
* let utils.c figure out DTS since it can be < PTS if low_delay = 0 (Sony IMX30) */
pkt->pts = mxf->current_edit_unit;
}
+ } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO && next_ofs >= 0) {
+ int ret = mxf_set_audio_pts(mxf, codec, pkt);
+ if (ret < 0)
+ return ret;
}
/* seek for truncated packets */
@@ -2114,13 +2185,18 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
if ((size = av_get_packet(s->pb, pkt, size)) < 0)
return size;
+ pkt->stream_index = 0;
+
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && t->ptses &&
mxf->current_edit_unit >= 0 && mxf->current_edit_unit < t->nb_ptses) {
pkt->dts = mxf->current_edit_unit + t->first_dts;
pkt->pts = t->ptses[mxf->current_edit_unit];
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ int ret = mxf_set_audio_pts(mxf, st->codec, pkt);
+ if (ret < 0)
+ return ret;
}
- pkt->stream_index = 0;
mxf->current_edit_unit += edit_units;
return 0;
@@ -2164,6 +2240,8 @@ static int mxf_read_close(AVFormatContext *s)
av_freep(&mxf->metadata_sets);
av_freep(&mxf->aesc);
av_freep(&mxf->local_tags);
+ av_freep(&mxf->streams_time_bases);
+ av_freep(&mxf->streams_samples);
for (i = 0; i < mxf->nb_index_tables; i++) {
av_freep(&mxf->index_tables[i].segments);
diff --git a/tests/ref/fate/mxf-demux b/tests/ref/fate/mxf-demux
index e162775..426afae 100644
--- a/tests/ref/fate/mxf-demux
+++ b/tests/ref/fate/mxf-demux
@@ -1,7 +1,7 @@
#tb 0: 1/25
-#tb 1: 1/25
+#tb 1: 1/8000
0, 0, -9223372036854775808, 1, 8468, 0xc0855553
-1, 0, 0, 50, 32000, 0x479155e6
+1, 0, 0, 16000, 32000, 0x479155e6
0, 1, -9223372036854775808, 1, 3814, 0xa10783b4
0, 2, -9223372036854775808, 1, 3747, 0xb7bf6973
0, 3, -9223372036854775808, 1, 3705, 0x5462a600
@@ -52,7 +52,7 @@
0, 48, -9223372036854775808, 1, 3688, 0x1db45852
0, 49, -9223372036854775808, 1, 38412, 0x2ee26a63
0, 50, -9223372036854775808, 1, 8385, 0x0bc20a27
-1, 50, 50, 50, 32000, 0x8f7e5009
+1, 16000, 16000, 16000, 32000, 0x8f7e5009
0, 51, -9223372036854775808, 1, 3733, 0xa3e2a9a0
0, 52, -9223372036854775808, 1, 3773, 0x27769caa
0, 53, -9223372036854775808, 1, 3670, 0xc8335e98
diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf
index 2253329..7e48d50 100644
--- a/tests/ref/lavf/mxf
+++ b/tests/ref/lavf/mxf
@@ -3,7 +3,7 @@
./tests/data/lavf/lavf.mxf CRC=0x4ace0849
88ab06201db1953329bfb4aa04a4fe05 *./tests/data/lavf/lavf.mxf
553529 ./tests/data/lavf/lavf.mxf
-./tests/data/lavf/lavf.mxf CRC=0xdb9bdf92
+./tests/data/lavf/lavf.mxf CRC=0x86fddf92
52c5b74ecfdc48bd77d79a6bbe62d2de *./tests/data/lavf/lavf.mxf
525881 ./tests/data/lavf/lavf.mxf
./tests/data/lavf/lavf.mxf CRC=0x4ace0849
diff --git a/tests/ref/seek/lavf_mxf b/tests/ref/seek/lavf_mxf
index cc634a8..5f2cf5d 100644
--- a/tests/ref/seek/lavf_mxf
+++ b/tests/ref/seek/lavf_mxf
@@ -7,8 +7,8 @@ ret: 0 st: 0 flags:0 ts: 0.800000
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
ret: 0 st: 0 flags:1 ts:-0.320000
ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801
-ret:-1 st: 1 flags:0 ts: 2.560000
-ret: 0 st: 1 flags:1 ts: 1.480000
+ret:-1 st: 1 flags:0 ts: 2.576667
+ret: 0 st: 1 flags:1 ts: 1.470833
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
ret: 0 st:-1 flags:0 ts: 0.365002
ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.480000 pos: 211968 size: 24787
@@ -17,9 +17,9 @@ ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801
ret:-1 st: 0 flags:0 ts: 2.160000
ret: 0 st: 0 flags:1 ts: 1.040000
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
-ret: 0 st: 1 flags:0 ts:-0.040000
+ret: 0 st: 1 flags:0 ts:-0.058333
ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801
-ret: 0 st: 1 flags:1 ts: 2.840000
+ret: 0 st: 1 flags:1 ts: 2.835833
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
ret:-1 st:-1 flags:0 ts: 1.730004
ret: 0 st:-1 flags:1 ts: 0.624171
@@ -28,9 +28,9 @@ ret: 0 st: 0 flags:0 ts:-0.480000
ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801
ret: 0 st: 0 flags:1 ts: 2.400000
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
-ret:-1 st: 1 flags:0 ts: 1.320000
-ret: 0 st: 1 flags:1 ts: 0.200000
-ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801
+ret:-1 st: 1 flags:0 ts: 1.306667
+ret: 0 st: 1 flags:1 ts: 0.200833
+ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
ret: 0 st:-1 flags:0 ts:-0.904994
ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801
ret: 0 st:-1 flags:1 ts: 1.989173
@@ -39,8 +39,8 @@ ret: 0 st: 0 flags:0 ts: 0.880000
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
ret: 0 st: 0 flags:1 ts:-0.240000
ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801
-ret:-1 st: 1 flags:0 ts: 2.680000
-ret: 0 st: 1 flags:1 ts: 1.560000
+ret:-1 st: 1 flags:0 ts: 2.671667
+ret: 0 st: 1 flags:1 ts: 1.565833
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
ret: 0 st:-1 flags:0 ts: 0.460008
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
diff --git a/tests/ref/seek/lavf_mxf_d10 b/tests/ref/seek/lavf_mxf_d10
index 4cfe595..e091c77 100644
--- a/tests/ref/seek/lavf_mxf_d10
+++ b/tests/ref/seek/lavf_mxf_d10
@@ -7,10 +7,10 @@ ret: 0 st: 0 flags:0 ts: 0.800000
ret: 0 st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:4265984 size:150000
ret: 0 st: 0 flags:1 ts:-0.320000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000
-ret: 0 st: 1 flags:0 ts: 2.560000
-ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
-ret: 0 st: 1 flags:1 ts: 1.480000
-ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
+ret: 0 st: 1 flags:0 ts: 2.576667
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
+ret: 0 st: 1 flags:1 ts: 1.470833
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
ret: 0 st:-1 flags:0 ts: 0.365002
ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:1923072 size:150000
ret: 0 st:-1 flags:1 ts:-0.740831
@@ -19,10 +19,10 @@ ret: 0 st: 0 flags:0 ts: 2.160000
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
ret: 0 st: 0 flags:1 ts: 1.040000
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
-ret: 0 st: 1 flags:0 ts:-0.040000
+ret: 0 st: 1 flags:0 ts:-0.058333
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000
-ret: 0 st: 1 flags:1 ts: 2.840000
-ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
+ret: 0 st: 1 flags:1 ts: 2.835833
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
ret: 0 st:-1 flags:0 ts: 1.730004
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
ret: 0 st:-1 flags:1 ts: 0.624171
@@ -31,10 +31,10 @@ ret: 0 st: 0 flags:0 ts:-0.480000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000
ret: 0 st: 0 flags:1 ts: 2.400000
ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
-ret: 0 st: 1 flags:0 ts: 1.320000
-ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
-ret: 0 st: 1 flags:1 ts: 0.200000
-ret: 0 st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:1071104 size:150000
+ret: 0 st: 1 flags:0 ts: 1.306667
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
+ret: 0 st: 1 flags:1 ts: 0.200833
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
ret: 0 st:-1 flags:0 ts:-0.904994
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000
ret: 0 st:-1 flags:1 ts: 1.989173
@@ -43,10 +43,10 @@ ret: 0 st: 0 flags:0 ts: 0.880000
ret: 0 st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:4691968 size:150000
ret: 0 st: 0 flags:1 ts:-0.240000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000
-ret: 0 st: 1 flags:0 ts: 2.680000
-ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
-ret: 0 st: 1 flags:1 ts: 1.560000
-ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000
+ret: 0 st: 1 flags:0 ts: 2.671667
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
+ret: 0 st: 1 flags:1 ts: 1.565833
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000
ret: 0 st:-1 flags:0 ts: 0.460008
ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:2562048 size:150000
ret: 0 st:-1 flags:1 ts:-0.645825
--
1.7.12.1
More information about the ffmpeg-devel
mailing list