From e51c08b0a288f49a2cc62367d7052640f262e053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 14 Apr 2017 13:38:53 +0300 Subject: [PATCH] qtmux: Fix timescale of timecode tracks They should have ideally the same timescale of the video track, which we can't guarantee here as in theory timecode configuration and video framerate could be different. However we should set a correct timescale based on the framerate given in the timecode configuration, and not just use the framerate numerator. --- gst/isomp4/atoms.c | 25 ++++++++++++++++++++++--- gst/isomp4/atoms.h | 2 ++ gst/isomp4/gstqtmux.c | 20 ++------------------ 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/gst/isomp4/atoms.c b/gst/isomp4/atoms.c index af6eaeb28a..b19f01840b 100644 --- a/gst/isomp4/atoms.c +++ b/gst/isomp4/atoms.c @@ -3779,6 +3779,23 @@ atom_trak_add_audio_entry (AtomTRAK * trak, AtomsContext * context, return mp4a; } +/* return number of centiframes per second */ +guint +atom_framerate_to_timescale (gint n, gint d) +{ + if (n == 0) + return 10000; + + if (d != 1 && d != 1001) { + /* otherwise there are probably rounding errors and we should rather guess + * if it's close enough to a well known framerate */ + gst_video_guess_framerate (gst_util_uint64_scale (d, GST_SECOND, n), &n, + &d); + } + + return gst_util_uint64_scale (n, 100, d); +} + static SampleTableEntryTMCD * atom_trak_add_timecode_entry (AtomTRAK * trak, AtomsContext * context, GstVideoTimeCode * tc) @@ -3790,7 +3807,8 @@ atom_trak_add_timecode_entry (AtomTRAK * trak, AtomsContext * context, trak->mdia.hdlr.handler_type = FOURCC_tmcd; g_free (trak->mdia.hdlr.name); trak->mdia.hdlr.name = g_strdup ("Time Code Media Handler"); - trak->mdia.mdhd.time_info.timescale = tc->config.fps_n / tc->config.fps_d; + trak->mdia.mdhd.time_info.timescale = + atom_framerate_to_timescale (tc->config.fps_n, tc->config.fps_d); tmcd->se.kind = TIMECODE; tmcd->se.data_reference_index = 1; @@ -3799,8 +3817,9 @@ atom_trak_add_timecode_entry (AtomTRAK * trak, AtomsContext * context, tmcd->tc_flags |= TC_DROP_FRAME; tmcd->name.language_code = 0; tmcd->name.name = g_strdup ("Tape"); - tmcd->timescale = tc->config.fps_n; - tmcd->frame_duration = tc->config.fps_d; + tmcd->timescale = + atom_framerate_to_timescale (tc->config.fps_n, tc->config.fps_d); + tmcd->frame_duration = 100; if (tc->config.fps_d == 1001) tmcd->n_frames = tc->config.fps_n / 1000; else diff --git a/gst/isomp4/atoms.h b/gst/isomp4/atoms.h index 949b79098f..c7a5d8b589 100644 --- a/gst/isomp4/atoms.h +++ b/gst/isomp4/atoms.h @@ -938,6 +938,8 @@ void atom_moov_chunks_set_offset (AtomMOOV *moov, guint32 offset); void atom_moov_add_trak (AtomMOOV *moov, AtomTRAK *trak); guint atom_moov_get_trak_count (AtomMOOV *moov); +guint atom_framerate_to_timescale (gint fps_n, gint fps_d); + guint64 atom_mvhd_copy_data (AtomMVHD * atom, guint8 ** buffer, guint64 * size, guint64 * offset); void atom_stco64_chunks_set_offset (AtomSTCO64 * stco64, guint32 offset); diff --git a/gst/isomp4/gstqtmux.c b/gst/isomp4/gstqtmux.c index 9c3c4c9250..761278c920 100644 --- a/gst/isomp4/gstqtmux.c +++ b/gst/isomp4/gstqtmux.c @@ -4049,23 +4049,6 @@ refuse_renegotiation: } } -/* return number of centiframes per second */ -static guint -adjust_rate (gint n, gint d) -{ - if (n == 0) - return 10000; - - if (d != 1 && d != 1001) { - /* otherwise there are probably rounding errors and we should rather guess - * if it's close enough to a well known framerate */ - gst_video_guess_framerate (gst_util_uint64_scale (d, GST_SECOND, n), &n, - &d); - } - - return gst_util_uint64_scale (n, 100, d); -} - static gboolean gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps) { @@ -4141,7 +4124,8 @@ gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps) /* bring frame numerator into a range that ensures both reasonable resolution * as well as a fair duration */ rate = qtmux->trak_timescale ? - qtmux->trak_timescale : adjust_rate (framerate_num, framerate_den); + qtmux->trak_timescale : atom_framerate_to_timescale (framerate_num, + framerate_den); GST_DEBUG_OBJECT (qtmux, "Rate of video track selected: %" G_GUINT32_FORMAT, rate);