summaryrefslogtreecommitdiff
path: root/gst/matroska/ebml-read.h
blob: b40c31d352d563bb5c79425901ecc7800876b17c (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
/* GStreamer EBML I/O
 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 *
 * ebml-read.c: read EBML data from file/stream
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef __GST_EBML_READ_H__
#define __GST_EBML_READ_H__

#include <gst/gst.h>
#include <gst/base/gstbytereader.h>

G_BEGIN_DECLS

#define GST_TYPE_EBML_READ \
  (gst_ebml_read_get_type ())
#define GST_EBML_READ(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_EBML_READ, GstEbmlRead))
#define GST_EBML_READ_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_EBML_READ, GstEbmlReadClass))
#define GST_IS_EBML_READ(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EBML_READ))
#define GST_IS_EBML_READ_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_EBML_READ))
#define GST_EBML_READ_GET_CLASS(obj) \
  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_EBML_READ, GstEbmlReadClass))

GST_DEBUG_CATEGORY_EXTERN (ebmlread_debug);

/* custom flow return code */
#define  GST_FLOW_PARSE  GST_FLOW_CUSTOM_ERROR

typedef struct _GstEbmlMaster {
  guint64       offset;
  GstByteReader br;
} GstEbmlMaster;

typedef struct _GstEbmlRead {
  GstElement *el;

  GstBuffer *buf;
  guint64 offset;

  GArray *readers;
} GstEbmlRead;

typedef const guint8 * (*GstPeekData) (gpointer * context, guint peek);

/* returns UNEXPECTED if not enough data */
GstFlowReturn gst_ebml_peek_id_length    (guint32 * _id, guint64 * _length,
                                          guint * _needed,
                                          GstPeekData peek, gpointer * ctx,
                                          GstElement * el, guint64 offset);

void          gst_ebml_read_init         (GstEbmlRead * ebml,
                                          GstElement * el, GstBuffer * buf,
                                          guint64 offset);

void          gst_ebml_read_clear        (GstEbmlRead * ebml);

GstFlowReturn gst_ebml_peek_id           (GstEbmlRead * ebml, guint32 * id);

/* return _PARSE if not enough data to read what is needed, _ERROR or _OK */
GstFlowReturn gst_ebml_read_skip         (GstEbmlRead *ebml);

GstFlowReturn gst_ebml_read_buffer       (GstEbmlRead *ebml,
                                          guint32     *id,
                                          GstBuffer  **buf);

GstFlowReturn gst_ebml_read_uint         (GstEbmlRead *ebml,
                                          guint32     *id,
                                          guint64     *num);

GstFlowReturn gst_ebml_read_sint         (GstEbmlRead *ebml,
                                          guint32     *id,
                                          gint64      *num);

GstFlowReturn gst_ebml_read_float        (GstEbmlRead *ebml,
                                          guint32     *id,
                                          gdouble     *num);

GstFlowReturn gst_ebml_read_ascii        (GstEbmlRead *ebml,
                                          guint32     *id,
                                          gchar      **str);

GstFlowReturn gst_ebml_read_utf8         (GstEbmlRead *ebml,
                                          guint32     *id,
                                          gchar      **str);

GstFlowReturn gst_ebml_read_date         (GstEbmlRead *ebml,
                                          guint32     *id,
                                          gint64      *date);

GstFlowReturn gst_ebml_read_master       (GstEbmlRead *ebml,
                                          guint32     *id);

GstFlowReturn gst_ebml_read_pop_master   (GstEbmlRead *ebml);

GstFlowReturn gst_ebml_read_binary       (GstEbmlRead *ebml,
                                          guint32     *id,
                                          guint8     **binary,
                                          guint64     *length);

GstFlowReturn gst_ebml_read_header       (GstEbmlRead *read,
                                          gchar      **doctype,
                                          guint       *version);

/* Returns current (absolute) position of Ebml parser,
 * i.e. taking into account offset provided at init */
static inline guint64
gst_ebml_read_get_pos (GstEbmlRead * ebml)
{
  GstEbmlMaster *m;

  g_return_val_if_fail (ebml->readers, 0);
  g_return_val_if_fail (ebml->readers->len, 0);

  m = &(g_array_index (ebml->readers, GstEbmlMaster, ebml->readers->len - 1));
  return m->offset + gst_byte_reader_get_pos (&m->br);
}

/* Returns starting offset of Ebml parser */
static inline guint64
gst_ebml_read_get_offset (GstEbmlRead * ebml)
{
  return ebml->offset;
}

static inline GstByteReader *
gst_ebml_read_br (GstEbmlRead * ebml)
{
  g_return_val_if_fail (ebml->readers, NULL);
  g_return_val_if_fail (ebml->readers->len, NULL);

  return &(g_array_index (ebml->readers,
          GstEbmlMaster, ebml->readers->len - 1).br);
}

static inline gboolean
gst_ebml_read_has_remaining (GstEbmlRead * ebml, guint64 bytes_needed,
    gboolean auto_pop)
{
  gboolean res;

  res = (gst_byte_reader_get_remaining (gst_ebml_read_br (ebml)) >= bytes_needed);
  if (G_LIKELY (!res && auto_pop)) {
    gst_ebml_read_pop_master (ebml);
  }

  return G_LIKELY (res);
}

G_END_DECLS

#endif /* __GST_EBML_READ_H__ */