1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
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 
21 #ifndef __ASF_DEMUX_H__
22 #define __ASF_DEMUX_H__
23 
24 #include <gst/gst.h>
25 #include <gst/base/gstadapter.h>
26 #include <gst/base/gstflowcombiner.h>
27 
28 #include "asfheaders.h"
29 
30 G_BEGIN_DECLS
31 
32 #define GST_TYPE_ASF_DEMUX \
33   (gst_asf_demux_get_type())
34 #define GST_ASF_DEMUX(obj) \
35   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ASF_DEMUX,GstASFDemux))
36 #define GST_ASF_DEMUX_CLASS(klass) \
37   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ASF_DEMUX,GstASFDemuxClass))
38 #define GST_IS_ASF_DEMUX(obj) \
39   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ASF_DEMUX))
40 #define GST_IS_ASF_DEMUX_CLASS(klass) \
41   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ASF_DEMUX))
42 
43 GST_DEBUG_CATEGORY_EXTERN (asfdemux_dbg);
44 #define GST_CAT_DEFAULT asfdemux_dbg
45 
46 typedef struct _GstASFDemux GstASFDemux;
47 typedef struct _GstASFDemuxClass GstASFDemuxClass;
48 typedef enum _GstASF3DMode GstASF3DMode;
49 
50 typedef struct {
51   guint32	packet;
52   guint16	count;
53 } AsfSimpleIndexEntry;
54 
55 typedef struct {
56   AsfPayloadExtensionID   id : 16;  /* extension ID; the :16 makes sure the
57                                      * struct gets packed into 4 bytes       */
58   guint16                 len;      /* save this so we can skip unknown IDs  */
59 } AsfPayloadExtension;
60 
61 /**
62  * 3D Types for Media play
63  */
64 enum _GstASF3DMode
65 {
66   GST_ASF_3D_NONE = 0x00,
67 
68   //added, interim format - half
69   GST_ASF_3D_SIDE_BY_SIDE_HALF_LR = 0x01,
70   GST_ASF_3D_SIDE_BY_SIDE_HALF_RL = 0x02,
71   GST_ASF_3D_TOP_AND_BOTTOM_HALF_LR = 0x03,
72   GST_ASF_3D_TOP_AND_BOTTOM_HALF_RL = 0x04,
73   GST_ASF_3D_DUAL_STREAM = 0x0D,                  /**< Full format*/
74 };
75 
76 typedef struct
77 {
78   gboolean        valid;               /* TRUE if structure is valid/filled */
79 
80   GstClockTime    start_time;
81   GstClockTime    end_time;
82   GstClockTime    avg_time_per_frame;
83   guint32         data_bitrate;
84   guint32         buffer_size;
85   guint32         intial_buf_fullness;
86   guint32         data_bitrate2;
87   guint32         buffer_size2;
88   guint32         intial_buf_fullness2;
89   guint32         max_obj_size;
90   guint32         flags;
91   guint16         lang_idx;
92 
93   /* may be NULL if there are no extensions; otherwise, terminated by
94    * an AsfPayloadExtension record with len 0 */
95   AsfPayloadExtension  *payload_extensions;
96 
97   /* missing: stream names */
98 } AsfStreamExtProps;
99 
100 typedef struct
101 {
102   AsfStreamType      type;
103 
104   gboolean           active;  /* if the stream has been activated (pad added) */
105 
106   GstPad     *pad;
107   guint16     id;
108 
109   /* video-only */
110   gboolean    is_video;
111   gboolean    fps_known;
112 
113   GstCaps    *caps;
114 
115   GstBuffer *streamheader;
116 
117   GstTagList *pending_tags;
118 
119   gboolean    discont;
120   gboolean    first_buffer;
121 
122   /* Descrambler settings */
123   guint8               span;
124   guint16              ds_packet_size;
125   guint16              ds_chunk_size;
126   guint16              ds_data_size;
127 
128   /* for new parsing code */
129   GArray         *payloads;  /* pending payloads */
130 
131   /* Video stream PAR & interlacing */
132   guint8	par_x;
133   guint8	par_y;
134   gboolean      interlaced;
135 
136   /* For reverse playback */
137   gboolean	reverse_kf_ready; /* Found complete KF payload*/
138   GArray	*payloads_rev; /* Temp queue for storing multiple payloads of packet*/
139   gint		kf_pos; /* KF position in payload queue. Payloads from this pos will be pushed */
140 
141   /* extended stream properties (optional) */
142   AsfStreamExtProps  ext_props;
143 
144   gboolean     inspect_payload;
145 } AsfStream;
146 
147 typedef enum {
148   GST_ASF_DEMUX_STATE_HEADER,
149   GST_ASF_DEMUX_STATE_DATA,
150   GST_ASF_DEMUX_STATE_INDEX
151 } GstASFDemuxState;
152 
153 #define GST_ASF_DEMUX_IS_REVERSE_PLAYBACK(seg) (seg.rate < 0.0? TRUE:FALSE)
154 
155 #define GST_ASF_DEMUX_NUM_VIDEO_PADS   16
156 #define GST_ASF_DEMUX_NUM_AUDIO_PADS   32
157 #define GST_ASF_DEMUX_NUM_STREAMS      32
158 #define GST_ASF_DEMUX_NUM_STREAM_IDS  127
159 
160 struct _GstASFDemux {
161   GstElement 	     element;
162 
163   GstPad            *sinkpad;
164 
165   gboolean           have_group_id;
166   guint              group_id;
167 
168   GstAdapter        *adapter;
169   GstTagList        *taglist;
170   GstASFDemuxState   state;
171 
172   /* byte offset where the asf starts, which might not be zero on chained
173    * asfs, index_offset and data_offset already are 'offseted' by base_offset */
174   guint64            base_offset;
175 
176   guint64            index_offset; /* byte offset where index might be, or 0   */
177   guint64            data_offset;  /* byte offset where packets start          */
178   guint64            data_size;    /* total size of packet data in bytes, or 0 */
179   guint64            num_packets;  /* total number of data packets, or 0       */
180   gint64             packet;       /* current packet                           */
181   guint              speed_packets; /* Known number of packets to get in one go*/
182 
183   gchar              **languages;
184   guint                num_languages;
185 
186   GstCaps             *metadata;         /* metadata, for delayed parsing; one
187                                           * structure ('stream-N') per stream */
188   GstStructure	      *global_metadata;  /* metadata which isn't specific to one stream */
189   GSList              *ext_stream_props; /* for delayed processing (buffers) */
190   GSList              *mut_ex_streams;   /* mutually exclusive streams */
191 
192   guint32              num_audio_streams;
193   guint32              num_video_streams;
194   guint32              num_streams;
195   AsfStream            stream[GST_ASF_DEMUX_NUM_STREAMS];
196   gboolean             activated_streams;
197   GstFlowCombiner     *flowcombiner;
198 
199   /* for chained asf handling, we need to hold the old asf streams until
200    * we detect the new ones */
201   AsfStream            old_stream[GST_ASF_DEMUX_NUM_STREAMS];
202   gboolean             old_num_streams;
203 
204   GstClockTime         first_ts;        /* smallest timestamp found        */
205 
206   guint32              packet_size;
207   guint64              play_time;
208 
209   guint64              preroll;
210 
211   gboolean             seekable;
212   gboolean             broadcast;
213 
214   GstSegment           segment;          /* configured play segment                 */
215   gboolean             keyunit_sync;
216   gboolean             accurate;
217 
218   gboolean             need_newsegment;  /* do we need to send a new-segment event? */
219   guint32              segment_seqnum;   /* if the new segment must have this seqnum */
220   GstClockTime         segment_ts;       /* streaming; timestamp for segment start */
221   GstSegment           in_segment;       /* streaming; upstream segment info */
222   GstClockTime         in_gap;           /* streaming; upstream initial segment gap for interpolation */
223   gboolean             segment_running;  /* if we've started the current segment    */
224   gboolean             streaming;        /* TRUE if we are operating chain-based    */
225   GstClockTime         latency;
226 
227   /* for debugging only */
228   gchar               *objpath;
229 
230   /* simple index, if available */
231   GstClockTime         sidx_interval;    /* interval between entries in ns */
232   guint                sidx_num_entries; /* number of index entries        */
233   AsfSimpleIndexEntry *sidx_entries;     /* packet number for each entry   */
234 
235   GSList              *other_streams;    /* remember streams that are in header but have unknown type */
236 
237   /* For reverse playback */
238   gboolean             seek_to_cur_pos; /* Search packets till we reach 'seek' time */
239   gboolean             multiple_payloads; /* Whether packet has multiple payloads */
240 
241   /* parsing 3D */
242   GstASF3DMode asf_3D_mode;
243 
244   gboolean saw_file_header;
245 };
246 
247 struct _GstASFDemuxClass {
248   GstElementClass parent_class;
249 };
250 
251 GType           gst_asf_demux_get_type (void);
252 
253 AsfStream     * gst_asf_demux_get_stream (GstASFDemux * demux, guint16 id);
254 
255 gboolean        gst_asf_demux_is_unknown_stream(GstASFDemux *demux, guint stream_num);
256 
257 G_END_DECLS
258 
259 #endif /* __ASF_DEMUX_H__ */
260