mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 05:31:15 +00:00
multifilesink: Add key-frame option to next-file
This allows segmenting of MPEG-TS files at key frames, which is exactly what is needed for Apple's HTTP streaming.
This commit is contained in:
parent
e31922913f
commit
acb6ebbc9a
2 changed files with 49 additions and 1 deletions
|
@ -162,6 +162,8 @@ gst_multi_file_sink_next_get_type (void)
|
|||
{GST_MULTI_FILE_SINK_NEXT_BUFFER, "New file for each buffer", "buffer"},
|
||||
{GST_MULTI_FILE_SINK_NEXT_DISCONT, "New file after each discontinuity",
|
||||
"discont"},
|
||||
{GST_MULTI_FILE_SINK_NEXT_KEY_FRAME, "New file at each key frame "
|
||||
"(Useful for MPEG-TS segmenting)", "key-frame"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -248,6 +250,8 @@ gst_multi_file_sink_init (GstMultiFileSink * multifilesink,
|
|||
multifilesink->post_messages = DEFAULT_POST_MESSAGES;
|
||||
|
||||
gst_base_sink_set_sync (GST_BASE_SINK (multifilesink), FALSE);
|
||||
|
||||
multifilesink->next_segment = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -428,6 +432,47 @@ gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
|
|||
goto stdio_write_error;
|
||||
}
|
||||
|
||||
ret = fwrite (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 1,
|
||||
multifilesink->file);
|
||||
if (ret != 1)
|
||||
goto stdio_write_error;
|
||||
|
||||
break;
|
||||
case GST_MULTI_FILE_SINK_NEXT_KEY_FRAME:
|
||||
if (multifilesink->next_segment == GST_CLOCK_TIME_NONE) {
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
|
||||
multifilesink->next_segment = GST_BUFFER_TIMESTAMP (buffer) +
|
||||
10 * GST_SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
|
||||
GST_BUFFER_TIMESTAMP (buffer) >= multifilesink->next_segment &&
|
||||
!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
|
||||
if (multifilesink->file) {
|
||||
fclose (multifilesink->file);
|
||||
multifilesink->file = NULL;
|
||||
|
||||
filename = g_strdup_printf (multifilesink->filename,
|
||||
multifilesink->index);
|
||||
gst_multi_file_sink_post_message (multifilesink, buffer, filename);
|
||||
g_free (filename);
|
||||
multifilesink->index++;
|
||||
}
|
||||
|
||||
multifilesink->next_segment += 10 * GST_SECOND;
|
||||
}
|
||||
|
||||
if (multifilesink->file == NULL) {
|
||||
filename = g_strdup_printf (multifilesink->filename,
|
||||
multifilesink->index);
|
||||
multifilesink->file = g_fopen (filename, "wb");
|
||||
g_free (filename);
|
||||
|
||||
if (multifilesink->file == NULL)
|
||||
goto stdio_write_error;
|
||||
}
|
||||
|
||||
ret = fwrite (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 1,
|
||||
multifilesink->file);
|
||||
if (ret != 1)
|
||||
|
|
|
@ -53,7 +53,8 @@ typedef struct _GstMultiFileSinkClass GstMultiFileSinkClass;
|
|||
|
||||
typedef enum {
|
||||
GST_MULTI_FILE_SINK_NEXT_BUFFER,
|
||||
GST_MULTI_FILE_SINK_NEXT_DISCONT
|
||||
GST_MULTI_FILE_SINK_NEXT_DISCONT,
|
||||
GST_MULTI_FILE_SINK_NEXT_KEY_FRAME
|
||||
} GstMultiFileSinkNext;
|
||||
|
||||
struct _GstMultiFileSink
|
||||
|
@ -65,6 +66,8 @@ struct _GstMultiFileSink
|
|||
gboolean post_messages;
|
||||
GstMultiFileSinkNext next_file;
|
||||
FILE *file;
|
||||
|
||||
gint64 next_segment;
|
||||
};
|
||||
|
||||
struct _GstMultiFileSinkClass
|
||||
|
|
Loading…
Reference in a new issue