1 /* GStreamer split muxer bin
2 * Copyright (C) 2014 Jan Schmidt <jan@centricular.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 #ifndef __GST_SPLITMUXSINK_H__
21 #define __GST_SPLITMUXSINK_H__
24 #include <gst/pbutils/pbutils.h>
25 #include <gst/base/base.h>
28 #define GST_TYPE_SPLITMUX_SINK (gst_splitmux_sink_get_type())
29 #define GST_SPLITMUX_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPLITMUX_SINK,GstSplitMuxSink))
30 #define GST_SPLITMUX_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPLITMUX_SINK,GstSplitMuxSinkClass))
31 #define GST_IS_SPLITMUX_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPLITMUX_SINK))
32 #define GST_IS_SPLITMUX_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPLITMUX_SINK))
33 typedef struct _GstSplitMuxSink GstSplitMuxSink;
34 typedef struct _GstSplitMuxSinkClass GstSplitMuxSinkClass;
36 GType gst_splitmux_sink_get_type (void);
37 gboolean register_splitmuxsink (GstPlugin * plugin);
39 typedef enum _SplitMuxInputState
41 SPLITMUX_INPUT_STATE_STOPPED,
42 SPLITMUX_INPUT_STATE_COLLECTING_GOP_START, /* Waiting for the next ref ctx keyframe */
43 SPLITMUX_INPUT_STATE_WAITING_GOP_COLLECT, /* Waiting for all streams to collect GOP */
44 SPLITMUX_INPUT_STATE_FINISHING_UP /* Got EOS from reference ctx, send everything */
47 typedef enum _SplitMuxOutputState
49 SPLITMUX_OUTPUT_STATE_STOPPED,
50 SPLITMUX_OUTPUT_STATE_AWAITING_COMMAND, /* Waiting first command packet from input */
51 SPLITMUX_OUTPUT_STATE_OUTPUT_GOP, /* Outputting a collected GOP */
52 SPLITMUX_OUTPUT_STATE_ENDING_FILE, /* Finishing the current fragment */
53 SPLITMUX_OUTPUT_STATE_START_NEXT_FILE /* Restarting after ENDING_FILE */
54 } SplitMuxOutputState;
56 typedef struct _SplitMuxOutputCommand
58 gboolean start_new_fragment; /* Whether to start a new fragment before advancing output ts */
59 GstClockTimeDiff max_output_ts; /* Set the limit to stop GOP output */
60 } SplitMuxOutputCommand;
62 typedef struct _MqStreamBuf
65 GstClockTimeDiff run_ts;
67 GstClockTime duration;
70 typedef struct _MqStreamCtx
72 GstSplitMuxSink *splitmux;
75 guint sink_pad_block_id;
76 guint src_pad_block_id;
77 gulong fragment_block_id;
79 gboolean is_reference;
84 gboolean out_eos_async_done;
85 gboolean need_unblock;
88 GstSegment in_segment;
89 GstSegment out_segment;
91 GstClockTimeDiff in_running_time;
92 GstClockTimeDiff out_running_time;
94 GstBuffer *prev_in_keyframe; /* store keyframe for each GOP */
102 GstBuffer *cur_out_buffer;
103 GstEvent *pending_gap;
106 struct _GstSplitMuxSink
114 gdouble mux_overhead;
116 GstClockTime threshold_time;
117 guint64 threshold_bytes;
119 gboolean send_keyframe_requests;
120 gchar *threshold_timecode_str;
121 GstClockTime next_max_tc_time;
122 GstClockTime alignment_threshold;
124 gboolean reset_muxer;
129 GstElement *provided_muxer;
131 GstElement *provided_sink;
132 GstElement *active_sink;
134 gboolean ready_for_output;
141 SplitMuxInputState input_state;
142 GstClockTimeDiff max_in_running_time;
143 /* Number of bytes sent to the
144 * current fragment */
145 guint64 fragment_total_bytes;
146 /* Number of bytes we've collected into
147 * the GOP that's being collected */
148 guint64 gop_total_bytes;
149 /* Start time of the current fragment */
150 GstClockTimeDiff fragment_start_time;
151 /* Start time of the current GOP */
152 GstClockTimeDiff gop_start_time;
154 GQueue out_cmd_q; /* Queue of commands for output thread */
156 SplitMuxOutputState output_state;
157 GstClockTimeDiff max_out_running_time;
159 guint64 muxed_out_bytes;
161 MqStreamCtx *reference_ctx;
162 /* Count of queued keyframes in the reference ctx */
163 guint queued_keyframes;
165 gboolean switching_fragment;
169 gboolean need_async_start;
170 gboolean async_pending;
172 gboolean use_robust_muxing;
173 gboolean muxer_has_reserved_props;
175 gboolean split_requested;
176 gboolean do_split_next_gop;
177 GstQueueArray *times_to_split;
179 /* Async finalize options */
180 gboolean async_finalize;
181 gchar *muxer_factory;
182 GstStructure *muxer_properties;
184 GstStructure *sink_properties;
187 struct _GstSplitMuxSinkClass
189 GstBinClass parent_class;
192 void (*split_now) (GstSplitMuxSink * splitmux);
193 void (*split_after) (GstSplitMuxSink * splitmux);
194 void (*split_at_running_time) (GstSplitMuxSink * splitmux, GstClockTime split_time);
198 #endif /* __GST_SPLITMUXSINK_H__ */