mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 03:00:35 +00:00
gst/matroska/ebml-read.c: Use GINT64 formatting constants from GLIB.
Original commit message from CVS: * gst/matroska/ebml-read.c: Use GINT64 formatting constants from GLIB. * gst/matroska/matroska-demux.c: Add some guards to avoid a possible division by 0 and crashing with NULL events on some systems. Use gst_gdouble_to_guint64 somewhere instead of an implicit conversion. * gst/matroska/matroska-mux.c: Check for invalid timestamps in a bunch of places to avoid writing bogus durations into the output file. Fix some double<->gint64 conversions that weren't using gst_guint64_to_gdouble
This commit is contained in:
parent
b7938d24ee
commit
edda3b6c0f
5 changed files with 99 additions and 43 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2008-03-03 Jan Schmidt <jan.schmidt@sun.com>
|
||||
|
||||
* gst/matroska/ebml-read.c:
|
||||
Use GINT64 formatting constants from GLIB.
|
||||
|
||||
* gst/matroska/matroska-demux.c:
|
||||
Add some guards to avoid a possible division by 0 and crashing
|
||||
with NULL events on some systems.
|
||||
Use gst_gdouble_to_guint64 somewhere instead of an implicit
|
||||
conversion.
|
||||
|
||||
* gst/matroska/matroska-mux.c:
|
||||
Check for invalid timestamps in a bunch of places to avoid
|
||||
writing bogus durations into the output file.
|
||||
Fix some double<->gint64 conversions that weren't using
|
||||
gst_guint64_to_gdouble
|
||||
|
||||
2008-03-03 Peter Kjellerstedt <pkj@axis.com>
|
||||
|
||||
* configure.ac:
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit 668c3f0b72d50813c30eb04be7048f638037c571
|
||||
Subproject commit 081a00a5e25d069b15bb7f6092c8f951462cd8eb
|
|
@ -266,8 +266,8 @@ gst_ebml_read_element_id (GstEbmlRead * ebml, guint32 * id, guint * level_up)
|
|||
guint64 pos = ebml->offset;
|
||||
|
||||
GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
|
||||
("Invalid EBML ID size tag (0x%x) at position %llu (0x%llx)",
|
||||
(guint) b, pos, pos));
|
||||
("Invalid EBML ID size tag (0x%x) at position %" G_GUINT64_FORMAT
|
||||
" (0x%" G_GINT64_MODIFIER "x)", (guint) b, pos, pos));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -318,8 +318,8 @@ gst_ebml_read_element_length (GstEbmlRead * ebml, guint64 * length)
|
|||
guint64 pos = ebml->offset;
|
||||
|
||||
GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
|
||||
("Invalid EBML length size tag (0x%x) at position %llu (0x%llx)",
|
||||
(guint) b, pos, pos));
|
||||
("Invalid EBML length size tag (0x%x) at position %" G_GUINT64_FORMAT
|
||||
" (0x%" G_GINT64_MODIFIER "x)", (guint) b, pos, pos));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -498,7 +498,8 @@ gst_ebml_read_uint (GstEbmlRead * ebml, guint32 * id, guint64 * num)
|
|||
|
||||
if (size < 1 || size > 8) {
|
||||
GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
|
||||
("Invalid integer element size %d at position %llu (0x%llu)",
|
||||
("Invalid integer element size %d at position %" G_GUINT64_FORMAT
|
||||
" (0x%" G_GINT64_MODIFIER "x)",
|
||||
size, ebml->offset - size, ebml->offset - size));
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -528,8 +529,9 @@ gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
|
|||
|
||||
if (size < 1 || size > 8) {
|
||||
GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
|
||||
("Invalid integer element size %d at position %llu (0x%llx)",
|
||||
size, ebml->offset - size, ebml->offset - size));
|
||||
("Invalid integer element size %d at position %" G_GUINT64_FORMAT
|
||||
" (0x%" G_GINT64_MODIFIER "x)", size, ebml->offset - size,
|
||||
ebml->offset - size));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -570,8 +572,9 @@ gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
|
|||
|
||||
if (size != 4 && size != 8 && size != 10) {
|
||||
GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
|
||||
("Invalid float element size %d at position %llu (0x%llx)",
|
||||
size, ebml->offset - size, ebml->offset - size));
|
||||
("Invalid float element size %d at position %" G_GUINT64_FORMAT
|
||||
" (0x%" G_GINT64_MODIFIER "x)", size, ebml->offset - size,
|
||||
ebml->offset - size));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -660,9 +660,11 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
|
|||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
context->default_duration =
|
||||
gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
|
||||
videocontext->default_fps = num;
|
||||
if (num != 0.0) {
|
||||
context->default_duration =
|
||||
gst_gdouble_to_guint64 ((gdouble) GST_SECOND / num);
|
||||
videocontext->default_fps = num;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1298,6 +1300,8 @@ gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
|
|||
gboolean ret = TRUE;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
|
||||
GST_EVENT_TYPE_NAME (event));
|
||||
|
||||
|
@ -1324,6 +1328,8 @@ gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
|
|||
GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
|
||||
res = gst_matroska_demux_handle_seek_event (demux, event);
|
||||
} else {
|
||||
|
@ -1879,12 +1885,17 @@ gst_matroska_demux_parse_info (GstMatroskaDemux * demux)
|
|||
|
||||
case GST_MATROSKA_ID_DURATION:{
|
||||
gdouble num;
|
||||
GstClockTime dur;
|
||||
|
||||
if (!gst_ebml_read_float (ebml, &id, &num)) {
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
demux->duration = num * gst_guint64_to_gdouble (demux->time_scale);
|
||||
|
||||
dur = gst_gdouble_to_guint64 (num *
|
||||
gst_guint64_to_gdouble (demux->time_scale));
|
||||
if (GST_CLOCK_TIME_IS_VALID (dur) && dur <= G_MAXINT64)
|
||||
demux->duration = dur;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3712,7 +3723,7 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
|
|||
|
||||
g_value_init (&fps_double, G_TYPE_DOUBLE);
|
||||
g_value_init (&fps_fraction, GST_TYPE_FRACTION);
|
||||
g_value_set_double (&fps_double, (gdouble) GST_SECOND * 1.0 /
|
||||
g_value_set_double (&fps_double, (gdouble) GST_SECOND /
|
||||
gst_guint64_to_gdouble (context->default_duration));
|
||||
g_value_transform (&fps_double, &fps_fraction);
|
||||
|
||||
|
|
|
@ -1185,13 +1185,17 @@ gst_matroska_mux_release_pad (GstElement * element, GstPad * pad)
|
|||
if (cdata->pad == pad) {
|
||||
GstClockTime min_dur; /* observed minimum duration */
|
||||
|
||||
/* no need to check if start_ts and end_ts are set, in the worst case
|
||||
* they're both -1 and we'll end up with a duration of 0 again */
|
||||
min_dur = GST_CLOCK_DIFF (collect_pad->start_ts, collect_pad->end_ts);
|
||||
if (collect_pad->duration < min_dur)
|
||||
collect_pad->duration = min_dur;
|
||||
if (collect_pad->duration > mux->duration)
|
||||
if (GST_CLOCK_TIME_IS_VALID (collect_pad->start_ts) &&
|
||||
GST_CLOCK_TIME_IS_VALID (collect_pad->end_ts)) {
|
||||
min_dur = GST_CLOCK_DIFF (collect_pad->start_ts, collect_pad->end_ts);
|
||||
if (collect_pad->duration < min_dur)
|
||||
collect_pad->duration = min_dur;
|
||||
}
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (collect_pad->duration) &&
|
||||
mux->duration < collect_pad->duration)
|
||||
mux->duration = collect_pad->duration;
|
||||
|
||||
gst_matroska_pad_free (collect_pad);
|
||||
gst_collect_pads_remove_pad (mux->collect, pad);
|
||||
gst_element_remove_pad (element, pad);
|
||||
|
@ -1321,7 +1325,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
|
|||
GSList *collected;
|
||||
int i;
|
||||
guint tracknum = 1;
|
||||
gdouble duration = 0;
|
||||
GstClockTime duration = 0;
|
||||
guint32 *segment_uid = (guint32 *) g_malloc (16);
|
||||
GRand *rand = g_rand_new ();
|
||||
GTimeVal time = { 0, 0 };
|
||||
|
@ -1376,14 +1380,15 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
|
|||
if (gst_pad_query_peer_duration (thepad, &format, &trackduration)) {
|
||||
GST_DEBUG_OBJECT (thepad, "duration: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (trackduration));
|
||||
if (trackduration != GST_CLOCK_TIME_NONE &&
|
||||
(gdouble) trackduration > duration) {
|
||||
duration = (gdouble) trackduration;
|
||||
if (trackduration != GST_CLOCK_TIME_NONE && trackduration > duration) {
|
||||
duration = (GstClockTime) trackduration;
|
||||
}
|
||||
}
|
||||
}
|
||||
gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
|
||||
duration / gst_guint64_to_gdouble (mux->time_scale));
|
||||
gst_guint64_to_gdouble (duration) /
|
||||
gst_guint64_to_gdouble (mux->time_scale));
|
||||
|
||||
gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_MUXINGAPP,
|
||||
"GStreamer plugin version " PACKAGE_VERSION);
|
||||
if (mux->writing_app && mux->writing_app[0]) {
|
||||
|
@ -1617,14 +1622,23 @@ gst_matroska_mux_finish (GstMatroskaMux * mux)
|
|||
|
||||
collect_pad = (GstMatroskaPad *) collected->data;
|
||||
|
||||
/* no need to check if start_ts and end_ts are set, in the worst case
|
||||
* they're both -1 and we'll end up with a duration of 0 again */
|
||||
min_duration = GST_CLOCK_DIFF (collect_pad->start_ts, collect_pad->end_ts);
|
||||
if (collect_pad->duration < min_duration)
|
||||
collect_pad->duration = min_duration;
|
||||
GST_DEBUG_OBJECT (collect_pad, "final track duration: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (collect_pad->duration));
|
||||
if (collect_pad->duration > duration)
|
||||
GST_DEBUG_OBJECT (mux, "Pad %" GST_PTR_FORMAT " start ts %" GST_TIME_FORMAT
|
||||
" end ts %" GST_TIME_FORMAT, collect_pad,
|
||||
GST_TIME_ARGS (collect_pad->start_ts),
|
||||
GST_TIME_ARGS (collect_pad->end_ts));
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (collect_pad->start_ts) &&
|
||||
GST_CLOCK_TIME_IS_VALID (collect_pad->end_ts)) {
|
||||
min_duration =
|
||||
GST_CLOCK_DIFF (collect_pad->start_ts, collect_pad->end_ts);
|
||||
if (collect_pad->duration < min_duration)
|
||||
collect_pad->duration = min_duration;
|
||||
GST_DEBUG_OBJECT (collect_pad, "final track duration: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (collect_pad->duration));
|
||||
}
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (collect_pad->duration) &&
|
||||
duration < collect_pad->duration)
|
||||
duration = collect_pad->duration;
|
||||
}
|
||||
if (duration != 0) {
|
||||
|
@ -1633,7 +1647,8 @@ gst_matroska_mux_finish (GstMatroskaMux * mux)
|
|||
pos = mux->ebml_write->pos;
|
||||
gst_ebml_write_seek (ebml, mux->duration_pos);
|
||||
gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
|
||||
gst_guint64_to_gdouble (duration / mux->time_scale));
|
||||
gst_guint64_to_gdouble (duration) /
|
||||
gst_guint64_to_gdouble (mux->time_scale));
|
||||
gst_ebml_write_seek (ebml, pos);
|
||||
}
|
||||
|
||||
|
@ -1941,18 +1956,28 @@ gst_matroska_mux_collected (GstCollectPads * pads, gpointer user_data)
|
|||
ret = GST_FLOW_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
GST_DEBUG_OBJECT (best->collect.pad, "best pad");
|
||||
GST_DEBUG_OBJECT (best->collect.pad, "best pad - buffer ts %"
|
||||
GST_TIME_FORMAT " dur %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (best->buffer)),
|
||||
GST_TIME_ARGS (GST_BUFFER_DURATION (best->buffer)));
|
||||
|
||||
/* make note of first and last encountered timestamps, so we can calculate
|
||||
* the actual duration later when we send an updated header on eos */
|
||||
best->end_ts = GST_BUFFER_TIMESTAMP (best->buffer);
|
||||
if (GST_BUFFER_DURATION_IS_VALID (best->buffer))
|
||||
best->end_ts += GST_BUFFER_DURATION (best->buffer);
|
||||
else if (best->track->default_duration)
|
||||
best->end_ts += best->track->default_duration;
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (best->buffer)) {
|
||||
GstClockTime start_ts = GST_BUFFER_TIMESTAMP (best->buffer);
|
||||
GstClockTime end_ts = start_ts;
|
||||
|
||||
if (G_UNLIKELY (best->start_ts == GST_CLOCK_TIME_NONE)) {
|
||||
best->start_ts = GST_BUFFER_TIMESTAMP (best->buffer);
|
||||
if (GST_BUFFER_DURATION_IS_VALID (best->buffer))
|
||||
end_ts += GST_BUFFER_DURATION (best->buffer);
|
||||
else if (best->track->default_duration)
|
||||
end_ts += best->track->default_duration;
|
||||
|
||||
if (end_ts > best->end_ts)
|
||||
best->end_ts = end_ts;
|
||||
|
||||
if (G_UNLIKELY (best->start_ts == GST_CLOCK_TIME_NONE ||
|
||||
start_ts < best->start_ts))
|
||||
best->start_ts = start_ts;
|
||||
}
|
||||
|
||||
/* write one buffer */
|
||||
|
|
Loading…
Reference in a new issue