matroskamux: Port to GstAggregator

Co-authored-by: Tim-Philipp Müller <tim@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7510>
This commit is contained in:
Sebastian Dröge 2024-09-13 10:13:11 +03:00 committed by GStreamer Marge Bot
parent a8f8bbef99
commit 945a7bdfc4
8 changed files with 509 additions and 613 deletions

View file

@ -12446,6 +12446,8 @@
"GstMatroskaMux:timecodescale", "GstMatroskaMux:timecodescale",
"GstMatroskaMux:version", "GstMatroskaMux:version",
"GstMatroskaMux:writing-app", "GstMatroskaMux:writing-app",
"GstMatroskaMuxPad",
"GstMatroskaMuxPad:frame-duration",
"GstMatroskaParse", "GstMatroskaParse",
"GstMatroskaParse!sink", "GstMatroskaParse!sink",
"GstMatroskaParse!src", "GstMatroskaParse!src",

View file

@ -9811,6 +9811,7 @@
"description": "Muxes video/audio/subtitle streams into a matroska stream", "description": "Muxes video/audio/subtitle streams into a matroska stream",
"hierarchy": [ "hierarchy": [
"GstMatroskaMux", "GstMatroskaMux",
"GstAggregator",
"GstElement", "GstElement",
"GstObject", "GstObject",
"GInitiallyUnowned", "GInitiallyUnowned",
@ -9826,7 +9827,8 @@
"audio_%%u": { "audio_%%u": {
"caps": "audio/mpeg:\n mpegversion: 1\n layer: [ 1, 3 ]\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/mpeg:\n mpegversion: { (int)2, (int)4 }\n stream-format: raw\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-ac3:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-eac3:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-dts:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-vorbis:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-flac:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-opus:\n channels: [ 1, 8 ]\n rate: { (int)8000, (int)16000, (int)24000, (int)32000, (int)48000 }\naudio/x-speex:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-raw:\n format: { U8, S16BE, S16LE, S24BE, S24LE, S32BE, S32LE, F32LE, F64LE }\n layout: interleaved\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-tta:\n width: { (int)8, (int)16, (int)24 }\n channels: { (int)1, (int)2 }\n rate: [ 8000, 96000 ]\naudio/x-pn-realaudio:\n raversion: { (int)1, (int)2, (int)8 }\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-wma:\n wmaversion: [ 1, 3 ]\n block_align: [ 0, 65535 ]\n bitrate: [ 0, 524288 ]\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-alaw:\n channels: { (int)1, (int)2 }\n rate: [ 8000, 192000 ]\naudio/x-mulaw:\n channels: { (int)1, (int)2 }\n rate: [ 8000, 192000 ]\naudio/x-adpcm:\n layout: dvi\n block_align: [ 64, 8192 ]\n channels: { (int)1, (int)2 }\n rate: [ 8000, 96000 ]\naudio/G722:\n channels: 1\n rate: 16000\naudio/x-adpcm:\n layout: g726\n channels: 1\n rate: 8000\n", "caps": "audio/mpeg:\n mpegversion: 1\n layer: [ 1, 3 ]\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/mpeg:\n mpegversion: { (int)2, (int)4 }\n stream-format: raw\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-ac3:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-eac3:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-dts:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-vorbis:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-flac:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-opus:\n channels: [ 1, 8 ]\n rate: { (int)8000, (int)16000, (int)24000, (int)32000, (int)48000 }\naudio/x-speex:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-raw:\n format: { U8, S16BE, S16LE, S24BE, S24LE, S32BE, S32LE, F32LE, F64LE }\n layout: interleaved\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-tta:\n width: { (int)8, (int)16, (int)24 }\n channels: { (int)1, (int)2 }\n rate: [ 8000, 96000 ]\naudio/x-pn-realaudio:\n raversion: { (int)1, (int)2, (int)8 }\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-wma:\n wmaversion: [ 1, 3 ]\n block_align: [ 0, 65535 ]\n bitrate: [ 0, 524288 ]\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-alaw:\n channels: { (int)1, (int)2 }\n rate: [ 8000, 192000 ]\naudio/x-mulaw:\n channels: { (int)1, (int)2 }\n rate: [ 8000, 192000 ]\naudio/x-adpcm:\n layout: dvi\n block_align: [ 64, 8192 ]\n channels: { (int)1, (int)2 }\n rate: [ 8000, 96000 ]\naudio/G722:\n channels: 1\n rate: 16000\naudio/x-adpcm:\n layout: g726\n channels: 1\n rate: 8000\n",
"direction": "sink", "direction": "sink",
"presence": "request" "presence": "request",
"type": "GstMatroskaMuxPad"
}, },
"src": { "src": {
"caps": "video/x-matroska:\nvideo/x-matroska-3d:\naudio/x-matroska:\n", "caps": "video/x-matroska:\nvideo/x-matroska-3d:\naudio/x-matroska:\n",
@ -9836,12 +9838,14 @@
"subtitle_%%u": { "subtitle_%%u": {
"caps": "subtitle/x-kate:\ntext/x-raw:\n format: utf8\napplication/x-ssa:\napplication/x-ass:\napplication/x-usf:\nsubpicture/x-dvd:\napplication/x-subtitle-unknown:\n", "caps": "subtitle/x-kate:\ntext/x-raw:\n format: utf8\napplication/x-ssa:\napplication/x-ass:\napplication/x-usf:\nsubpicture/x-dvd:\napplication/x-subtitle-unknown:\n",
"direction": "sink", "direction": "sink",
"presence": "request" "presence": "request",
"type": "GstMatroskaMuxPad"
}, },
"video_%%u": { "video_%%u": {
"caps": "video/mpeg:\n mpegversion: { (int)1, (int)2, (int)4 }\n systemstream: false\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h264:\n stream-format: { (string)avc, (string)avc3 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h265:\n stream-format: { (string)hvc1, (string)hev1 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-divx:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-huffyuv:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-dv:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h263:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-msmpeg:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nimage/jpeg:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-theora:\nvideo/x-dirac:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-pn-realvideo:\n rmversion: [ 1, 4 ]\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-vp8:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-vp9:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-raw:\n format: { YUY2, I420, YV12, UYVY, AYUV, GRAY8, GRAY10_LE32, GRAY16_LE, BGR, RGB, RGBA64_LE, BGRA64_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-prores:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-wmv:\n wmvversion: [ 1, 3 ]\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-av1:\n stream-format: obu-stream\n alignment: tu\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-ffv:\n ffversion: 1\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n", "caps": "video/mpeg:\n mpegversion: { (int)1, (int)2, (int)4 }\n systemstream: false\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h264:\n stream-format: { (string)avc, (string)avc3 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h265:\n stream-format: { (string)hvc1, (string)hev1 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-divx:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-huffyuv:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-dv:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h263:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-msmpeg:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nimage/jpeg:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-theora:\nvideo/x-dirac:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-pn-realvideo:\n rmversion: [ 1, 4 ]\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-vp8:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-vp9:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-raw:\n format: { YUY2, I420, YV12, UYVY, AYUV, GRAY8, GRAY10_LE32, GRAY16_LE, BGR, RGB, RGBA64_LE, BGRA64_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-prores:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-wmv:\n wmvversion: [ 1, 3 ]\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-av1:\n stream-format: obu-stream\n alignment: tu\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-ffv:\n ffversion: 1\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n",
"direction": "sink", "direction": "sink",
"presence": "request" "presence": "request",
"type": "GstMatroskaMuxPad"
} }
}, },
"properties": { "properties": {
@ -10011,6 +10015,7 @@
"hierarchy": [ "hierarchy": [
"GstWebMMux", "GstWebMMux",
"GstMatroskaMux", "GstMatroskaMux",
"GstAggregator",
"GstElement", "GstElement",
"GstObject", "GstObject",
"GInitiallyUnowned", "GInitiallyUnowned",
@ -10026,7 +10031,8 @@
"audio_%%u": { "audio_%%u": {
"caps": "audio/x-vorbis:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-opus:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\n", "caps": "audio/x-vorbis:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\naudio/x-opus:\n channels: [ 1, 2147483647 ]\n rate: [ 1, 2147483647 ]\n",
"direction": "sink", "direction": "sink",
"presence": "request" "presence": "request",
"type": "GstMatroskaMuxPad"
}, },
"src": { "src": {
"caps": "video/webm:\naudio/webm:\n", "caps": "video/webm:\naudio/webm:\n",
@ -10036,12 +10042,14 @@
"subtitle_%%u": { "subtitle_%%u": {
"caps": "subtitle/x-kate:\ntext/x-raw:\n format: utf8\napplication/x-ssa:\napplication/x-ass:\napplication/x-usf:\nsubpicture/x-dvd:\napplication/x-subtitle-unknown:\n", "caps": "subtitle/x-kate:\ntext/x-raw:\n format: utf8\napplication/x-ssa:\napplication/x-ass:\napplication/x-usf:\nsubpicture/x-dvd:\napplication/x-subtitle-unknown:\n",
"direction": "sink", "direction": "sink",
"presence": "request" "presence": "request",
"type": "GstMatroskaMuxPad"
}, },
"video_%%u": { "video_%%u": {
"caps": "video/x-vp8:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-vp9:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-av1:\n stream-format: obu-stream\n alignment: tu\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "caps": "video/x-vp8:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-vp9:\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-av1:\n stream-format: obu-stream\n alignment: tu\n width: [ 16, 2147483647 ]\n height: [ 16, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
"direction": "sink", "direction": "sink",
"presence": "request" "presence": "request",
"type": "GstMatroskaMuxPad"
} }
}, },
"properties": {}, "properties": {},
@ -10050,7 +10058,33 @@
}, },
"filename": "gstmatroska", "filename": "gstmatroska",
"license": "LGPL", "license": "LGPL",
"other-types": {}, "other-types": {
"GstMatroskaMuxPad": {
"hierarchy": [
"GstMatroskaMuxPad",
"GstAggregatorPad",
"GstPad",
"GstObject",
"GInitiallyUnowned",
"GObject"
],
"kind": "object",
"properties": {
"frame-duration": {
"blurb": "Default frame duration",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": true,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
}
}
}
},
"package": "GStreamer Good Plug-ins", "package": "GStreamer Good Plug-ins",
"source": "gst-plugins-good", "source": "gst-plugins-good",
"tracers": {}, "tracers": {},

View file

@ -52,7 +52,7 @@ gst_ebml_write_class_init (GstEbmlWriteClass * klass)
static void static void
gst_ebml_write_init (GstEbmlWrite * ebml) gst_ebml_write_init (GstEbmlWrite * ebml)
{ {
ebml->srcpad = NULL; ebml->agg = NULL;
ebml->pos = 0; ebml->pos = 0;
ebml->last_pos = G_MAXUINT64; /* force segment event */ ebml->last_pos = G_MAXUINT64; /* force segment event */
@ -68,7 +68,7 @@ gst_ebml_write_finalize (GObject * object)
{ {
GstEbmlWrite *ebml = GST_EBML_WRITE (object); GstEbmlWrite *ebml = GST_EBML_WRITE (object);
gst_object_unref (ebml->srcpad); ebml->agg = NULL;
if (ebml->cache) { if (ebml->cache) {
gst_byte_writer_free (ebml->cache); gst_byte_writer_free (ebml->cache);
@ -98,12 +98,12 @@ gst_ebml_write_finalize (GObject * object)
* Returns: a new #GstEbmlWrite * Returns: a new #GstEbmlWrite
*/ */
GstEbmlWrite * GstEbmlWrite *
gst_ebml_write_new (GstPad * srcpad) gst_ebml_write_new (GstAggregator * agg)
{ {
GstEbmlWrite *ebml = GstEbmlWrite *ebml =
GST_EBML_WRITE (g_object_new (GST_TYPE_EBML_WRITE, NULL)); GST_EBML_WRITE (g_object_new (GST_TYPE_EBML_WRITE, NULL));
ebml->srcpad = gst_object_ref (srcpad); ebml->agg = agg;
ebml->timestamp = GST_CLOCK_TIME_NONE; ebml->timestamp = GST_CLOCK_TIME_NONE;
gst_ebml_write_reset (ebml); gst_ebml_write_reset (ebml);
@ -207,11 +207,10 @@ gst_ebml_write_set_cache (GstEbmlWrite * ebml, guint size)
ebml->cache_pos = ebml->pos; ebml->cache_pos = ebml->pos;
} }
static gboolean static void
gst_ebml_writer_send_segment_event (GstEbmlWrite * ebml, guint64 new_pos) gst_ebml_writer_send_segment_event (GstEbmlWrite * ebml, guint64 new_pos)
{ {
GstSegment segment; GstSegment segment;
gboolean res;
GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos); GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos);
@ -221,12 +220,7 @@ gst_ebml_writer_send_segment_event (GstEbmlWrite * ebml, guint64 new_pos)
segment.stop = -1; segment.stop = -1;
segment.position = 0; segment.position = 0;
res = gst_pad_push_event (ebml->srcpad, gst_event_new_segment (&segment)); gst_aggregator_update_segment (ebml->agg, &segment);
if (!res)
GST_WARNING ("seek to %" G_GUINT64_FORMAT "failed", new_pos);
return res;
} }
/** /**
@ -268,7 +262,7 @@ gst_ebml_write_flush_cache (GstEbmlWrite * ebml, gboolean is_keyframe,
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
} }
ebml->last_pos = ebml->pos; ebml->last_pos = ebml->pos;
ebml->last_write_result = gst_pad_push (ebml->srcpad, buffer); ebml->last_write_result = gst_aggregator_finish_buffer (ebml->agg, buffer);
} else { } else {
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
} }
@ -474,7 +468,7 @@ gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf,
GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT); GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
} }
ebml->last_pos = ebml->pos; ebml->last_pos = ebml->pos;
ebml->last_write_result = gst_pad_push (ebml->srcpad, buf); ebml->last_write_result = gst_aggregator_finish_buffer (ebml->agg, buf);
} else { } else {
gst_buffer_unref (buf); gst_buffer_unref (buf);
} }

View file

@ -25,7 +25,7 @@
#include <glib.h> #include <glib.h>
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/base/gstbytewriter.h> #include <gst/base/base.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -45,7 +45,8 @@ G_BEGIN_DECLS
typedef struct _GstEbmlWrite { typedef struct _GstEbmlWrite {
GstObject object; GstObject object;
GstPad *srcpad; GstAggregator *agg;
guint64 pos; guint64 pos;
guint64 last_pos; guint64 last_pos;
GstClockTime timestamp; GstClockTime timestamp;
@ -70,7 +71,7 @@ typedef struct _GstEbmlWriteClass {
GType gst_ebml_write_get_type (void); GType gst_ebml_write_get_type (void);
GstEbmlWrite *gst_ebml_write_new (GstPad *srcpad); GstEbmlWrite *gst_ebml_write_new (GstAggregator *agg);
void gst_ebml_write_reset (GstEbmlWrite *ebml); void gst_ebml_write_reset (GstEbmlWrite *ebml);
GstFlowReturn gst_ebml_last_write_result (GstEbmlWrite *ebml); GstFlowReturn gst_ebml_last_write_result (GstEbmlWrite *ebml);

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,7 @@
#define __GST_MATROSKA_MUX_H__ #define __GST_MATROSKA_MUX_H__
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/base/gstcollectpads.h> #include <gst/base/base.h>
#include "ebml-write.h" #include "ebml-write.h"
#include "matroska-ids.h" #include "matroska-ids.h"
@ -42,6 +42,11 @@ G_BEGIN_DECLS
#define GST_IS_MATROSKA_MUX_CLASS(klass) \ #define GST_IS_MATROSKA_MUX_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MATROSKA_MUX)) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MATROSKA_MUX))
#define GST_TYPE_MATROSKA_MUX_PAD (gst_matroska_mux_pad_get_type())
#define GST_MATROSKA_MUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_CAST((pad),GST_TYPE_MATROSKA_MUX_PAD,GstMatroskaMuxPad))
#define GST_MATROSKA_MUX_PAD_CAST(pad) ((GstMatroskaMuxPad *) pad)
#define GST_IS_MATROSKA_MUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_TYPE((pad),GST_TYPE_MATROSKA_MUX_PAD))
typedef enum { typedef enum {
GST_MATROSKA_MUX_STATE_START, GST_MATROSKA_MUX_STATE_START,
GST_MATROSKA_MUX_STATE_HEADER, GST_MATROSKA_MUX_STATE_HEADER,
@ -53,36 +58,37 @@ typedef struct _GstMatroskaMetaSeekIndex {
guint64 pos; guint64 pos;
} GstMatroskaMetaSeekIndex; } GstMatroskaMetaSeekIndex;
typedef gboolean (*GstMatroskaCapsFunc) (GstPad *pad, GstCaps *caps);
typedef struct _GstMatroskaMux GstMatroskaMux; typedef struct _GstMatroskaMux GstMatroskaMux;
typedef struct _GstMatroskaMuxPad GstMatroskaMuxPad;
typedef gboolean (*GstMatroskaCapsFunc) (GstMatroskaMux *mux, GstMatroskaMuxPad *mux_pad, GstCaps *caps);
/* all information needed for one matroska stream */ /* all information needed for one matroska stream */
typedef struct struct _GstMatroskaMuxPad {
{ GstAggregatorPad pad;
GstCollectData collect; /* we extend the CollectData */
gboolean frame_duration;
gboolean frame_duration_user;
GstMatroskaCapsFunc capsfunc; GstMatroskaCapsFunc capsfunc;
GstMatroskaTrackContext *track; GstMatroskaTrackContext *track;
GstMatroskaMux *mux;
GstTagList *tags; GstTagList *tags;
GstClockTime start_ts; GstClockTime start_ts;
GstClockTime end_ts; /* last timestamp + (if available) duration */ GstClockTime end_ts; /* last timestamp + (if available) duration */
guint64 default_duration_scaled; guint64 default_duration_scaled;
} };
GstMatroskaPad;
typedef struct _GstMatroskaMuxPadClass {
GstAggregatorPadClass pad_class;
} GstMatroskaMuxPadClass;
struct _GstMatroskaMux { struct _GstMatroskaMux {
GstElement element; GstAggregator aggregator;
/* < private > */ /* < private > */
/* pads */
GstPad *srcpad;
GstCollectPads *collect;
GstEbmlWrite *ebml_write; GstEbmlWrite *ebml_write;
guint num_streams, guint num_streams,
@ -150,10 +156,11 @@ struct _GstMatroskaMux {
}; };
typedef struct _GstMatroskaMuxClass { typedef struct _GstMatroskaMuxClass {
GstElementClass parent; GstAggregatorClass parent;
} GstMatroskaMuxClass; } GstMatroskaMuxClass;
GType gst_matroska_mux_get_type (void); GType gst_matroska_mux_get_type (void);
GType gst_matroska_mux_pad_get_type (void);
G_END_DECLS G_END_DECLS

View file

@ -87,10 +87,10 @@ gst_webm_mux_class_init (GstWebMMuxClass * klass)
{ {
GstElementClass *gstelement_class = (GstElementClass *) klass; GstElementClass *gstelement_class = (GstElementClass *) klass;
gst_element_class_add_static_pad_template (gstelement_class, gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
&webm_videosink_templ); &webm_videosink_templ, GST_TYPE_MATROSKA_MUX_PAD);
gst_element_class_add_static_pad_template (gstelement_class, gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
&webm_audiosink_templ); &webm_audiosink_templ, GST_TYPE_MATROSKA_MUX_PAD);
gst_element_class_add_static_pad_template (gstelement_class, &webm_src_templ); gst_element_class_add_static_pad_template (gstelement_class, &webm_src_templ);
gst_element_class_set_static_metadata (gstelement_class, "WebM muxer", gst_element_class_set_static_metadata (gstelement_class, "WebM muxer",
"Codec/Muxer", "Codec/Muxer",

View file

@ -74,13 +74,16 @@ test_ebml_header_with_version (gint version,
g_object_set (h->element, "version", version, NULL); g_object_set (h->element, "version", version, NULL);
inbuffer = gst_harness_create_buffer (h, 1); inbuffer = gst_harness_create_buffer (h, 1);
GST_BUFFER_PTS (inbuffer) = 0;
fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer)); fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer));
fail_unless_equals_int (2, gst_harness_buffers_received (h));
outbuffer = gst_harness_pull (h); outbuffer = gst_harness_pull (h);
compare_buffer_to_data (outbuffer, data, data_size); compare_buffer_to_data (outbuffer, data, data_size);
gst_buffer_unref (outbuffer); gst_buffer_unref (outbuffer);
outbuffer = gst_harness_pull (h);
gst_buffer_unref (outbuffer);
gst_harness_teardown (h); gst_harness_teardown (h);
} }
@ -142,6 +145,7 @@ GST_START_TEST (test_vorbis_header)
h = setup_matroskamux_harness (VORBIS_TMPL_CAPS_STRING); h = setup_matroskamux_harness (VORBIS_TMPL_CAPS_STRING);
inbuffer = gst_harness_create_buffer (h, 1); inbuffer = gst_harness_create_buffer (h, 1);
GST_BUFFER_PTS (inbuffer) = 0;
fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer)); fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer));
outbuffer = gst_harness_pull (h); outbuffer = gst_harness_pull (h);
@ -160,7 +164,10 @@ GST_START_TEST (test_vorbis_header)
ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1); ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
gst_buffer_unref (outbuffer); gst_buffer_unref (outbuffer);
outbuffer = gst_harness_try_pull (h); if (vorbis_header_found)
break;
outbuffer = gst_harness_pull (h);
} }
fail_unless (vorbis_header_found); fail_unless (vorbis_header_found);
@ -186,13 +193,11 @@ test_block_group_with_version (gint version,
inbuffer = gst_harness_create_buffer (h, 1); inbuffer = gst_harness_create_buffer (h, 1);
GST_BUFFER_TIMESTAMP (inbuffer) = 0; GST_BUFFER_TIMESTAMP (inbuffer) = 0;
fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer)); fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer));
fail_unless_equals_int (5, gst_harness_buffers_received (h));
for (int i = 0; i < 5; i++) {
outbuffer = gst_harness_pull (h); outbuffer = gst_harness_pull (h);
fail_unless (outbuffer != NULL); fail_unless (outbuffer != NULL);
while (outbuffer != NULL) {
gst_buffer_unref (outbuffer); gst_buffer_unref (outbuffer);
outbuffer = gst_harness_try_pull (h);
} }
/* Now push a buffer */ /* Now push a buffer */
@ -245,13 +250,11 @@ GST_START_TEST (test_reset)
inbuffer = gst_harness_create_buffer (h, 1); inbuffer = gst_harness_create_buffer (h, 1);
GST_BUFFER_TIMESTAMP (inbuffer) = 0; GST_BUFFER_TIMESTAMP (inbuffer) = 0;
fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer)); fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer));
fail_unless_equals_int (5, gst_harness_buffers_received (h));
for (int i = 0; i < 5; i++) {
outbuffer = gst_harness_pull (h); outbuffer = gst_harness_pull (h);
fail_unless (outbuffer != NULL); fail_unless (outbuffer != NULL);
while (outbuffer != NULL) {
gst_buffer_unref (outbuffer); gst_buffer_unref (outbuffer);
outbuffer = gst_harness_try_pull (h);
} }
fail_unless_equals_int (GST_STATE_CHANGE_SUCCESS, fail_unless_equals_int (GST_STATE_CHANGE_SUCCESS,
@ -262,12 +265,13 @@ GST_START_TEST (test_reset)
inbuffer = gst_harness_create_buffer (h, 1); inbuffer = gst_harness_create_buffer (h, 1);
GST_BUFFER_TIMESTAMP (inbuffer) = 0; GST_BUFFER_TIMESTAMP (inbuffer) = 0;
fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer)); fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, inbuffer));
gst_harness_push_event (h, gst_event_new_eos ());
outbuffer = gst_harness_pull (h); outbuffer = gst_harness_pull (h);
fail_unless (outbuffer != NULL); fail_unless (outbuffer != NULL);
while (outbuffer != NULL) { while (outbuffer != NULL) {
gst_buffer_unref (outbuffer); gst_buffer_unref (outbuffer);
outbuffer = gst_harness_try_pull (h); fail_unless (gst_harness_pull_until_eos (h, &outbuffer));
} }
gst_harness_teardown (h); gst_harness_teardown (h);
@ -940,7 +944,6 @@ test_toc (gboolean with_edition)
/* send eos to ensure everything is written */ /* send eos to ensure everything is written */
fail_unless (gst_harness_push_event (h, gst_event_new_eos ())); fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
ASSERT_MINI_OBJECT_REFCOUNT (test_toc, "test_toc", 1);
outbuffer = gst_harness_pull (h); outbuffer = gst_harness_pull (h);
fail_unless (outbuffer != NULL); fail_unless (outbuffer != NULL);
@ -958,7 +961,7 @@ test_toc (gboolean with_edition)
} }
gst_buffer_unref (outbuffer); gst_buffer_unref (outbuffer);
outbuffer = gst_harness_try_pull (h); fail_unless (gst_harness_pull_until_eos (h, &outbuffer));
} }
fail_unless (gst_buffer_map (merged_buffer, &info, GST_MAP_READ)); fail_unless (gst_buffer_map (merged_buffer, &info, GST_MAP_READ));