mp4 robust muxing: improve documentation and logging
[platform/upstream/gst-plugins-good.git] / gst / multifile / gstsplitmuxsink.h
1 /* GStreamer split muxer bin
2  * Copyright (C) 2014 Jan Schmidt <jan@centricular.com>
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #ifndef __GST_SPLITMUXSINK_H__
21 #define __GST_SPLITMUXSINK_H__
22
23 #include <gst/gst.h>
24 #include <gst/pbutils/pbutils.h>
25
26 G_BEGIN_DECLS
27 #define GST_TYPE_SPLITMUX_SINK               (gst_splitmux_sink_get_type())
28 #define GST_SPLITMUX_SINK(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPLITMUX_SINK,GstSplitMuxSink))
29 #define GST_SPLITMUX_SINK_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPLITMUX_SINK,GstSplitMuxSinkClass))
30 #define GST_IS_SPLITMUX_SINK(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPLITMUX_SINK))
31 #define GST_IS_SPLITMUX_SINK_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPLITMUX_SINK))
32 typedef struct _GstSplitMuxSink GstSplitMuxSink;
33 typedef struct _GstSplitMuxSinkClass GstSplitMuxSinkClass;
34
35 GType gst_splitmux_sink_get_type (void);
36 gboolean register_splitmuxsink (GstPlugin * plugin);
37
38 typedef enum _SplitMuxInputState
39 {
40   SPLITMUX_INPUT_STATE_STOPPED,
41   SPLITMUX_INPUT_STATE_COLLECTING_GOP_START,    /* Waiting for the next ref ctx keyframe */
42   SPLITMUX_INPUT_STATE_WAITING_GOP_COLLECT,     /* Waiting for all streams to collect GOP */
43   SPLITMUX_INPUT_STATE_FINISHING_UP             /* Got EOS from reference ctx, send everything */
44 } SplitMuxInputState;
45
46 typedef enum _SplitMuxOutputState
47 {
48   SPLITMUX_OUTPUT_STATE_STOPPED,
49   SPLITMUX_OUTPUT_STATE_AWAITING_COMMAND,       /* Waiting first command packet from input */
50   SPLITMUX_OUTPUT_STATE_OUTPUT_GOP,     /* Outputting a collected GOP */
51   SPLITMUX_OUTPUT_STATE_ENDING_FILE,    /* Finishing the current fragment */
52   SPLITMUX_OUTPUT_STATE_START_NEXT_FILE /* Restarting after ENDING_FILE */
53 } SplitMuxOutputState;
54
55 typedef struct _SplitMuxOutputCommand
56 {
57   gboolean start_new_fragment;  /* Whether to start a new fragment before advancing output ts */
58   GstClockTimeDiff max_output_ts;       /* Set the limit to stop GOP output */
59 } SplitMuxOutputCommand;
60
61 typedef struct _MqStreamBuf
62 {
63   gboolean keyframe;
64   GstClockTimeDiff run_ts;
65   guint64 buf_size;
66   GstClockTime duration;
67 } MqStreamBuf;
68
69 typedef struct _MqStreamCtx
70 {
71   GstSplitMuxSink *splitmux;
72
73   guint q_overrun_id;
74   guint sink_pad_block_id;
75   guint src_pad_block_id;
76   gulong fragment_block_id;
77
78   gboolean is_reference;
79
80   gboolean flushing;
81   gboolean in_eos;
82   gboolean out_eos;
83   gboolean out_eos_async_done;
84   gboolean need_unblock;
85   gboolean caps_change;
86
87   GstSegment in_segment;
88   GstSegment out_segment;
89
90   GstClockTimeDiff in_running_time;
91   GstClockTimeDiff out_running_time;
92
93   GstBuffer *prev_in_keyframe; /* store keyframe for each GOP */
94
95   GstElement *q;
96   GQueue queued_bufs;
97
98   GstPad *sinkpad;
99   GstPad *srcpad;
100
101   GstBuffer *cur_out_buffer;
102   GstEvent *pending_gap;
103 } MqStreamCtx;
104
105 struct _GstSplitMuxSink
106 {
107   GstBin parent;
108
109   GMutex lock;
110   GCond input_cond;
111   GCond output_cond;
112
113   gdouble mux_overhead;
114
115   GstClockTime threshold_time;
116   guint64 threshold_bytes;
117   guint max_files;
118   gboolean send_keyframe_requests;
119   gchar *threshold_timecode_str;
120   GstClockTime next_max_tc_time;
121   GstClockTime alignment_threshold;
122
123   gboolean reset_muxer;
124
125   GstElement *muxer;
126   GstElement *sink;
127
128   GstElement *provided_muxer;
129
130   GstElement *provided_sink;
131   GstElement *active_sink;
132
133   gboolean ready_for_output;
134
135   gchar *location;
136   guint fragment_id;
137
138   GList *contexts;
139
140   SplitMuxInputState input_state;
141   GstClockTimeDiff max_in_running_time;
142   /* Number of bytes sent to the
143    * current fragment */
144   guint64 fragment_total_bytes;
145   /* Number of bytes we've collected into
146    * the GOP that's being collected */
147   guint64 gop_total_bytes;
148   /* Start time of the current fragment */
149   GstClockTimeDiff fragment_start_time;
150   /* Start time of the current GOP */
151   GstClockTimeDiff gop_start_time;
152
153   GQueue out_cmd_q;             /* Queue of commands for output thread */
154
155   SplitMuxOutputState output_state;
156   GstClockTimeDiff max_out_running_time;
157
158   guint64 muxed_out_bytes;
159
160   MqStreamCtx *reference_ctx;
161   /* Count of queued keyframes in the reference ctx */
162   guint queued_keyframes;
163
164   gboolean switching_fragment;
165
166   gboolean have_video;
167
168   gboolean need_async_start;
169   gboolean async_pending;
170
171   gboolean use_robust_muxing;
172   gboolean muxer_has_reserved_props;
173
174   gboolean split_now;
175
176   /* Async finalize options */
177   gboolean async_finalize;
178   gchar *muxer_factory;
179   GstStructure *muxer_properties;
180   gchar *sink_factory;
181   GstStructure *sink_properties;
182 };
183
184 struct _GstSplitMuxSinkClass
185 {
186   GstBinClass parent_class;
187
188   /* actions */
189   void     (*split_now)   (GstSplitMuxSink * splitmux);
190 };
191
192 G_END_DECLS
193 #endif /* __GST_SPLITMUXSINK_H__ */