summaryrefslogtreecommitdiff
path: root/gst/asfdemux/gstasfdemux.h
blob: daad917aaec396b87a2dc1ea22988ad2e2202895 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */


#ifndef __ASF_DEMUX_H__
#define __ASF_DEMUX_H__

#include <gst/gst.h>
#include <gst/base/gstadapter.h>
#include <gst/base/gstflowcombiner.h>

#include "asfheaders.h"

G_BEGIN_DECLS
  
#define GST_TYPE_ASF_DEMUX \
  (gst_asf_demux_get_type())
#define GST_ASF_DEMUX(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ASF_DEMUX,GstASFDemux))
#define GST_ASF_DEMUX_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ASF_DEMUX,GstASFDemuxClass))
#define GST_IS_ASF_DEMUX(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ASF_DEMUX))
#define GST_IS_ASF_DEMUX_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ASF_DEMUX))

GST_DEBUG_CATEGORY_EXTERN (asfdemux_dbg);
#define GST_CAT_DEFAULT asfdemux_dbg

typedef struct _GstASFDemux GstASFDemux;
typedef struct _GstASFDemuxClass GstASFDemuxClass;
typedef enum _GstASF3DMode GstASF3DMode;

typedef struct {
  guint32	packet;
  guint16	count;
} AsfSimpleIndexEntry;

typedef struct {
  AsfPayloadExtensionID   id : 16;  /* extension ID; the :16 makes sure the
                                     * struct gets packed into 4 bytes       */
  guint16                 len;      /* save this so we can skip unknown IDs  */
} AsfPayloadExtension;

/**
 * 3D Types for Media play
 */
enum _GstASF3DMode
{
  GST_ASF_3D_NONE = 0x00,

  //added, interim format - half
  GST_ASF_3D_SIDE_BY_SIDE_HALF_LR = 0x01,
  GST_ASF_3D_SIDE_BY_SIDE_HALF_RL = 0x02,
  GST_ASF_3D_TOP_AND_BOTTOM_HALF_LR = 0x03,
  GST_ASF_3D_TOP_AND_BOTTOM_HALF_RL = 0x04,
  GST_ASF_3D_DUAL_STREAM = 0x0D,                  /**< Full format*/
};

typedef struct
{
  gboolean        valid;               /* TRUE if structure is valid/filled */

  GstClockTime    start_time;
  GstClockTime    end_time;
  GstClockTime    avg_time_per_frame;
  guint32         data_bitrate;
  guint32         buffer_size;
  guint32         intial_buf_fullness;
  guint32         data_bitrate2;
  guint32         buffer_size2;
  guint32         intial_buf_fullness2;
  guint32         max_obj_size;
  guint32         flags;
  guint16         lang_idx;

  /* may be NULL if there are no extensions; otherwise, terminated by
   * an AsfPayloadExtension record with len 0 */
  AsfPayloadExtension  *payload_extensions;

  /* missing: stream names */
} AsfStreamExtProps;

typedef struct
{
  AsfStreamType      type;

  gboolean           active;  /* if the stream has been activated (pad added) */

  GstPad     *pad;
  guint16     id;

  /* video-only */
  gboolean    is_video;
  gboolean    fps_known;

  GstCaps    *caps;

  GstBuffer *streamheader;

  GstTagList *pending_tags;

  gboolean    discont;
  gboolean    first_buffer;

  /* Descrambler settings */
  guint8               span;
  guint16              ds_packet_size;
  guint16              ds_chunk_size;
  guint16              ds_data_size;

  /* for new parsing code */
  GArray         *payloads;  /* pending payloads */

  /* Video stream PAR & interlacing */
  guint8	par_x;
  guint8	par_y;
  gboolean      interlaced;

  /* extended stream properties (optional) */
  AsfStreamExtProps  ext_props;
  
  gboolean     inspect_payload;
} AsfStream;

typedef enum {
  GST_ASF_DEMUX_STATE_HEADER,
  GST_ASF_DEMUX_STATE_DATA,
  GST_ASF_DEMUX_STATE_INDEX
} GstASFDemuxState;

#define GST_ASF_DEMUX_NUM_VIDEO_PADS   16
#define GST_ASF_DEMUX_NUM_AUDIO_PADS   32
#define GST_ASF_DEMUX_NUM_STREAMS      32
#define GST_ASF_DEMUX_NUM_STREAM_IDS  127

struct _GstASFDemux {
  GstElement 	     element;

  GstPad            *sinkpad;

  gboolean           have_group_id;
  guint              group_id;

  GstAdapter        *adapter;
  GstTagList        *taglist;
  GstASFDemuxState   state;

  /* byte offset where the asf starts, which might not be zero on chained
   * asfs, index_offset and data_offset already are 'offseted' by base_offset */
  guint64            base_offset;

  guint64            index_offset; /* byte offset where index might be, or 0   */
  guint64            data_offset;  /* byte offset where packets start          */
  guint64            data_size;    /* total size of packet data in bytes, or 0 */
  guint64            num_packets;  /* total number of data packets, or 0       */
  gint64             packet;       /* current packet                           */
  guint              speed_packets; /* Known number of packets to get in one go*/

  gchar              **languages;
  guint                num_languages;

  GstCaps             *metadata;         /* metadata, for delayed parsing; one
                                          * structure ('stream-N') per stream */
  GstStructure	      *global_metadata;  /* metadata which isn't specific to one stream */
  GSList              *ext_stream_props; /* for delayed processing (buffers) */
  GSList              *mut_ex_streams;   /* mutually exclusive streams */

  guint32              num_audio_streams;
  guint32              num_video_streams;
  guint32              num_streams;
  AsfStream            stream[GST_ASF_DEMUX_NUM_STREAMS];
  gboolean             activated_streams;
  GstFlowCombiner     *flowcombiner;

  /* for chained asf handling, we need to hold the old asf streams until
   * we detect the new ones */
  AsfStream            old_stream[GST_ASF_DEMUX_NUM_STREAMS];
  gboolean             old_num_streams;

  GstClockTime         first_ts;        /* smallest timestamp found        */

  guint32              packet_size;
  guint64              play_time;

  guint64              preroll;

  gboolean             seekable;
  gboolean             broadcast;

  GstSegment           segment;          /* configured play segment                 */
  gboolean             accurate;

  gboolean             need_newsegment;  /* do we need to send a new-segment event? */
  guint32              segment_seqnum;   /* if the new segment must have this seqnum */
  GstClockTime         segment_ts;       /* streaming; timestamp for segment start */
  GstSegment           in_segment;       /* streaming; upstream segment info */
  GstClockTime         in_gap;           /* streaming; upstream initial segment gap for interpolation */
  gboolean             segment_running;  /* if we've started the current segment    */
  gboolean             streaming;        /* TRUE if we are operating chain-based    */
  GstClockTime         latency;

  /* for debugging only */
  gchar               *objpath;

  /* simple index, if available */
  GstClockTime         sidx_interval;    /* interval between entries in ns */
  guint                sidx_num_entries; /* number of index entries        */
  AsfSimpleIndexEntry *sidx_entries;     /* packet number for each entry   */
  
  GSList              *other_streams;    /* remember streams that are in header but have unknown type */

  /* parsing 3D */
  GstASF3DMode asf_3D_mode;
};

struct _GstASFDemuxClass {
  GstElementClass parent_class;
};

GType           gst_asf_demux_get_type (void);

AsfStream     * gst_asf_demux_get_stream (GstASFDemux * demux, guint16 id);

gboolean        gst_asf_demux_is_unknown_stream(GstASFDemux *demux, guint stream_num);

G_END_DECLS

#endif /* __ASF_DEMUX_H__ */