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.
This commit is contained in:
Sebastian Dröge 2017-04-14 13:38:53 +03:00
parent c6e9c67f63
commit e51c08b0a2
3 changed files with 26 additions and 21 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);