• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2008-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
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 __MXF_DEMUX_H__
21 #define __MXF_DEMUX_H__
22 
23 #include <gst/gst.h>
24 #include <gst/base/gstadapter.h>
25 #include <gst/base/gstflowcombiner.h>
26 #include <gst/video/video.h>
27 
28 #include "mxfessence.h"
29 
30 G_BEGIN_DECLS
31 
32 #define GST_TYPE_MXF_DEMUX \
33   (gst_mxf_demux_get_type())
34 #define GST_MXF_DEMUX(obj) \
35   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MXF_DEMUX,GstMXFDemux))
36 #define GST_MXF_DEMUX_CLASS(klass) \
37   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MXF_DEMUX,GstMXFDemuxClass))
38 #define GST_IS_MXF_DEMUX(obj) \
39   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MXF_DEMUX))
40 #define GST_IS_MXF_DEMUX_CLASS(klass) \
41   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MXF_DEMUX))
42 typedef struct _GstMXFDemux GstMXFDemux;
43 typedef struct _GstMXFDemuxClass GstMXFDemuxClass;
44 
45 #define GST_TYPE_MXF_DEMUX_PAD (gst_mxf_demux_pad_get_type())
46 #define GST_MXF_DEMUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_CAST((pad),GST_TYPE_MXF_DEMUX_PAD,GstMXFDemuxPad))
47 #define GST_MXF_DEMUX_PAD_CAST(pad) ((GstMXFDemuxPad *) pad)
48 #define GST_IS_MXF_DEMUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_TYPE((pad),GST_TYPE_MXF_DEMUX_PAD))
49 typedef struct _GstMXFDemuxPad GstMXFDemuxPad;
50 typedef struct _GstMXFDemuxPadClass GstMXFDemuxPadClass;
51 
52 
53 /*
54  * GstMXFKLV is used to pass around information about a KLV.
55  *
56  * It optionally contains the content of the klv (data field).
57  */
58 typedef struct {
59   MXFUL key;
60   guint64 offset;               /* absolute offset of K */
61   gsize length;                 /* Size of data (i.e. V) */
62   guint64 data_offset;          /* relative offset of data (i.e. size of 'KL') */
63   GstBuffer *data;              /* Can be NULL in pull-mode. */
64 
65   /* For partial reads (ex: clip/custom wrapping essence), the amount of data
66    * already consumed within. If 0, all of length+data_offset was consumed */
67   guint64 consumed;
68 } GstMXFKLV;
69 
70 
71 typedef enum {
72   GST_MXF_DEMUX_STATE_UNKNOWN,	/* Still looking for run-in/klv */
73   GST_MXF_DEMUX_STATE_KLV,	/* Next read/fetch is a KLV */
74   GST_MXF_DEMUX_STATE_ESSENCE	/* Next read/fetch is within a KLV (i.e. non-frame-wrapped) */
75 } GstMXFDemuxState;
76 
77 typedef struct _GstMXFDemuxPartition GstMXFDemuxPartition;
78 typedef struct _GstMXFDemuxEssenceTrack GstMXFDemuxEssenceTrack;
79 
80 struct _GstMXFDemuxPartition
81 {
82   MXFPartitionPack partition;
83   MXFPrimerPack primer;
84   gboolean parsed_metadata;
85 
86   /* Relative offset at which essence starts within this partition.
87    *
88    * For Frame wrapping, the position of the first KLV
89    * For Clip/Custom wrapping, the position of the first byte of essence in the KLV
90    **/
91   guint64 essence_container_offset;
92 
93   /* If the partition contains a single essence track, point to it */
94   GstMXFDemuxEssenceTrack *single_track;
95 
96   /* For clip-based wrapping, the essence KLV */
97   GstMXFKLV clip_klv;
98 };
99 
100 #define MXF_INDEX_DELTA_ID_UNKNOWN -1
101 #define MXF_INDEX_DELTA_ID_IGNORE -2
102 
103 struct _GstMXFDemuxEssenceTrack
104 {
105   guint32 body_sid;
106   guint32 index_sid;
107   guint32 track_number;
108 
109   /* delta id, the position of this track in the container package delta table
110    * (if the track is in an interleaved essence container)
111    *
112    * Special values:
113    * * -1 Not discovered yet
114    * * -2 Ignore delta entry (if index table is not present or not complete)
115    */
116   gint32 delta_id;
117 
118   guint32 track_id;
119   MXFUMID source_package_uid;
120 
121   /* Position and duration in edit units */
122   gint64 position;
123   gint64 duration;
124 
125   GArray *offsets;
126 
127   MXFMetadataSourcePackage *source_package;
128   MXFMetadataTimelineTrack *source_track;
129 
130   gpointer mapping_data;
131   const MXFEssenceElementHandler *handler;
132   MXFEssenceElementHandleFunc handle_func;
133 
134   GstTagList *tags;
135 
136   GstCaps *caps;
137   gboolean intra_only;
138 
139   MXFEssenceWrapping wrapping;
140 
141   /* Minimum number of edit unit to send in one go.
142    * Default : 1
143    * Used for raw audio track */
144   guint min_edit_units;
145 };
146 
147 typedef struct
148 {
149   /* absolute byte offset excluding run_in, 0 if uninitialized */
150   guint64 offset;
151 
152   /* PTS edit unit number or G_MAXUINT64 */
153   guint64 pts;
154 
155   /* DTS edit unit number if we got here via PTS */
156   guint64 dts;
157 
158   /* Duration in edit units */
159   guint64 duration;
160 
161   gboolean keyframe;
162   gboolean initialized;
163 
164   /* Size, used for non-frame-wrapped content */
165   guint64 size;
166 } GstMXFDemuxIndex;
167 
168 typedef struct
169 {
170   guint32 body_sid;
171   guint32 index_sid;
172 
173   /* Array of MXFIndexTableSegment, sorted by DTS
174    * Note: Can be empty and can be sparse (i.e. not cover every edit unit) */
175   GArray *segments;
176 
177   /* Delta entry to which reordering should be applied (-1 == no reordering) */
178   gint reordered_delta_entry;
179 
180   /* Array of gint8 reverse temporal offsets.
181    * Contains the shift to apply to an entry DTS to get the PTS
182    *
183    * Can be NULL if the content doesn't have temporal shifts (i.e. all present
184    * entries have a temporal offset of 0) */
185   GArray *reverse_temporal_offsets;
186 
187   /* Greatest temporal offset value contained within offsets.
188    * Unsigned because the smallest value is 0 (no reordering)  */
189   guint max_temporal_offset;
190 } GstMXFDemuxIndexTable;
191 
192 struct _GstMXFDemuxPad
193 {
194   GstPad parent;
195 
196   guint32 track_id;
197   gboolean need_segment;
198 
199   GstClockTime position;
200   gdouble position_accumulated_error;
201   /* Current position in the material track (in edit units) */
202   gint64 current_material_track_position;
203 
204   gboolean eos, discont;
205 
206   GstTagList *tags;
207 
208   MXFMetadataGenericPackage *material_package;
209   MXFMetadataTimelineTrack *material_track;
210 
211   GstVideoTimeCode start_timecode;
212 
213   guint current_component_index;
214   MXFMetadataSourceClip *current_component;
215 
216   /* Position in the material track where this component started */
217   gint64 current_component_start_position;
218 
219   /* Position/duration in the source track */
220   gint64 current_component_start;
221   gint64 current_component_duration;
222 
223   /* Current essence track and position (in edit units) */
224   GstMXFDemuxEssenceTrack *current_essence_track;
225   gint64 current_essence_track_position;
226 };
227 
228 struct _GstMXFDemuxPadClass
229 {
230   GstPadClass parent;
231 };
232 
233 struct _GstMXFDemux
234 {
235   GstElement element;
236 
237   GstPad *sinkpad;
238   GPtrArray *src;
239 
240   /* < private > */
241   GstMXFDemuxState state;
242 
243   gboolean have_group_id;
244   guint group_id;
245 
246   GstAdapter *adapter;
247 
248   GstFlowCombiner *flowcombiner;
249 
250   GstSegment segment;
251   guint32 seqnum;
252 
253   GstEvent *close_seg_event;
254 
255   guint64 offset;
256 
257   gboolean random_access;
258   gboolean flushing;
259 
260   guint64 run_in;
261 
262   guint64 header_partition_pack_offset;
263   guint64 footer_partition_pack_offset;
264 
265   /* MXF file state */
266   GList *partitions;
267   GstMXFDemuxPartition *current_partition;
268 
269   GArray *essence_tracks;
270 
271   GList *pending_index_table_segments;
272   GList *index_tables; /* one per BodySID / IndexSID */
273   gboolean index_table_segments_collected;
274 
275   GArray *random_index_pack;
276 
277   /* Metadata */
278   GRWLock metadata_lock;
279   gboolean update_metadata;
280   gboolean pull_footer_metadata;
281 
282   gboolean metadata_resolved;
283   MXFMetadataPreface *preface;
284   GHashTable *metadata;
285 
286   /* Current Material Package */
287   MXFUMID current_package_uid;
288   MXFMetadataGenericPackage *current_package;
289   gchar *current_package_string;
290 
291   GstTagList *tags;
292 
293   /* Properties */
294   gchar *requested_package_string;
295   GstClockTime max_drift;
296 
297   /* Quirks */
298   gboolean temporal_order_misuse;
299 };
300 
301 struct _GstMXFDemuxClass
302 {
303   GstElementClass parent_class;
304 };
305 
306 GType gst_mxf_demux_get_type (void);
307 
308 G_END_DECLS
309 
310 #endif /* __MXF_DEMUX_H__ */
311