David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 1 | /* GStreamer |
| 2 | * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> |
| 3 | * 2000 Wim Taymans <wtay@chello.be> |
| 4 | * 2006 Wim Taymans <wim@fluendo.com> |
| 5 | * 2006 David A. Schleef <ds@schleef.org> |
| 6 | * |
| 7 | * gstmultifilesink.c: |
| 8 | * |
| 9 | * This library is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU Library General Public |
| 11 | * License as published by the Free Software Foundation; either |
| 12 | * version 2 of the License, or (at your option) any later version. |
| 13 | * |
| 14 | * This library is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | * Library General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU Library General Public |
| 20 | * License along with this library; if not, write to the |
| 21 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 22 | * Boston, MA 02111-1307, USA. |
| 23 | */ |
| 24 | /** |
| 25 | * SECTION:element-multifilesink |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 26 | * @see_also: #GstFileSrc |
| 27 | * |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 28 | * Write incoming data to a series of sequentially-named files. |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 29 | * |
| 30 | * The filename property should contain a string with a %d placeholder that will |
| 31 | * be substituted with the index for each filename. |
| 32 | * |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 33 | * If the #GstMultiFileSink:post-messages property is #TRUE, it sends an application |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 34 | * message named |
| 35 | * <classname>"GstMultiFileSink"</classname> after writing each |
| 36 | * buffer. |
| 37 | * |
| 38 | * The message's structure contains these fields: |
| 39 | * <itemizedlist> |
| 40 | * <listitem> |
| 41 | * <para> |
| 42 | * #gchar * |
| 43 | * <classname>"filename"</classname>: |
| 44 | * the filename where the buffer was written. |
| 45 | * </para> |
| 46 | * </listitem> |
| 47 | * <listitem> |
| 48 | * <para> |
| 49 | * #gint |
| 50 | * <classname>"index"</classname>: |
| 51 | * the index of the buffer. |
| 52 | * </para> |
| 53 | * </listitem> |
| 54 | * <listitem> |
| 55 | * <para> |
| 56 | * #GstClockTime |
| 57 | * <classname>"timestamp"</classname>: |
| 58 | * the timestamp of the buffer. |
| 59 | * </para> |
| 60 | * </listitem> |
| 61 | * <listitem> |
| 62 | * <para> |
| 63 | * #GstClockTime |
| 64 | * <classname>"stream-time"</classname>: |
| 65 | * the stream time of the buffer. |
| 66 | * </para> |
| 67 | * </listitem> |
| 68 | * <listitem> |
| 69 | * <para> |
| 70 | * #GstClockTime |
| 71 | * <classname>"running-time"</classname>: |
| 72 | * the running_time of the buffer. |
| 73 | * </para> |
| 74 | * </listitem> |
| 75 | * <listitem> |
| 76 | * <para> |
| 77 | * #GstClockTime |
| 78 | * <classname>"duration"</classname>: |
| 79 | * the duration of the buffer. |
| 80 | * </para> |
| 81 | * </listitem> |
| 82 | * <listitem> |
| 83 | * <para> |
| 84 | * #guint64 |
| 85 | * <classname>"offset"</classname>: |
| 86 | * the offset of the buffer that triggered the message. |
| 87 | * </para> |
| 88 | * </listitem> |
| 89 | * <listitem> |
| 90 | * <para> |
| 91 | * #guint64 |
| 92 | * <classname>"offset-end"</classname>: |
| 93 | * the offset-end of the buffer that triggered the message. |
| 94 | * </para> |
| 95 | * </listitem> |
| 96 | * </itemizedlist> |
| 97 | * |
| 98 | * <title>Example launch line</title> |
| 99 | * <refsect2> |
| 100 | * |[ |
| 101 | * gst-launch audiotestsrc ! multifilesink |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 102 | * gst-launch videotestsrc ! multifilesink post-messages=true filename="frame%d" |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 103 | * ]| |
| 104 | * </refsect2> |
| 105 | * |
| 106 | * Last reviewed on 2009-09-11 (0.10.17) |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 107 | */ |
| 108 | |
| 109 | #ifdef HAVE_CONFIG_H |
| 110 | # include "config.h" |
| 111 | #endif |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 112 | #include <gst/base/gstbasetransform.h> |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 113 | #include <glib/gstdio.h> |
Stefan Kost | 6f765c5 | 2007-07-03 08:01:18 +0000 | [diff] [blame] | 114 | #include "gstmultifilesink.h" |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 115 | |
| 116 | static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", |
| 117 | GST_PAD_SINK, |
| 118 | GST_PAD_ALWAYS, |
| 119 | GST_STATIC_CAPS_ANY); |
| 120 | |
| 121 | GST_DEBUG_CATEGORY_STATIC (gst_multi_file_sink_debug); |
| 122 | #define GST_CAT_DEFAULT gst_multi_file_sink_debug |
| 123 | |
| 124 | static const GstElementDetails gst_multi_file_sink_details = |
| 125 | GST_ELEMENT_DETAILS ("Multi-File Sink", |
| 126 | "Sink/File", |
David Schleef | da83e9f | 2008-02-08 03:44:12 +0000 | [diff] [blame] | 127 | "Write buffers to a sequentially named set of files", |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 128 | "David Schleef <ds@schleef.org>"); |
| 129 | |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 130 | #define DEFAULT_LOCATION "%05d" |
| 131 | #define DEFAULT_INDEX 0 |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 132 | #define DEFAULT_POST_MESSAGES FALSE |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 133 | #define DEFAULT_NEXT_FILE GST_MULTI_FILE_SINK_NEXT_BUFFER |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 134 | |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 135 | enum |
| 136 | { |
| 137 | PROP_0, |
| 138 | PROP_LOCATION, |
| 139 | PROP_INDEX, |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 140 | PROP_POST_MESSAGES, |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 141 | PROP_NEXT_FILE, |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 142 | PROP_LAST |
| 143 | }; |
| 144 | |
| 145 | static void gst_multi_file_sink_finalize (GObject * object); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 146 | |
| 147 | static void gst_multi_file_sink_set_property (GObject * object, guint prop_id, |
| 148 | const GValue * value, GParamSpec * pspec); |
| 149 | static void gst_multi_file_sink_get_property (GObject * object, guint prop_id, |
| 150 | GValue * value, GParamSpec * pspec); |
| 151 | |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 152 | static gboolean gst_multi_file_sink_stop (GstBaseSink * sink); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 153 | static GstFlowReturn gst_multi_file_sink_render (GstBaseSink * sink, |
| 154 | GstBuffer * buffer); |
| 155 | |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 156 | #define GST_TYPE_MULTI_FILE_SINK_NEXT (gst_multi_file_sink_next_get_type ()) |
| 157 | static GType |
| 158 | gst_multi_file_sink_next_get_type (void) |
| 159 | { |
| 160 | static GType multi_file_sync_next_type = 0; |
| 161 | static const GEnumValue next_types[] = { |
| 162 | {GST_MULTI_FILE_SINK_NEXT_BUFFER, "New file for each buffer", "buffer"}, |
| 163 | {GST_MULTI_FILE_SINK_NEXT_DISCONT, "New file after each discontinuity", |
| 164 | "discont"}, |
| 165 | {0, NULL, NULL} |
| 166 | }; |
| 167 | |
| 168 | if (!multi_file_sync_next_type) { |
| 169 | multi_file_sync_next_type = |
| 170 | g_enum_register_static ("GstMultiFileSinkNext", next_types); |
| 171 | } |
| 172 | |
| 173 | return multi_file_sync_next_type; |
| 174 | } |
| 175 | |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 176 | GST_BOILERPLATE (GstMultiFileSink, gst_multi_file_sink, GstBaseSink, |
| 177 | GST_TYPE_BASE_SINK); |
| 178 | |
| 179 | static void |
| 180 | gst_multi_file_sink_base_init (gpointer g_class) |
| 181 | { |
| 182 | GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); |
| 183 | |
| 184 | GST_DEBUG_CATEGORY_INIT (gst_multi_file_sink_debug, "multifilesink", 0, |
| 185 | "multifilesink element"); |
| 186 | |
| 187 | gst_element_class_add_pad_template (gstelement_class, |
| 188 | gst_static_pad_template_get (&sinktemplate)); |
| 189 | gst_element_class_set_details (gstelement_class, |
| 190 | &gst_multi_file_sink_details); |
| 191 | } |
| 192 | |
| 193 | static void |
| 194 | gst_multi_file_sink_class_init (GstMultiFileSinkClass * klass) |
| 195 | { |
| 196 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); |
| 197 | GstBaseSinkClass *gstbasesink_class = GST_BASE_SINK_CLASS (klass); |
| 198 | |
| 199 | gobject_class->set_property = gst_multi_file_sink_set_property; |
| 200 | gobject_class->get_property = gst_multi_file_sink_get_property; |
| 201 | |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 202 | g_object_class_install_property (gobject_class, PROP_LOCATION, |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 203 | g_param_spec_string ("location", "File Location", |
| 204 | "Location of the file to write", NULL, G_PARAM_READWRITE)); |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 205 | |
| 206 | g_object_class_install_property (gobject_class, PROP_INDEX, |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 207 | g_param_spec_int ("index", "Index", |
| 208 | "Index to use with location property to create file names. The " |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 209 | "index is incremented by one for each buffer written.", |
| 210 | 0, G_MAXINT, DEFAULT_INDEX, G_PARAM_READWRITE)); |
| 211 | /** |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 212 | * GstMultiFileSink:post-messages |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 213 | * |
| 214 | * Post a message on the GstBus for each file. |
| 215 | * |
| 216 | * Since: 0.10.17 |
| 217 | */ |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 218 | g_object_class_install_property (gobject_class, PROP_POST_MESSAGES, |
| 219 | g_param_spec_boolean ("post-messages", "Post Messages", |
| 220 | "Post a message for each file with information of the buffer", |
| 221 | DEFAULT_POST_MESSAGES, G_PARAM_READWRITE)); |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 222 | /** |
| 223 | * GstMultiFileSink:next-file |
| 224 | * |
| 225 | * When to start a new file. |
| 226 | * |
| 227 | * Since: 0.10.17 |
| 228 | */ |
| 229 | g_object_class_install_property (gobject_class, PROP_NEXT_FILE, |
| 230 | g_param_spec_enum ("next-file", "Next File", |
| 231 | "When to start a new file", |
| 232 | GST_TYPE_MULTI_FILE_SINK_NEXT, DEFAULT_NEXT_FILE, |
| 233 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 234 | |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 235 | gobject_class->finalize = gst_multi_file_sink_finalize; |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 236 | |
| 237 | gstbasesink_class->get_times = NULL; |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 238 | gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_multi_file_sink_stop); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 239 | gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_multi_file_sink_render); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 240 | } |
| 241 | |
| 242 | static void |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 243 | gst_multi_file_sink_init (GstMultiFileSink * multifilesink, |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 244 | GstMultiFileSinkClass * g_class) |
| 245 | { |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 246 | multifilesink->filename = g_strdup (DEFAULT_LOCATION); |
| 247 | multifilesink->index = DEFAULT_INDEX; |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 248 | multifilesink->post_messages = DEFAULT_POST_MESSAGES; |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 249 | |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 250 | gst_base_sink_set_sync (GST_BASE_SINK (multifilesink), FALSE); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 251 | } |
| 252 | |
| 253 | static void |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 254 | gst_multi_file_sink_finalize (GObject * object) |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 255 | { |
| 256 | GstMultiFileSink *sink = GST_MULTI_FILE_SINK (object); |
| 257 | |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 258 | g_free (sink->filename); |
Stefan Kost | a67ced8 | 2007-09-24 10:53:36 +0000 | [diff] [blame] | 259 | |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 260 | G_OBJECT_CLASS (parent_class)->finalize (object); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 261 | } |
| 262 | |
| 263 | static gboolean |
| 264 | gst_multi_file_sink_set_location (GstMultiFileSink * sink, |
| 265 | const gchar * location) |
| 266 | { |
| 267 | g_free (sink->filename); |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 268 | /* FIXME: validate location to have just one %d */ |
| 269 | sink->filename = g_strdup (location); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 270 | |
| 271 | return TRUE; |
| 272 | } |
Stefan Kost | a99d3f8 | 2009-01-28 12:29:42 +0200 | [diff] [blame] | 273 | |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 274 | static void |
| 275 | gst_multi_file_sink_set_property (GObject * object, guint prop_id, |
| 276 | const GValue * value, GParamSpec * pspec) |
| 277 | { |
| 278 | GstMultiFileSink *sink = GST_MULTI_FILE_SINK (object); |
| 279 | |
| 280 | switch (prop_id) { |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 281 | case PROP_LOCATION: |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 282 | gst_multi_file_sink_set_location (sink, g_value_get_string (value)); |
| 283 | break; |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 284 | case PROP_INDEX: |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 285 | sink->index = g_value_get_int (value); |
| 286 | break; |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 287 | case PROP_POST_MESSAGES: |
| 288 | sink->post_messages = g_value_get_boolean (value); |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 289 | break; |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 290 | case PROP_NEXT_FILE: |
| 291 | sink->next_file = g_value_get_enum (value); |
| 292 | break; |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 293 | default: |
| 294 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
| 295 | break; |
| 296 | } |
| 297 | } |
| 298 | |
| 299 | static void |
| 300 | gst_multi_file_sink_get_property (GObject * object, guint prop_id, |
| 301 | GValue * value, GParamSpec * pspec) |
| 302 | { |
| 303 | GstMultiFileSink *sink = GST_MULTI_FILE_SINK (object); |
| 304 | |
| 305 | switch (prop_id) { |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 306 | case PROP_LOCATION: |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 307 | g_value_set_string (value, sink->filename); |
| 308 | break; |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 309 | case PROP_INDEX: |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 310 | g_value_set_int (value, sink->index); |
| 311 | break; |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 312 | case PROP_POST_MESSAGES: |
| 313 | g_value_set_boolean (value, sink->post_messages); |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 314 | break; |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 315 | case PROP_NEXT_FILE: |
| 316 | g_value_set_enum (value, sink->next_file); |
| 317 | break; |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 318 | default: |
| 319 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
| 320 | break; |
| 321 | } |
| 322 | } |
| 323 | |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 324 | static gboolean |
| 325 | gst_multi_file_sink_stop (GstBaseSink * sink) |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 326 | { |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 327 | GstMultiFileSink *multifilesink; |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 328 | |
David Schleef | a088480 | 2007-10-25 23:42:52 +0000 | [diff] [blame] | 329 | multifilesink = GST_MULTI_FILE_SINK (sink); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 330 | |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 331 | if (multifilesink->file != NULL) { |
| 332 | fclose (multifilesink->file); |
| 333 | multifilesink->file = NULL; |
| 334 | } |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 335 | |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 336 | return TRUE; |
| 337 | } |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 338 | |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 339 | |
| 340 | static void |
| 341 | gst_multi_file_sink_post_message (GstMultiFileSink * multifilesink, |
| 342 | GstBuffer * buffer, const char *filename) |
| 343 | { |
Wim Taymans | 1935483 | 2009-09-11 13:12:54 +0200 | [diff] [blame] | 344 | if (multifilesink->post_messages) { |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 345 | GstClockTime duration, timestamp; |
| 346 | GstClockTime running_time, stream_time; |
| 347 | guint64 offset, offset_end; |
| 348 | GstStructure *s; |
| 349 | GstSegment *segment; |
| 350 | GstFormat format; |
| 351 | |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 352 | segment = &GST_BASE_SINK (multifilesink)->segment; |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 353 | format = segment->format; |
| 354 | |
| 355 | timestamp = GST_BUFFER_TIMESTAMP (buffer); |
| 356 | duration = GST_BUFFER_DURATION (buffer); |
| 357 | offset = GST_BUFFER_OFFSET (buffer); |
| 358 | offset_end = GST_BUFFER_OFFSET_END (buffer); |
| 359 | |
| 360 | running_time = gst_segment_to_running_time (segment, format, timestamp); |
| 361 | stream_time = gst_segment_to_stream_time (segment, format, timestamp); |
| 362 | |
| 363 | s = gst_structure_new ("GstMultiFileSink", |
| 364 | "filename", G_TYPE_STRING, filename, |
| 365 | "index", G_TYPE_INT, multifilesink->index, |
| 366 | "timestamp", G_TYPE_UINT64, timestamp, |
| 367 | "stream-time", G_TYPE_UINT64, stream_time, |
| 368 | "running-time", G_TYPE_UINT64, running_time, |
| 369 | "duration", G_TYPE_UINT64, duration, |
| 370 | "offset", G_TYPE_UINT64, offset, |
| 371 | "offset-end", G_TYPE_UINT64, offset_end, NULL); |
| 372 | |
| 373 | gst_element_post_message (GST_ELEMENT_CAST (multifilesink), |
| 374 | gst_message_new_element (GST_OBJECT_CAST (multifilesink), s)); |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 375 | } |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 376 | } |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 377 | |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 378 | static GstFlowReturn |
| 379 | gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer) |
| 380 | { |
| 381 | GstMultiFileSink *multifilesink; |
| 382 | guint size; |
| 383 | guint8 *data; |
| 384 | gchar *filename; |
| 385 | gboolean ret; |
| 386 | GError *error = NULL; |
| 387 | |
| 388 | size = GST_BUFFER_SIZE (buffer); |
| 389 | data = GST_BUFFER_DATA (buffer); |
| 390 | |
| 391 | multifilesink = GST_MULTI_FILE_SINK (sink); |
| 392 | |
| 393 | switch (multifilesink->next_file) { |
| 394 | case GST_MULTI_FILE_SINK_NEXT_BUFFER: |
| 395 | filename = g_strdup_printf (multifilesink->filename, |
| 396 | multifilesink->index); |
| 397 | |
| 398 | ret = g_file_set_contents (filename, (char *) data, size, &error); |
| 399 | if (!ret) |
| 400 | goto write_error; |
| 401 | |
| 402 | gst_multi_file_sink_post_message (multifilesink, buffer, filename); |
| 403 | multifilesink->index++; |
| 404 | |
| 405 | g_free (filename); |
| 406 | break; |
| 407 | case GST_MULTI_FILE_SINK_NEXT_DISCONT: |
| 408 | if (GST_BUFFER_IS_DISCONT (buffer)) { |
| 409 | if (multifilesink->file) { |
| 410 | fclose (multifilesink->file); |
| 411 | multifilesink->file = NULL; |
| 412 | |
| 413 | filename = g_strdup_printf (multifilesink->filename, |
| 414 | multifilesink->index); |
| 415 | gst_multi_file_sink_post_message (multifilesink, buffer, filename); |
| 416 | g_free (filename); |
| 417 | multifilesink->index++; |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | if (multifilesink->file == NULL) { |
| 422 | filename = g_strdup_printf (multifilesink->filename, |
| 423 | multifilesink->index); |
| 424 | multifilesink->file = g_fopen (filename, "wb"); |
| 425 | g_free (filename); |
| 426 | |
| 427 | if (multifilesink->file == NULL) |
| 428 | goto stdio_write_error; |
| 429 | } |
| 430 | |
| 431 | ret = fwrite (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 1, |
| 432 | multifilesink->file); |
| 433 | if (ret != 1) |
| 434 | goto stdio_write_error; |
| 435 | |
| 436 | break; |
| 437 | default: |
| 438 | g_assert_not_reached (); |
| 439 | } |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 440 | |
Wim Taymans | f68cd7e | 2009-09-11 12:16:18 +0200 | [diff] [blame] | 441 | return GST_FLOW_OK; |
| 442 | |
| 443 | /* ERRORS */ |
| 444 | write_error: |
| 445 | { |
| 446 | switch (error->code) { |
| 447 | case G_FILE_ERROR_NOSPC:{ |
| 448 | GST_ELEMENT_ERROR (multifilesink, RESOURCE, NO_SPACE_LEFT, (NULL), |
| 449 | (NULL)); |
| 450 | break; |
| 451 | } |
| 452 | default:{ |
| 453 | GST_ELEMENT_ERROR (multifilesink, RESOURCE, WRITE, |
| 454 | ("Error while writing to file \"%s\".", filename), |
| 455 | ("%s", g_strerror (errno))); |
| 456 | } |
| 457 | } |
| 458 | g_error_free (error); |
| 459 | g_free (filename); |
| 460 | |
| 461 | return GST_FLOW_ERROR; |
| 462 | } |
David Schleef | 78eeb66 | 2009-09-13 12:30:34 -0700 | [diff] [blame] | 463 | stdio_write_error: |
| 464 | GST_ELEMENT_ERROR (multifilesink, RESOURCE, WRITE, |
| 465 | ("Error while writing to file."), (NULL)); |
| 466 | return GST_FLOW_ERROR; |
David Schleef | 1126a88 | 2006-11-10 18:51:10 +0000 | [diff] [blame] | 467 | } |