mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 05:22:30 +00:00
Write track and segment UIDs, write muxing date, write TRACKDEFAULTDURATION for TTA audio, write BLOCKDURATION if known.
Original commit message from CVS: Write track and segment UIDs, write muxing date, write TRACKDEFAULTDURATION for TTA audio, write BLOCKDURATION if known.
This commit is contained in:
parent
5488fa27bc
commit
e83fb2a3c2
6 changed files with 91 additions and 9 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2004-09-01 Arwed v. Merkatz <v.merkatz@gmx.net>
|
||||
|
||||
* gst/matroska/ebml-ids.h:
|
||||
* gst/matroska/ebml-read.c: (gst_ebml_read_date):
|
||||
* gst/matroska/ebml-write.c: (gst_ebml_write_date):
|
||||
automatically convert unix time <-> ebml time when reading/writing a date
|
||||
* gst/matroska/matroska-ids.h:
|
||||
* gst/matroska/matroska-mux.c: (gst_matroska_mux_create_uid),
|
||||
(gst_matroska_mux_reset), (gst_matroska_mux_audio_pad_link),
|
||||
(gst_matroska_mux_track_header), (gst_matroska_mux_start),
|
||||
(gst_matroska_mux_write_data):
|
||||
Write track and segment UIDs, write muxing date, write
|
||||
TRACKDEFAULTDURATION for TTA audio, write BLOCKDURATION if known.
|
||||
|
||||
2004-08-31 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* ext/alsa/gstalsamixer.c: (gst_alsa_mixer_build_list):
|
||||
|
|
|
@ -42,6 +42,9 @@ G_BEGIN_DECLS
|
|||
/* general EBML types */
|
||||
#define GST_EBML_ID_VOID 0xEC
|
||||
|
||||
/* EbmlDate offset from the unix epoch in seconds, 2001/01/01 00:00:00 UTC */
|
||||
#define GST_EBML_DATE_OFFSET 978307200
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_EBML_IDS_H__ */
|
||||
|
|
|
@ -591,13 +591,18 @@ gst_ebml_read_utf8 (GstEbmlRead * ebml, guint32 * id, gchar ** str)
|
|||
}
|
||||
|
||||
/*
|
||||
* Read the next element as a date (nanoseconds since 1/1/2000).
|
||||
* Read the next element as a date.
|
||||
* Returns the seconds since the unix epoch.
|
||||
*/
|
||||
|
||||
gboolean
|
||||
gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
|
||||
{
|
||||
return gst_ebml_read_sint (ebml, id, date);
|
||||
gint64 ebml_date;
|
||||
gboolean res = gst_ebml_read_sint (ebml, id, &ebml_date);
|
||||
|
||||
*date = (ebml_date / GST_SECOND) + GST_EBML_DATE_OFFSET;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -430,10 +430,11 @@ gst_ebml_write_utf8 (GstEbmlWrite * ebml, guint32 id, const gchar * str)
|
|||
gst_ebml_write_ascii (ebml, id, str);
|
||||
}
|
||||
|
||||
/* date should be in seconds since the unix epoch */
|
||||
void
|
||||
gst_ebml_write_date (GstEbmlWrite * ebml, guint32 id, gint64 date)
|
||||
{
|
||||
gst_ebml_write_sint (ebml, id, date);
|
||||
gst_ebml_write_sint (ebml, id, (date - GST_EBML_DATE_OFFSET) * GST_SECOND);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#define GST_MATROSKA_ID_WRITINGAPP 0x5741
|
||||
#define GST_MATROSKA_ID_MUXINGAPP 0x4D80
|
||||
#define GST_MATROSKA_ID_DATEUTC 0x4461
|
||||
#define GST_MATROSKA_ID_SEGMENTUID 0x73A4
|
||||
|
||||
/* ID in the tracks master */
|
||||
#define GST_MATROSKA_ID_TRACKENTRY 0xAE
|
||||
|
|
|
@ -114,6 +114,8 @@ GST_STATIC_PAD_TEMPLATE ("subtitle_%d",
|
|||
GST_PAD_REQUEST,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
static GArray *used_uids;
|
||||
|
||||
/* gobject magic foo */
|
||||
static void gst_matroska_mux_base_init (GstMatroskaMuxClass * klass);
|
||||
static void gst_matroska_mux_class_init (GstMatroskaMuxClass * klass);
|
||||
|
@ -139,6 +141,9 @@ static void gst_matroska_mux_get_property (GObject * object,
|
|||
/* reset muxer */
|
||||
static void gst_matroska_mux_reset (GstElement * element);
|
||||
|
||||
/* uid generation */
|
||||
static guint32 gst_matroska_mux_create_uid ();
|
||||
|
||||
static GstEbmlWriteClass *parent_class = NULL;
|
||||
|
||||
/*static guint gst_matroska_mux_signals[LAST_SIGNAL] = { 0 };*/
|
||||
|
@ -242,6 +247,28 @@ gst_matroska_mux_init (GstMatroskaMux * mux)
|
|||
gst_matroska_mux_reset (GST_ELEMENT (mux));
|
||||
}
|
||||
|
||||
static guint32
|
||||
gst_matroska_mux_create_uid ()
|
||||
{
|
||||
guint32 uid = 0;
|
||||
GRand *rand = g_rand_new ();
|
||||
|
||||
while (!uid) {
|
||||
guint i;
|
||||
|
||||
uid = g_rand_int (rand);
|
||||
for (i = 0; i < used_uids->len; i++) {
|
||||
if (g_array_index (used_uids, guint32, i) == uid) {
|
||||
uid = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_array_append_val (used_uids, uid);
|
||||
}
|
||||
g_free (rand);
|
||||
return uid;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_matroska_mux_reset (GstElement * element)
|
||||
{
|
||||
|
@ -289,6 +316,13 @@ gst_matroska_mux_reset (GstElement * element)
|
|||
/* reset timers */
|
||||
mux->time_scale = 1000000;
|
||||
mux->duration = 0;
|
||||
|
||||
/* reset uid array */
|
||||
if (used_uids) {
|
||||
g_free (used_uids);
|
||||
}
|
||||
/* arbitrary size, 10 should be enough in most cases */
|
||||
used_uids = g_array_sized_new (FALSE, FALSE, sizeof (guint32), 10);
|
||||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
|
@ -468,6 +502,7 @@ gst_matroska_mux_audio_pad_link (GstPad * pad, const GstCaps * caps)
|
|||
audiocontext->samplerate = samplerate;
|
||||
audiocontext->channels = channels;
|
||||
audiocontext->bitdepth = 0;
|
||||
context->default_duration = 0;
|
||||
|
||||
if (!strcmp (mimetype, "audio/mpeg")) {
|
||||
gint mpegversion = 0;
|
||||
|
@ -530,6 +565,9 @@ gst_matroska_mux_audio_pad_link (GstPad * pad, const GstCaps * caps)
|
|||
} else if (!strcmp (mimetype, "audio/x-raw-tta")) {
|
||||
gint width;
|
||||
|
||||
/* TTA frame duration */
|
||||
context->default_duration = 1.04489795918367346939 * GST_SECOND;
|
||||
|
||||
gst_structure_get_int (structure, "width", &width);
|
||||
audiocontext->bitdepth = width;
|
||||
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_TTA);
|
||||
|
@ -610,16 +648,19 @@ gst_matroska_mux_track_header (GstMatroskaMux * mux,
|
|||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKNUMBER, context->num);
|
||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKTYPE, context->type);
|
||||
|
||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKUID,
|
||||
gst_matroska_mux_create_uid ());
|
||||
if (context->default_duration) {
|
||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKDEFAULTDURATION,
|
||||
context->default_duration);
|
||||
}
|
||||
|
||||
/* type-specific stuff */
|
||||
switch (context->type) {
|
||||
case GST_MATROSKA_TRACK_TYPE_VIDEO:{
|
||||
GstMatroskaTrackVideoContext *videocontext =
|
||||
(GstMatroskaTrackVideoContext *) context;
|
||||
|
||||
/* framerate, but not in the video part */
|
||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKDEFAULTDURATION,
|
||||
context->default_duration);
|
||||
|
||||
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKVIDEO);
|
||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOPIXELWIDTH,
|
||||
videocontext->pixel_width);
|
||||
|
@ -697,6 +738,9 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
|
|||
gint i;
|
||||
guint tracknum = 1;
|
||||
gdouble duration = 0;
|
||||
guint32 *segment_uid = (guint32 *) g_malloc (16);
|
||||
GRand *rand = g_rand_new ();
|
||||
GTimeVal time = { 0, 0 };
|
||||
|
||||
/* we start with a EBML header */
|
||||
gst_ebml_write_header (ebml, "matroska", 1);
|
||||
|
@ -723,6 +767,12 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
|
|||
/* segment info */
|
||||
mux->info_pos = ebml->pos;
|
||||
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_INFO);
|
||||
for (i = 0; i < 4; i++) {
|
||||
segment_uid[i] = g_rand_int (rand);
|
||||
}
|
||||
g_free (rand);
|
||||
gst_ebml_write_binary (ebml, GST_MATROSKA_ID_SEGMENTUID,
|
||||
(guint8 *) segment_uid, 16);
|
||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TIMECODESCALE, mux->time_scale);
|
||||
mux->duration_pos = ebml->pos;
|
||||
/* get duration */
|
||||
|
@ -752,8 +802,8 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
|
|||
gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_WRITINGAPP, app);
|
||||
}
|
||||
}
|
||||
/* FIXME: how do I get this? Automatic? Via tags? */
|
||||
/*gst_ebml_write_date (ebml, GST_MATROSKA_ID_DATEUTC, 0); */
|
||||
g_get_current_time (&time);
|
||||
gst_ebml_write_date (ebml, GST_MATROSKA_ID_DATEUTC, time.tv_sec);
|
||||
gst_ebml_write_master_finish (ebml, master);
|
||||
|
||||
/* tracks */
|
||||
|
@ -956,6 +1006,14 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux)
|
|||
GST_BUFFER_DATA (hdr)[3] = 0;
|
||||
gst_ebml_write_buffer (ebml, hdr);
|
||||
gst_ebml_write_buffer (ebml, buf);
|
||||
if (GST_BUFFER_DURATION_IS_VALID (buf)) {
|
||||
guint64 block_duration = GST_BUFFER_DURATION (buf);
|
||||
|
||||
if (block_duration != mux->sink[i].track->default_duration) {
|
||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION,
|
||||
block_duration / mux->time_scale);
|
||||
}
|
||||
}
|
||||
gst_ebml_write_master_finish (ebml, blockgroup);
|
||||
gst_ebml_write_master_finish (ebml, cluster);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue