ext/ffmpeg/: Add a stream-header flag to set stream-header caps on some streams,...
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Mon, 11 Jul 2005 12:34:18 +0000 (12:34 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Mon, 11 Jul 2005 12:34:18 +0000 (12:34 +0000)
Original commit message from CVS:
Reviewed by:  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
* 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
common
ext/ffmpeg/gstffmpeg.h
ext/ffmpeg/gstffmpegmux.c
ext/ffmpeg/gstffmpegprotocol.c

index 479bdaa..24e1832 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2005-07-11  daniel fischer  <dan@f3c.com>
+
+       Reviewed by:  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
+
+       * 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  <luogni@tin.it>
 
        * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_loop):
diff --git a/common b/common
index d6e46b2..ac7272b 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit d6e46b214fac0ecb46010ff522af2f7653e1c18e
+Subproject commit ac7272b7af934c2294a44ac1c0f3fac3f8d17ec6
index 3e4dacd..4cab7cd 100644 (file)
@@ -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__ */
index 0f149da..7c1fcbc 100644 (file)
@@ -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,
index 2772b53..9ca1013 100644 (file)
@@ -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;