From 5f377234f55d231d1713b4bc389bcddb0bcbc8a9 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 11 Jul 2005 12:34:18 +0000 Subject: [PATCH] ext/ffmpeg/: Add a stream-header flag to set stream-header caps on some streams, such as (in this case) flv (fixes #3... Original commit message from CVS: Reviewed by: Ronald S. Bultje * ext/ffmpeg/gstffmpeg.h: * ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_loop): * ext/ffmpeg/gstffmpegprotocol.c: (gst_ffmpegdata_open), (gst_ffmpegdata_write): Add a stream-header flag to set stream-header caps on some streams, such as (in this case) flv (fixes #309051). --- ChangeLog | 11 +++++++++++ common | 2 +- ext/ffmpeg/gstffmpeg.h | 4 ++++ ext/ffmpeg/gstffmpegmux.c | 11 ++++++++++- ext/ffmpeg/gstffmpegprotocol.c | 33 +++++++++++++++++++++++++++++++-- 5 files changed, 57 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 479bdaa1fd..24e1832455 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-07-11 daniel fischer + + Reviewed by: Ronald S. Bultje + + * ext/ffmpeg/gstffmpeg.h: + * ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_loop): + * ext/ffmpeg/gstffmpegprotocol.c: (gst_ffmpegdata_open), + (gst_ffmpegdata_write): + Add a stream-header flag to set stream-header caps on some streams, + such as (in this case) flv (fixes #309051). + 2005-06-27 Luca Ognibene * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_loop): diff --git a/common b/common index d6e46b214f..ac7272b7af 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit d6e46b214fac0ecb46010ff522af2f7653e1c18e +Subproject commit ac7272b7af934c2294a44ac1c0f3fac3f8d17ec6 diff --git a/ext/ffmpeg/gstffmpeg.h b/ext/ffmpeg/gstffmpeg.h index 3e4dacd2ae..4cab7cd096 100644 --- a/ext/ffmpeg/gstffmpeg.h +++ b/ext/ffmpeg/gstffmpeg.h @@ -49,4 +49,8 @@ G_END_DECLS extern URLProtocol gstreamer_protocol; +/* use GST_FFMPEG URL_STREAMHEADER with URL_WRONLY if the first + * buffer should be used as streamheader property on the pad's caps. */ +#define GST_FFMPEG_URL_STREAMHEADER 16 + #endif /* __GST_FFMPEG_H__ */ diff --git a/ext/ffmpeg/gstffmpegmux.c b/ext/ffmpeg/gstffmpegmux.c index 0f149da77b..7c1fcbc73e 100644 --- a/ext/ffmpeg/gstffmpegmux.c +++ b/ext/ffmpeg/gstffmpegmux.c @@ -342,6 +342,7 @@ gst_ffmpegmux_loop (GstElement * element) /* open "file" (gstreamer protocol to next element) */ if (!ffmpegmux->opened) { const GstTagList *iface_tags; + int open_flags = URL_WRONLY; /* we do need all streams to have started capsnego, * or things will go horribly wrong */ @@ -410,8 +411,13 @@ gst_ffmpegmux_loop (GstElement * element) gst_tag_list_free (tags); } + /* set the streamheader flag for gstffmpegprotocol if codec supports it */ + if (!strcmp (ffmpegmux->context->oformat->name, "flv") ) { + open_flags |= GST_FFMPEG_URL_STREAMHEADER; + } + if (url_fopen (&ffmpegmux->context->pb, - ffmpegmux->context->filename, URL_WRONLY) < 0) { + ffmpegmux->context->filename, open_flags) < 0) { GST_ELEMENT_ERROR (element, LIBRARY, TOO_LAZY, (NULL), ("Failed to open stream context in ffmux")); return; @@ -432,6 +438,9 @@ gst_ffmpegmux_loop (GstElement * element) ("Failed to write file header - check codec settings")); return; } + + /* flush the header so it will be used as streamheader */ + put_flush_packet (&ffmpegmux->context->pb); } /* take the one with earliest timestamp, diff --git a/ext/ffmpeg/gstffmpegprotocol.c b/ext/ffmpeg/gstffmpegprotocol.c index 2772b5330e..9ca101354b 100644 --- a/ext/ffmpeg/gstffmpegprotocol.c +++ b/ext/ffmpeg/gstffmpegprotocol.c @@ -41,6 +41,7 @@ struct _GstProtocolInfo GstByteStream *bs; gboolean eos; + gboolean set_streamheader; }; static int @@ -53,6 +54,9 @@ gst_ffmpegdata_open (URLContext * h, const char *filename, int flags) info = g_new0 (GstProtocolInfo, 1); + info->set_streamheader = flags & GST_FFMPEG_URL_STREAMHEADER; + flags &= ~GST_FFMPEG_URL_STREAMHEADER; + /* we don't support R/W together */ if (flags != URL_RDONLY && flags != URL_WRONLY) { g_warning ("Only read-only or write-only are supported"); @@ -196,16 +200,41 @@ gst_ffmpegdata_write (URLContext * h, unsigned char *buf, int size) GstBuffer *outbuf; GST_DEBUG ("Writing %d bytes", size); - info = (GstProtocolInfo *) h->priv_data; - g_return_val_if_fail (h->flags == URL_WRONLY, -EIO); + g_return_val_if_fail (h->flags != URL_RDONLY, -EIO); /* create buffer and push data further */ outbuf = gst_buffer_new_and_alloc (size); GST_BUFFER_SIZE (outbuf) = size; memcpy (GST_BUFFER_DATA (outbuf), buf, size); + if (info->set_streamheader) { + GstCaps *caps = gst_pad_get_caps (info->pad); + GList *bufs = NULL; + GstStructure *structure = gst_caps_get_structure (caps, 0); + GValue list = { 0 }, value = { 0 }; + + GST_DEBUG ("Using buffer (size %i) as streamheader", size); + + g_value_init (&list, GST_TYPE_FIXED_LIST); + + GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_IN_CAPS); + + g_value_init (&value, GST_TYPE_BUFFER); + g_value_set_boxed (&value, outbuf); + gst_value_list_append_value (&list, &value); + g_value_unset (&value); + + gst_structure_set_value (structure, "streamheader", &list); + g_value_unset (&list); + + gst_pad_try_set_caps (info->pad, caps); + + /* only set the first buffer */ + info->set_streamheader = FALSE; + } + gst_pad_push (info->pad, GST_DATA (outbuf)); return size;