gstreamer/gst/matroska/matroska-mux.c

996 lines
31 KiB
C
Raw Normal View History

Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
/* GStreamer Matroska muxer/demuxer
* (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
*
* matroska-mux.c: matroska file/stream muxer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <string.h>
#include "matroska-mux.h"
#include "matroska-ids.h"
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_METADATA,
/* FILL ME */
};
static GstStaticPadTemplate src_templ =
GST_STATIC_PAD_TEMPLATE (
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-matroska")
);
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
#define COMMON_VIDEO_CAPS \
"width = (int) [ 16, 4096 ], " \
"height = (int) [ 16, 4096 ], " \
"framerate = (double) [ 0, MAX ]"
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
static GstStaticPadTemplate videosink_templ =
GST_STATIC_PAD_TEMPLATE (
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
"video_%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS (
"video/mpeg, "
"mpegversion = (int) { 1, 2, 4 }, "
"systemstream = (boolean) false, "
COMMON_VIDEO_CAPS "; "
"video/x-divx, "
COMMON_VIDEO_CAPS "; "
"video/x-xvid, "
COMMON_VIDEO_CAPS "; "
"video/x-msmpeg, "
COMMON_VIDEO_CAPS "; "
"video/x-jpeg, "
COMMON_VIDEO_CAPS "; "
"video/x-raw-yuv, "
"format = (fourcc) { YUY2, I420 }, "
COMMON_VIDEO_CAPS
)
);
#define COMMON_AUDIO_CAPS \
"channels = (int) [ 1, 8 ], " \
"rate = (int) [ 8000, 96000 ]"
configure.ac: Improve mpeg2enc detection. This is for distributions that do ship mjpegtools, but without mpeg2enc. Al... Original commit message from CVS: 2003-12-21 Ronald Bultje <rbultje@ronald.bitfreak.net> * configure.ac: Improve mpeg2enc detection. This is for distributions that do ship mjpegtools, but without mpeg2enc. Also does object check for might there ever be ABI incompatibility. * ext/mpeg2enc/gstmpeg2enc.cc: Add Andrew as second maintainer (he's helping me), and also add an error if no caps was set. This happens if I pull before capsnego and that's something I should solve sometime else. * gst/matroska/matroska-demux.c: (gst_matroska_demux_parse_blockgroup): Fix time parsing. * gst/matroska/matroska-mux.c: (gst_matroska_mux_audio_pad_link), (gst_matroska_mux_track_header): Add caps to templates. * gst/mpegaudioparse/gstmpegaudioparse.c: (mp3_sink_factory): Add mpegversion=1 to prevent confusion with MPEG/AAC. * gst/mpegstream/gstmpegdemux.c: Remove layer since it causes warnings about unfixed caps. * gst/videotestsrc/gstvideotestsrc.c: (gst_videotestsrc_get): Fix obvious typo (we error out if caps were set, we should of course error out if *no* caps were set). * sys/oss/gstosselement.c: (gst_osselement_convert): Fix format conversion, we confused bits/bytes. * sys/oss/gstosselement.h: Improve documentation for 'bps'. * sys/v4l/TODO: Remove stuff about plugins that need removing - this was done ages ago. * sys/v4l/gstv4lmjpegsrc.c: (gst_v4lmjpegsrc_init), (gst_v4lmjpegsrc_src_convert), (gst_v4lmjpegsrc_src_query): * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_init), (gst_v4lsrc_src_convert), (gst_v4lsrc_src_query): * sys/v4l2/gstv4l2src.c: (gst_v4l2src_init), (gst_v4l2src_src_convert), (gst_v4l2src_src_query): Add get_query_types(), get_formats() and query() functions.
2003-12-21 18:44:34 +00:00
/* FIXME:
* * audio/x-raw-float: endianness needs defining.
* * audio/x-vorbis: private data setup needs work.
*/
static GstStaticPadTemplate audiosink_templ =
GST_STATIC_PAD_TEMPLATE (
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
"audio_%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS (
"audio/mpeg, "
"mpegversion = (int) 1, "
"layer = (int) [ 1, 3 ], "
COMMON_AUDIO_CAPS "; "
"audio/mpeg, "
"mpegversion = (int) { 2, 4 }, "
COMMON_AUDIO_CAPS "; "
"audio/x-ac3, "
COMMON_AUDIO_CAPS "; "
"audio/x-raw-int, "
"width = (int) { 8, 16, 24 }, "
"depth = (int) { 8, 16, 24 }, "
"endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, "
"signed = (boolean) { true, false }, "
COMMON_AUDIO_CAPS
)
);
static GstStaticPadTemplate subtitlesink_templ =
GST_STATIC_PAD_TEMPLATE (
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
"subtitle_%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY
);
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
/* gobject magic foo */
static void gst_matroska_mux_base_init (GstMatroskaMuxClass *klass);
static void gst_matroska_mux_class_init (GstMatroskaMuxClass *klass);
static void gst_matroska_mux_init (GstMatroskaMux *mux);
/* element functions */
static void gst_matroska_mux_loop (GstElement *element);
/* pad functions */
static GstPad * gst_matroska_mux_request_new_pad (GstElement *element,
GstPadTemplate *templ,
const gchar *name);
/* gst internal change state handler */
static GstElementStateReturn
gst_matroska_mux_change_state (GstElement *element);
/* gobject bla bla */
static void gst_matroska_mux_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gst_matroska_mux_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
/* reset muxer */
static void gst_matroska_mux_reset (GstElement *element);
static GstEbmlWriteClass *parent_class = NULL;
/*static guint gst_matroska_mux_signals[LAST_SIGNAL] = { 0 };*/
GType
gst_matroska_mux_get_type (void)
{
static GType gst_matroska_mux_type = 0;
if (!gst_matroska_mux_type) {
static const GTypeInfo gst_matroska_mux_info = {
sizeof (GstMatroskaMuxClass),
(GBaseInitFunc) gst_matroska_mux_base_init,
NULL,
(GClassInitFunc) gst_matroska_mux_class_init,
NULL,
NULL,
sizeof (GstMatroskaMux),
0,
(GInstanceInitFunc) gst_matroska_mux_init,
};
gst_matroska_mux_type =
g_type_register_static (GST_TYPE_EBML_WRITE,
"GstMatroskaMmux",
&gst_matroska_mux_info, 0);
}
return gst_matroska_mux_type;
}
static void
gst_matroska_mux_base_init (GstMatroskaMuxClass *klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
static GstElementDetails gst_matroska_mux_details = {
"Matroska muxer",
"Codec/Muxer",
"Muxes video/audio/subtitle streams into a matroska stream",
"Ronald Bultje <rbultje@ronald.bitfreak.net>"
};
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&videosink_templ));
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&audiosink_templ));
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&subtitlesink_templ));
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_templ));
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
gst_element_class_set_details (element_class,
&gst_matroska_mux_details);
}
static void
gst_matroska_mux_class_init (GstMatroskaMuxClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
g_object_class_install_property (gobject_class, ARG_METADATA,
g_param_spec_boxed ("metadata", "Metadata", "Metadata",
GST_TYPE_CAPS, G_PARAM_READWRITE));
parent_class = g_type_class_ref (GST_TYPE_EBML_WRITE);
gobject_class->get_property = gst_matroska_mux_get_property;
gobject_class->set_property = gst_matroska_mux_set_property;
gstelement_class->change_state = gst_matroska_mux_change_state;
gstelement_class->request_new_pad = gst_matroska_mux_request_new_pad;
}
static void
gst_matroska_mux_init (GstMatroskaMux *mux)
{
GstElementClass *klass = GST_ELEMENT_GET_CLASS (mux);
gint i;
mux->srcpad = gst_pad_new_from_template (
gst_element_class_get_pad_template (klass, "src"), "src");
gst_element_add_pad (GST_ELEMENT (mux), mux->srcpad);
GST_EBML_WRITE (mux)->srcpad = mux->srcpad;
gst_element_set_loop_function (GST_ELEMENT (mux),
gst_matroska_mux_loop);
/* initial stream no. */
for (i = 0; i < GST_MATROSKA_MUX_MAX_STREAMS; i++) {
mux->sink[i].buffer = NULL;
mux->sink[i].track = NULL;
}
mux->index = NULL;
/* finish off */
gst_matroska_mux_reset (GST_ELEMENT (mux));
}
static void
gst_matroska_mux_reset (GstElement *element)
{
GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
guint i;
/* reset input */
mux->state = GST_MATROSKA_MUX_STATE_START;
/* clean up existing streams */
for (i = 0; i < GST_MATROSKA_MUX_MAX_STREAMS; i++) {
if (mux->sink[i].track != NULL) {
if (mux->sink[i].track->pad != NULL) {
gst_element_remove_pad (GST_ELEMENT (mux), mux->sink[i].track->pad);
}
g_free (mux->sink[i].track->codec_id);
g_free (mux->sink[i].track->codec_name);
g_free (mux->sink[i].track->name);
g_free (mux->sink[i].track->language);
g_free (mux->sink[i].track->codec_priv);
g_free (mux->sink[i].track);
mux->sink[i].track = NULL;
}
if (mux->sink[i].buffer != NULL) {
gst_buffer_unref (mux->sink[i].buffer);
mux->sink[i].buffer = NULL;
}
mux->sink[i].eos = FALSE;
}
mux->num_streams = 0;
mux->num_a_streams = 0;
mux->num_t_streams = 0;
mux->num_v_streams = 0;
/* reset media info (to default) */
gst_caps_replace (&mux->metadata,
gst_caps_new_simple ("application/x-gst-metadata",
"application", G_TYPE_STRING, "",
"date", G_TYPE_STRING, "", NULL));
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
/* reset indexes */
mux->num_indexes = 0;
g_free (mux->index);
mux->index = NULL;
/* reset timers */
mux->time_scale = 1000000;
mux->duration = 0;
}
static GstPadLinkReturn
gst_matroska_mux_video_pad_link (GstPad *pad, const GstCaps *caps)
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
{
GstMatroskaTrackContext *context = NULL;
GstMatroskaTrackVideoContext *videocontext;
GstMatroskaMux *mux = GST_MATROSKA_MUX (gst_pad_get_parent (pad));
const gchar *mimetype;
gint width, height, pixel_width, pixel_height, i;
gdouble framerate;
GstStructure *structure;
gboolean ret;
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
/* find context */
for (i = 0; i < mux->num_streams; i++) {
if (mux->sink[i].track && mux->sink[i].track->pad &&
mux->sink[i].track->pad == pad) {
context = mux->sink[i].track;
break;
}
}
g_assert (i < mux->num_streams);
g_assert (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO);
videocontext = (GstMatroskaTrackVideoContext *) context;
/* gst -> matroska ID'ing */
structure = gst_caps_get_structure (caps, 0);
mimetype = gst_structure_get_name (structure);
/* get general properties */
gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "height", &height);
gst_structure_get_double (structure, "framerate", &framerate);
videocontext->pixel_width = width;
videocontext->pixel_height = height;
context->default_duration = GST_SECOND / framerate;
ret = gst_structure_get_int (structure, "pixel_width", &pixel_width);
ret &= gst_structure_get_int (structure, "pixel_height", &pixel_height);
if (ret) {
if (pixel_width > pixel_height) {
videocontext->display_width = width * pixel_width / pixel_height;
videocontext->display_height = height;
} else if (pixel_width < pixel_height) {
videocontext->display_width = width;
videocontext->display_height = height * pixel_height / pixel_width;
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
} else {
videocontext->display_width = 0;
videocontext->display_height = 0;
}
} else {
videocontext->display_width = 0;
videocontext->display_height = 0;
}
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
videocontext->asr_mode = GST_MATROSKA_ASPECT_RATIO_MODE_FREE;
videocontext->eye_mode = GST_MATROSKA_EYE_MODE_MONO;
videocontext->fourcc = 0;
/* find type */
if (!strcmp (mimetype, "video/x-raw-yuv")) {
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED);
gst_structure_get_fourcc (structure, "format", &videocontext->fourcc);
return GST_PAD_LINK_OK;
} else if (!strcmp (mimetype, "video/x-jpeg")) {
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MJPEG);
return GST_PAD_LINK_OK;
} else if (!strcmp (mimetype, "video/x-divx")) {
gint divxversion;
gst_structure_get_int (structure, "divxversion", &divxversion);
switch (divxversion) {
case 3:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3);
break;
case 4:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP);
break;
case 5:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP);
break;
}
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
return GST_PAD_LINK_OK;
} else if (!strcmp (mimetype, "video/x-xvid")) {
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP);
return GST_PAD_LINK_OK;
} else if (!strcmp (mimetype, "video/mpeg")) {
gint mpegversion;
gst_structure_get_int (structure, "mpegversion", &mpegversion);
switch (mpegversion) {
case 1:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MPEG1);
break;
case 2:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MPEG2);
break;
case 3:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP);
break;
}
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
return GST_PAD_LINK_OK;
} else if (!strcmp (mimetype, "video/x-msmpeg")) {
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3);
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
return GST_PAD_LINK_OK;
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
}
return GST_PAD_LINK_REFUSED;
}
static GstPadLinkReturn
gst_matroska_mux_audio_pad_link (GstPad *pad,
const GstCaps *caps)
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
{
GstMatroskaTrackContext *context = NULL;
GstMatroskaTrackAudioContext *audiocontext;
GstMatroskaMux *mux = GST_MATROSKA_MUX (gst_pad_get_parent (pad));
const gchar *mimetype;
gint samplerate, channels, i;
GstStructure *structure;
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
/* find context */
for (i = 0; i < mux->num_streams; i++) {
if (mux->sink[i].track && mux->sink[i].track->pad &&
mux->sink[i].track->pad == pad) {
context = mux->sink[i].track;
break;
}
}
g_assert (i < mux->num_streams);
g_assert (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO);
audiocontext = (GstMatroskaTrackAudioContext *) context;
structure = gst_caps_get_structure (caps, 0);
mimetype = gst_structure_get_name (structure);
/* general setup */
gst_structure_get_int (structure, "rate", &samplerate);
gst_structure_get_int (structure, "channels", &channels);
audiocontext->samplerate = samplerate;
audiocontext->channels = channels;
audiocontext->bitdepth = 0;
if (!strcmp (mimetype, "audio/mpeg")) {
gint mpegversion = 0;
gst_structure_get_int (structure, "mpegversion", &mpegversion);
switch (mpegversion) {
case 1: {
gint layer;
gst_structure_get_int (structure, "layer", &layer);
switch (layer) {
case 1:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1);
break;
case 2:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2);
break;
case 3:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3);
break;
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
}
break;
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
}
case 2:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_MPEG2
"MAIN");
break;
case 4:
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_MPEG4
"MAIN");
break;
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
}
return GST_PAD_LINK_OK;
} else if (!strcmp (mimetype, "audio/x-raw-int")) {
gint endianness, width, depth;
gboolean signedness;
gst_structure_get_int (structure, "endianness", &endianness);
gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "depth", &depth);
gst_structure_get_int (structure, "signed", &signedness);
if (width != depth ||
(width == 8 && signedness) || (width == 16 && !signedness))
return GST_PAD_LINK_REFUSED;
audiocontext->bitdepth = depth;
if (endianness == G_BIG_ENDIAN)
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE);
else
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE);
return GST_PAD_LINK_OK;
} else if (!strcmp (mimetype, "audio/x-raw-float")) {
/* FIXME: endianness is undefined */
} else if (!strcmp (mimetype, "audio/x-vorbis")) {
/* FIXME: private data setup needs work */
} else if (!strcmp (mimetype, "audio/x-ac3")) {
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_AC3);
return GST_PAD_LINK_OK;
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
}
return GST_PAD_LINK_REFUSED;
}
static GstPadLinkReturn
gst_matroska_mux_subtitle_pad_link (GstPad *pad,
const GstCaps *caps)
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
{
/* Consider this as boilerplate code for now. There is
* no single subtitle creation element in GStreamer,
* neither do I know how subtitling works at all. */
return GST_PAD_LINK_REFUSED;
}
static GstPad *
gst_matroska_mux_request_new_pad (GstElement *element,
GstPadTemplate *templ,
const gchar *pad_name)
{
GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
GstPad *pad = NULL;
gchar *name = NULL;
GstPadLinkFunction linkfunc = NULL;
GstMatroskaTrackContext *context = NULL;
if (templ == gst_element_class_get_pad_template (klass, "audio_%d")) {
name = g_strdup_printf ("audio_%d", mux->num_a_streams++);
linkfunc = gst_matroska_mux_audio_pad_link;
context = (GstMatroskaTrackContext *)
g_new0 (GstMatroskaTrackAudioContext, 1);
context->type = GST_MATROSKA_TRACK_TYPE_AUDIO;
context->name = g_strdup ("Audio");
} else if (templ == gst_element_class_get_pad_template (klass, "video_%d")) {
name = g_strdup_printf ("video_%d", mux->num_v_streams++);
linkfunc = gst_matroska_mux_video_pad_link;
context = (GstMatroskaTrackContext *)
g_new0 (GstMatroskaTrackVideoContext, 1);
context->type = GST_MATROSKA_TRACK_TYPE_VIDEO;
context->name = g_strdup ("Video");
} else if (templ == gst_element_class_get_pad_template (klass, "subtitle_%d")) {
name = g_strdup_printf ("subtitle_%d", mux->num_t_streams++);
linkfunc = gst_matroska_mux_subtitle_pad_link;
context = (GstMatroskaTrackContext *)
g_new0 (GstMatroskaTrackSubtitleContext, 1);
context->type = GST_MATROSKA_TRACK_TYPE_SUBTITLE;
context->name = g_strdup ("Subtitle");
} else {
g_warning ("matroskamux: this is not our template!");
return NULL;
}
pad = gst_pad_new_from_template (templ, name);
g_free (name);
gst_element_add_pad (element, pad);
gst_pad_set_link_function (pad, linkfunc);
context->index = mux->num_streams++;
mux->sink[context->index].track = context;
context->pad = pad;
context->flags = GST_MATROSKA_TRACK_ENABLED |
GST_MATROSKA_TRACK_DEFAULT;
return pad;
}
static void
gst_matroska_mux_track_header (GstMatroskaMux *mux,
GstMatroskaTrackContext *context)
{
GstEbmlWrite *ebml = GST_EBML_WRITE (mux);
guint64 master;
/* track type goes before the type-specific stuff */
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKNUMBER, context->num);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKTYPE, context->type);
/* 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);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOPIXELHEIGHT,
videocontext->pixel_height);
if (videocontext->display_width && videocontext->display_height) {
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEODISPLAYWIDTH,
videocontext->display_width);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEODISPLAYHEIGHT,
videocontext->display_height);
}
if (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 1);
if (videocontext->fourcc) {
guint32 fcc_le = GUINT32_TO_LE (videocontext->fourcc);
gst_ebml_write_binary (ebml, GST_MATROSKA_ID_VIDEOCOLOURSPACE,
(gpointer) &fcc_le, 4);
}
gst_ebml_write_master_finish (ebml, master);
break;
}
case GST_MATROSKA_TRACK_TYPE_AUDIO: {
GstMatroskaTrackAudioContext *audiocontext =
(GstMatroskaTrackAudioContext *) context;
master = gst_ebml_write_master_start (ebml,
GST_MATROSKA_ID_TRACKAUDIO);
if (audiocontext->samplerate != 8000)
gst_ebml_write_float (ebml, GST_MATROSKA_ID_AUDIOSAMPLINGFREQ,
audiocontext->samplerate);
if (audiocontext->channels != 1)
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_AUDIOCHANNELS,
audiocontext->channels);
configure.ac: Improve mpeg2enc detection. This is for distributions that do ship mjpegtools, but without mpeg2enc. Al... Original commit message from CVS: 2003-12-21 Ronald Bultje <rbultje@ronald.bitfreak.net> * configure.ac: Improve mpeg2enc detection. This is for distributions that do ship mjpegtools, but without mpeg2enc. Also does object check for might there ever be ABI incompatibility. * ext/mpeg2enc/gstmpeg2enc.cc: Add Andrew as second maintainer (he's helping me), and also add an error if no caps was set. This happens if I pull before capsnego and that's something I should solve sometime else. * gst/matroska/matroska-demux.c: (gst_matroska_demux_parse_blockgroup): Fix time parsing. * gst/matroska/matroska-mux.c: (gst_matroska_mux_audio_pad_link), (gst_matroska_mux_track_header): Add caps to templates. * gst/mpegaudioparse/gstmpegaudioparse.c: (mp3_sink_factory): Add mpegversion=1 to prevent confusion with MPEG/AAC. * gst/mpegstream/gstmpegdemux.c: Remove layer since it causes warnings about unfixed caps. * gst/videotestsrc/gstvideotestsrc.c: (gst_videotestsrc_get): Fix obvious typo (we error out if caps were set, we should of course error out if *no* caps were set). * sys/oss/gstosselement.c: (gst_osselement_convert): Fix format conversion, we confused bits/bytes. * sys/oss/gstosselement.h: Improve documentation for 'bps'. * sys/v4l/TODO: Remove stuff about plugins that need removing - this was done ages ago. * sys/v4l/gstv4lmjpegsrc.c: (gst_v4lmjpegsrc_init), (gst_v4lmjpegsrc_src_convert), (gst_v4lmjpegsrc_src_query): * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_init), (gst_v4lsrc_src_convert), (gst_v4lsrc_src_query): * sys/v4l2/gstv4l2src.c: (gst_v4l2src_init), (gst_v4l2src_src_convert), (gst_v4l2src_src_query): Add get_query_types(), get_formats() and query() functions.
2003-12-21 18:44:34 +00:00
if (audiocontext->bitdepth) {
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_AUDIOBITDEPTH,
audiocontext->bitdepth);
}
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
gst_ebml_write_master_finish (ebml, master);
break;
}
default:
/* doesn't need type-specific data */
break;
}
gst_ebml_write_ascii (ebml, GST_MATROSKA_ID_CODECID,
context->codec_id);
if (context->codec_priv)
gst_ebml_write_binary (ebml, GST_MATROSKA_ID_CODECPRIVATE,
context->codec_priv, context->codec_priv_size);
/* FIXME: until we have a nice way of getting the codecname
* out of the caps, I'm not going to enable this. Too much
* (useless, double, boring) work... */
/*gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_CODECNAME,
context->codec_name);*/
gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_TRACKNAME,
context->name);
}
static void
gst_matroska_mux_start (GstMatroskaMux *mux)
{
GstEbmlWrite *ebml = GST_EBML_WRITE (mux);
guint32 seekhead_id[] = { GST_MATROSKA_ID_INFO,
GST_MATROSKA_ID_TRACKS,
GST_MATROSKA_ID_CUES,
#if 0
GST_MATROSKA_ID_TAGS,
#endif
0 };
guint64 master, child;
gint i;
guint tracknum = 1;
/* we start with a EBML header */
gst_ebml_write_header (ebml, "matroska", 1);
/* start a segment */
mux->segment_pos = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEGMENT);
mux->segment_master = ebml->pos;
/* the rest of the header is cached */
gst_ebml_write_set_cache (ebml, 0x1000);
/* seekhead (table of contents) - we set the positions later */
mux->seekhead_pos = ebml->pos;
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKHEAD);
for (i = 0; seekhead_id[i] != 0; i++) {
child = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKENTRY);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKID, seekhead_id[i]);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKPOSITION, -1);
gst_ebml_write_master_finish (ebml, child);
}
gst_ebml_write_master_finish (ebml, master);
/* segment info */
mux->info_pos = ebml->pos;
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_INFO);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TIMECODESCALE, mux->time_scale);
mux->duration_pos = ebml->pos;
gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION, 0);
gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_MUXINGAPP, "GStreamer");
if (mux->metadata &&
gst_structure_has_field (gst_caps_get_structure(mux->metadata,0),
"application")) {
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
const gchar *app;
app = gst_structure_get_string (gst_caps_get_structure(mux->metadata, 0),
"application");
Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first b... Original commit message from CVS: Riff, EBML, fourcc etc. work. Not fully finished, but better than what we used to have and definately worth a first broad testing. I've revived rifflib. Rifflib used to be a bytestream-for-riff, which just dup'ed bytestream. I've rewritten rifflib to be a modern riff- chunk parser that uses bytestream fully, plus adds some extra functions so that riff file parsing becomes extremely easy. It also contains some small usability functions for strh/strf and metadata parsing. Note that it doesn't use the new tagging yet, that's a TODO. Avidemux has been rewritten to use this. I think we all agreed that avidemux was pretty much a big mess, which is because it used all sort of bytestream magic all around the place. It was just ugly. This is a lot nicer, very complete and safe. I think this is far more robust than what the old avidemux could ever have been. Of course, it might contain bugs, please let me know. EBML writing has also been implemented. This is useful for matroska. I'm intending to modify avidemux (with a riffwriter) similarly. Maybe I'll change wavparse/-enc too to use rifflib. Lastly, several plugins have been modified to use rifflib's fourcc parsing instead of their own. this puts fourcc parsing in one central place, which should make it a lot simpler to add new fourccs. We might want to move this to its own lib instead of rifflib. Enjoy!
2003-12-07 20:00:41 +00:00
if (app && app[0]) {
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);*/
gst_ebml_write_master_finish (ebml, master);
/* tracks */
mux->tracks_pos = ebml->pos;
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKS);
for (i = 0; i < mux->num_streams; i++) {
if (GST_PAD_IS_USABLE (mux->sink[i].track->pad)) {
mux->sink[i].track->num = tracknum++;
child = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKENTRY);
gst_matroska_mux_track_header (mux, mux->sink[i].track);
gst_ebml_write_master_finish (ebml, child);
}
}
gst_ebml_write_master_finish (ebml, master);
/* lastly, flush the cache */
gst_ebml_write_flush_cache (ebml);
}
static void
gst_matroska_mux_finish (GstMatroskaMux *mux)
{
GstEbmlWrite *ebml = GST_EBML_WRITE (mux);
guint64 pos;
/* cues */
if (mux->index != NULL) {
guint n;
guint64 master, pointentry_master, trackpos_master;
mux->cues_pos = ebml->pos;
gst_ebml_write_set_cache (ebml, 12 + 41 * mux->num_indexes);
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CUES);
for (n = 0; n < mux->num_indexes; n++) {
GstMatroskaIndex *idx = &mux->index[n];
pointentry_master = gst_ebml_write_master_start (ebml,
GST_MATROSKA_ID_POINTENTRY);
gst_ebml_write_date (ebml, GST_MATROSKA_ID_CUETIME,
idx->time / mux->time_scale);
trackpos_master = gst_ebml_write_master_start (ebml,
GST_MATROSKA_ID_CUETRACKPOSITION);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CUETRACK, idx->track);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CUECLUSTERPOSITION,
idx->pos - mux->segment_master);
gst_ebml_write_master_finish (ebml, trackpos_master);
gst_ebml_write_master_finish (ebml, pointentry_master);
}
gst_ebml_write_master_finish (ebml, master);
gst_ebml_write_flush_cache (ebml);
}
/* FIXME: tags */
/* update seekhead. We know that:
* - a seekhead contains 4 entries.
* - order of entries is as above.
* - a seekhead has a 4-byte header + 8-byte length
* - each entry is 2-byte master, 2-byte ID pointer,
* 2-byte length pointer, all 8/1-byte length, 4-
* byte ID and 8-byte length pointer, where the
* length pointer starts at 20.
* - all entries are local to the segment (so pos - segment_master).
* - so each entry is at 12 + 20 + num * 28. */
gst_ebml_replace_uint (ebml, mux->seekhead_pos + 32,
mux->info_pos - mux->segment_master);
gst_ebml_replace_uint (ebml, mux->seekhead_pos + 60,
mux->tracks_pos - mux->segment_master);
if (mux->index != NULL) {
gst_ebml_replace_uint (ebml, mux->seekhead_pos + 88,
mux->cues_pos - mux->segment_master);
} else {
/* void'ify */
guint64 my_pos = ebml->pos;
gst_ebml_write_seek (ebml, mux->seekhead_pos + 68);
gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
gst_ebml_write_seek (ebml, my_pos);
}
#if 0
gst_ebml_replace_uint (ebml, mux->seekhead_pos + 116,
mux->tags_pos - mux->segment_master);
#endif
/* update duration */
pos = GST_EBML_WRITE (mux)->pos;
gst_ebml_write_seek (ebml, mux->duration_pos);
gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
mux->duration / mux->time_scale);
gst_ebml_write_seek (ebml, pos);
/* finish segment - this also writes element length */
gst_ebml_write_master_finish (ebml, mux->segment_pos);
}
static gint
gst_matroska_mux_prepare_data (GstMatroskaMux *mux)
{
gint i, first = -1;
for (i = 0; i < mux->num_streams; i++) {
while (!mux->sink[i].eos && !mux->sink[i].buffer &&
mux->sink[i].track->num > 0 &&
GST_PAD_IS_USABLE (mux->sink[i].track->pad)) {
GstData *data;
data = gst_pad_pull (mux->sink[i].track->pad);
if (GST_IS_EVENT (data)) {
if (GST_EVENT_TYPE (GST_EVENT (data)) == GST_EVENT_EOS)
mux->sink[i].eos = TRUE;
gst_event_unref (GST_EVENT (data));
} else {
mux->sink[i].buffer = GST_BUFFER (data);
}
}
if (mux->sink[i].buffer) {
if (first < 0 || GST_BUFFER_TIMESTAMP (mux->sink[i].buffer) <
GST_BUFFER_TIMESTAMP (mux->sink[first].buffer))
first = i;
}
}
return first;
}
static void
gst_matroska_mux_write_data (GstMatroskaMux *mux)
{
GstEbmlWrite *ebml = GST_EBML_WRITE (mux);
GstBuffer *buf, *hdr;
gint i;
guint64 cluster, blockgroup;
/* which stream-num to write from? */
if ((i = gst_matroska_mux_prepare_data (mux)) < 0) {
GstEvent *event = gst_event_new (GST_EVENT_EOS);
gst_matroska_mux_finish (mux);
gst_pad_push (mux->srcpad, GST_DATA (event));
gst_element_set_eos (GST_ELEMENT (mux));
return;
}
/* write data */
buf = mux->sink[i].buffer;
mux->sink[i].buffer = NULL;
/* We currently write an index entry for each keyframe in a
* video track. This can be largely improved, such as doing
* one for each keyframe or each second (for all-keyframe
* streams), only the *first* video track or the audio track
* if we have no video tracks. But that'll come later... */
if (mux->sink[i].track->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_KEY_UNIT)) {
GstMatroskaIndex *idx;
if (mux->num_indexes % 32 == 0) {
mux->index = g_renew (GstMatroskaIndex, mux->index,
mux->num_indexes + 32);
}
idx = &mux->index[mux->num_indexes++];
idx->pos = ebml->pos;
idx->time = GST_BUFFER_TIMESTAMP (buf);
idx->track = mux->sink[i].track->num;
}
/* write one cluster with one blockgroup with one block with
* one slice (*breath*).
* FIXME: lacing, multiple frames/cluster, etc. */
cluster = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
blockgroup = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_BLOCKGROUP);
gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_BLOCK,
GST_BUFFER_SIZE (buf) + 4);
hdr = gst_buffer_new_and_alloc (4);
/* track num - FIXME: what if num >= 0x80 (unlikely)? */
GST_BUFFER_DATA (hdr)[0] = mux->sink[i].track->num | 0x80;
/* time relative to clustertime - we don't use this yet */
* (guint16 *) &GST_BUFFER_DATA (hdr)[1] = GUINT16_TO_BE (0);
/* flags - no lacing (yet) */
GST_BUFFER_DATA (hdr)[3] = 0;
gst_ebml_write_buffer (ebml, hdr);
gst_ebml_write_buffer (ebml, buf);
gst_ebml_write_master_finish (ebml, blockgroup);
gst_ebml_write_master_finish (ebml, cluster);
}
static void
gst_matroska_mux_loop (GstElement *element)
{
GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
/* start with a header */
if (mux->state == GST_MATROSKA_MUX_STATE_START) {
mux->state = GST_MATROSKA_MUX_STATE_HEADER;
gst_matroska_mux_start (mux);
mux->state = GST_MATROSKA_MUX_STATE_DATA;
}
/* do one single buffer */
gst_matroska_mux_write_data (mux);
}
static GstElementStateReturn
gst_matroska_mux_change_state (GstElement *element)
{
GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PAUSED_TO_READY:
gst_matroska_mux_reset (GST_ELEMENT (mux));
break;
default:
break;
}
if (((GstElementClass *) parent_class)->change_state)
return ((GstElementClass *) parent_class)->change_state (element);
return GST_STATE_SUCCESS;
}
static void
gst_matroska_mux_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GstMatroskaMux *mux;
g_return_if_fail (GST_IS_MATROSKA_MUX (object));
mux = GST_MATROSKA_MUX (object);
switch (prop_id) {
case ARG_METADATA:
gst_caps_replace (&mux->metadata,
g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_matroska_mux_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GstMatroskaMux *mux;
g_return_if_fail (GST_IS_MATROSKA_MUX (object));
mux = GST_MATROSKA_MUX (object);
switch (prop_id) {
case ARG_METADATA:
g_value_set_boxed (value, mux->metadata);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
gboolean
gst_matroska_mux_plugin_init (GstPlugin *plugin)
{
return gst_element_register (plugin, "matroskamux",
GST_RANK_NONE,
GST_TYPE_MATROSKA_MUX);
}