mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 22:46:24 +00:00
qtdemux: Put framerate into the closedcaption caps if it can be calculated from the stream
Using the same calculation used for video streams.
This commit is contained in:
parent
830e7dc14b
commit
c50be8f146
1 changed files with 81 additions and 57 deletions
|
@ -8329,67 +8329,75 @@ gst_qtdemux_configure_protected_caps (GstQTDemux * qtdemux,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_qtdemux_guess_framerate (GstQTDemux * qtdemux, QtDemuxStream * stream)
|
||||||
|
{
|
||||||
|
/* fps is calculated base on the duration of the average framerate since
|
||||||
|
* qt does not have a fixed framerate. */
|
||||||
|
gboolean fps_available = TRUE;
|
||||||
|
guint32 first_duration = 0;
|
||||||
|
|
||||||
|
if (stream->n_samples > 0)
|
||||||
|
first_duration = stream->samples[0].duration;
|
||||||
|
|
||||||
|
if ((stream->n_samples == 1 && first_duration == 0)
|
||||||
|
|| (qtdemux->fragmented && stream->n_samples_moof == 1)) {
|
||||||
|
/* still frame */
|
||||||
|
CUR_STREAM (stream)->fps_n = 0;
|
||||||
|
CUR_STREAM (stream)->fps_d = 1;
|
||||||
|
} else {
|
||||||
|
if (stream->duration == 0 || stream->n_samples < 2) {
|
||||||
|
CUR_STREAM (stream)->fps_n = stream->timescale;
|
||||||
|
CUR_STREAM (stream)->fps_d = 1;
|
||||||
|
fps_available = FALSE;
|
||||||
|
} else {
|
||||||
|
GstClockTime avg_duration;
|
||||||
|
guint64 duration;
|
||||||
|
guint32 n_samples;
|
||||||
|
|
||||||
|
/* duration and n_samples can be updated for fragmented format
|
||||||
|
* so, framerate of fragmented format is calculated using data in a moof */
|
||||||
|
if (qtdemux->fragmented && stream->n_samples_moof > 0
|
||||||
|
&& stream->duration_moof > 0) {
|
||||||
|
n_samples = stream->n_samples_moof;
|
||||||
|
duration = stream->duration_moof;
|
||||||
|
} else {
|
||||||
|
n_samples = stream->n_samples;
|
||||||
|
duration = stream->duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate a framerate, ignoring the first sample which is sometimes truncated */
|
||||||
|
/* stream->duration is guint64, timescale, n_samples are guint32 */
|
||||||
|
avg_duration =
|
||||||
|
gst_util_uint64_scale_round (duration -
|
||||||
|
first_duration, GST_SECOND,
|
||||||
|
(guint64) (stream->timescale) * (n_samples - 1));
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (qtdemux,
|
||||||
|
"Calculating avg sample duration based on stream (or moof) duration %"
|
||||||
|
G_GUINT64_FORMAT
|
||||||
|
" minus first sample %u, leaving %d samples gives %"
|
||||||
|
GST_TIME_FORMAT, duration, first_duration,
|
||||||
|
n_samples - 1, GST_TIME_ARGS (avg_duration));
|
||||||
|
|
||||||
|
gst_video_guess_framerate (avg_duration, &CUR_STREAM (stream)->fps_n,
|
||||||
|
&CUR_STREAM (stream)->fps_d);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (qtdemux,
|
||||||
|
"Calculating framerate, timescale %u gave fps_n %d fps_d %d",
|
||||||
|
stream->timescale, CUR_STREAM (stream)->fps_n,
|
||||||
|
CUR_STREAM (stream)->fps_d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fps_available;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_qtdemux_configure_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
|
gst_qtdemux_configure_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
|
||||||
{
|
{
|
||||||
if (stream->subtype == FOURCC_vide) {
|
if (stream->subtype == FOURCC_vide) {
|
||||||
/* fps is calculated base on the duration of the average framerate since
|
gboolean fps_available = gst_qtdemux_guess_framerate (qtdemux, stream);
|
||||||
* qt does not have a fixed framerate. */
|
|
||||||
gboolean fps_available = TRUE;
|
|
||||||
guint32 first_duration = 0;
|
|
||||||
|
|
||||||
if (stream->n_samples > 0)
|
|
||||||
first_duration = stream->samples[0].duration;
|
|
||||||
|
|
||||||
if ((stream->n_samples == 1 && first_duration == 0)
|
|
||||||
|| (qtdemux->fragmented && stream->n_samples_moof == 1)) {
|
|
||||||
/* still frame */
|
|
||||||
CUR_STREAM (stream)->fps_n = 0;
|
|
||||||
CUR_STREAM (stream)->fps_d = 1;
|
|
||||||
} else {
|
|
||||||
if (stream->duration == 0 || stream->n_samples < 2) {
|
|
||||||
CUR_STREAM (stream)->fps_n = stream->timescale;
|
|
||||||
CUR_STREAM (stream)->fps_d = 1;
|
|
||||||
fps_available = FALSE;
|
|
||||||
} else {
|
|
||||||
GstClockTime avg_duration;
|
|
||||||
guint64 duration;
|
|
||||||
guint32 n_samples;
|
|
||||||
|
|
||||||
/* duration and n_samples can be updated for fragmented format
|
|
||||||
* so, framerate of fragmented format is calculated using data in a moof */
|
|
||||||
if (qtdemux->fragmented && stream->n_samples_moof > 0
|
|
||||||
&& stream->duration_moof > 0) {
|
|
||||||
n_samples = stream->n_samples_moof;
|
|
||||||
duration = stream->duration_moof;
|
|
||||||
} else {
|
|
||||||
n_samples = stream->n_samples;
|
|
||||||
duration = stream->duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate a framerate, ignoring the first sample which is sometimes truncated */
|
|
||||||
/* stream->duration is guint64, timescale, n_samples are guint32 */
|
|
||||||
avg_duration =
|
|
||||||
gst_util_uint64_scale_round (duration -
|
|
||||||
first_duration, GST_SECOND,
|
|
||||||
(guint64) (stream->timescale) * (n_samples - 1));
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (qtdemux,
|
|
||||||
"Calculating avg sample duration based on stream (or moof) duration %"
|
|
||||||
G_GUINT64_FORMAT
|
|
||||||
" minus first sample %u, leaving %d samples gives %"
|
|
||||||
GST_TIME_FORMAT, duration, first_duration,
|
|
||||||
n_samples - 1, GST_TIME_ARGS (avg_duration));
|
|
||||||
|
|
||||||
gst_video_guess_framerate (avg_duration, &CUR_STREAM (stream)->fps_n,
|
|
||||||
&CUR_STREAM (stream)->fps_d);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (qtdemux,
|
|
||||||
"Calculating framerate, timescale %u gave fps_n %d fps_d %d",
|
|
||||||
stream->timescale, CUR_STREAM (stream)->fps_n,
|
|
||||||
CUR_STREAM (stream)->fps_d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CUR_STREAM (stream)->caps) {
|
if (CUR_STREAM (stream)->caps) {
|
||||||
CUR_STREAM (stream)->caps =
|
CUR_STREAM (stream)->caps =
|
||||||
|
@ -8509,6 +8517,22 @@ gst_qtdemux_configure_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (stream->subtype == FOURCC_clcp) {
|
||||||
|
gboolean fps_available = gst_qtdemux_guess_framerate (qtdemux, stream);
|
||||||
|
|
||||||
|
if (CUR_STREAM (stream)->caps) {
|
||||||
|
CUR_STREAM (stream)->caps =
|
||||||
|
gst_caps_make_writable (CUR_STREAM (stream)->caps);
|
||||||
|
|
||||||
|
/* set framerate if calculated framerate is reliable */
|
||||||
|
if (fps_available) {
|
||||||
|
gst_caps_set_simple (CUR_STREAM (stream)->caps,
|
||||||
|
"framerate", GST_TYPE_FRACTION, CUR_STREAM (stream)->fps_n,
|
||||||
|
CUR_STREAM (stream)->fps_d, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (stream->pad) {
|
if (stream->pad) {
|
||||||
GstCaps *prev_caps = NULL;
|
GstCaps *prev_caps = NULL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue