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:
Jan Schmidt 2008-03-03 22:01:56 +00:00
parent b7938d24ee
commit edda3b6c0f
5 changed files with 99 additions and 43 deletions

View file

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

@ -1 +1 @@
Subproject commit 668c3f0b72d50813c30eb04be7048f638037c571
Subproject commit 081a00a5e25d069b15bb7f6092c8f951462cd8eb

View file

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

View file

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

View file

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