matroska: refactor code common to matroskademux and matroskaparse
[gstreamer-omap:gst-plugins-good.git] / gst / matroska / matroska-read-common.c
1 /* GStreamer Matroska muxer/demuxer
2  * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  * (c) 2006 Tim-Philipp Müller <tim centricular net>
4  * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5  * (c) 2011 Debarshi Ray <rishi@gnu.org>
6  *
7  * matroska-read-common.c: shared by matroska file/stream demuxer and parser
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <string.h>
30
31 #ifdef HAVE_ZLIB
32 #include <zlib.h>
33 #endif
34
35 #ifdef HAVE_BZ2
36 #include <bzlib.h>
37 #endif
38
39 #include "lzo.h"
40
41 #include "ebml-read.h"
42 #include "matroska-read-common.h"
43
44 GST_DEBUG_CATEGORY_STATIC (matroskareadcommon_debug);
45 #define GST_CAT_DEFAULT matroskareadcommon_debug
46
47 #define DEBUG_ELEMENT_START(common, ebml, element) \
48     GST_DEBUG_OBJECT (common, "Parsing " element " element at offset %" \
49         G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
50
51 #define DEBUG_ELEMENT_STOP(common, ebml, element, ret) \
52     GST_DEBUG_OBJECT (common, "Parsing " element " element " \
53         " finished with '%s'", gst_flow_get_name (ret))
54
55 GstFlowReturn
56 gst_matroska_decode_content_encodings (GArray * encodings)
57 {
58   gint i;
59
60   if (encodings == NULL)
61     return GST_FLOW_OK;
62
63   for (i = 0; i < encodings->len; i++) {
64     GstMatroskaTrackEncoding *enc =
65         &g_array_index (encodings, GstMatroskaTrackEncoding, i);
66     guint8 *data = NULL;
67     guint size;
68
69     if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
70         == 0)
71       continue;
72
73     /* Encryption not supported yet */
74     if (enc->type != 0)
75       return GST_FLOW_ERROR;
76
77     if (i + 1 >= encodings->len)
78       return GST_FLOW_ERROR;
79
80     if (enc->comp_settings_length == 0)
81       continue;
82
83     data = enc->comp_settings;
84     size = enc->comp_settings_length;
85
86     if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
87       return GST_FLOW_ERROR;
88
89     g_free (enc->comp_settings);
90
91     enc->comp_settings = data;
92     enc->comp_settings_length = size;
93   }
94
95   return GST_FLOW_OK;
96 }
97
98 gboolean
99 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
100     guint8 ** data_out, guint * size_out,
101     GstMatroskaTrackCompressionAlgorithm algo)
102 {
103   guint8 *new_data = NULL;
104   guint new_size = 0;
105   guint8 *data = *data_out;
106   guint size = *size_out;
107   gboolean ret = TRUE;
108
109   if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
110 #ifdef HAVE_ZLIB
111     /* zlib encoded data */
112     z_stream zstream;
113     guint orig_size;
114     int result;
115
116     orig_size = size;
117     zstream.zalloc = (alloc_func) 0;
118     zstream.zfree = (free_func) 0;
119     zstream.opaque = (voidpf) 0;
120     if (inflateInit (&zstream) != Z_OK) {
121       GST_WARNING ("zlib initialization failed.");
122       ret = FALSE;
123       goto out;
124     }
125     zstream.next_in = (Bytef *) data;
126     zstream.avail_in = orig_size;
127     new_size = orig_size;
128     new_data = g_malloc (new_size);
129     zstream.avail_out = new_size;
130     zstream.next_out = (Bytef *) new_data;
131
132     do {
133       result = inflate (&zstream, Z_NO_FLUSH);
134       if (result != Z_OK && result != Z_STREAM_END) {
135         GST_WARNING ("zlib decompression failed.");
136         g_free (new_data);
137         inflateEnd (&zstream);
138         break;
139       }
140       new_size += 4000;
141       new_data = g_realloc (new_data, new_size);
142       zstream.next_out = (Bytef *) (new_data + zstream.total_out);
143       zstream.avail_out += 4000;
144     } while (zstream.avail_in != 0 && result != Z_STREAM_END);
145
146     if (result != Z_STREAM_END) {
147       ret = FALSE;
148       goto out;
149     } else {
150       new_size = zstream.total_out;
151       inflateEnd (&zstream);
152     }
153 #else
154     GST_WARNING ("zlib encoded tracks not supported.");
155     ret = FALSE;
156     goto out;
157 #endif
158   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
159 #ifdef HAVE_BZ2
160     /* bzip2 encoded data */
161     bz_stream bzstream;
162     guint orig_size;
163     int result;
164
165     bzstream.bzalloc = NULL;
166     bzstream.bzfree = NULL;
167     bzstream.opaque = NULL;
168     orig_size = size;
169
170     if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
171       GST_WARNING ("bzip2 initialization failed.");
172       ret = FALSE;
173       goto out;
174     }
175
176     bzstream.next_in = (char *) data;
177     bzstream.avail_in = orig_size;
178     new_size = orig_size;
179     new_data = g_malloc (new_size);
180     bzstream.avail_out = new_size;
181     bzstream.next_out = (char *) new_data;
182
183     do {
184       result = BZ2_bzDecompress (&bzstream);
185       if (result != BZ_OK && result != BZ_STREAM_END) {
186         GST_WARNING ("bzip2 decompression failed.");
187         g_free (new_data);
188         BZ2_bzDecompressEnd (&bzstream);
189         break;
190       }
191       new_size += 4000;
192       new_data = g_realloc (new_data, new_size);
193       bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
194       bzstream.avail_out += 4000;
195     } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
196
197     if (result != BZ_STREAM_END) {
198       ret = FALSE;
199       goto out;
200     } else {
201       new_size = bzstream.total_out_lo32;
202       BZ2_bzDecompressEnd (&bzstream);
203     }
204 #else
205     GST_WARNING ("bzip2 encoded tracks not supported.");
206     ret = FALSE;
207     goto out;
208 #endif
209   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
210     /* lzo encoded data */
211     int result;
212     int orig_size, out_size;
213
214     orig_size = size;
215     out_size = size;
216     new_size = size;
217     new_data = g_malloc (new_size);
218
219     do {
220       orig_size = size;
221       out_size = new_size;
222
223       result = lzo1x_decode (new_data, &out_size, data, &orig_size);
224
225       if (orig_size > 0) {
226         new_size += 4000;
227         new_data = g_realloc (new_data, new_size);
228       }
229     } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
230
231     new_size -= out_size;
232
233     if (result != LZO_OUTPUT_FULL) {
234       GST_WARNING ("lzo decompression failed");
235       g_free (new_data);
236
237       ret = FALSE;
238       goto out;
239     }
240
241   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
242     /* header stripped encoded data */
243     if (enc->comp_settings_length > 0) {
244       new_data = g_malloc (size + enc->comp_settings_length);
245       new_size = size + enc->comp_settings_length;
246
247       memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
248       memcpy (new_data + enc->comp_settings_length, data, size);
249     }
250   } else {
251     GST_ERROR ("invalid compression algorithm %d", algo);
252     ret = FALSE;
253   }
254
255 out:
256
257   if (!ret) {
258     *data_out = NULL;
259     *size_out = 0;
260   } else {
261     *data_out = new_data;
262     *size_out = new_size;
263   }
264
265   return ret;
266 }
267
268 static gint
269 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
270 {
271   if (i1->time < i2->time)
272     return -1;
273   else if (i1->time > i2->time)
274     return 1;
275   else if (i1->block < i2->block)
276     return -1;
277   else if (i1->block > i2->block)
278     return 1;
279   else
280     return 0;
281 }
282
283 static gint
284 gst_matroska_read_common_encoding_cmp (GstMatroskaTrackEncoding * a,
285     GstMatroskaTrackEncoding * b)
286 {
287   if (b->order > a->order)
288     return 1;
289   else if (b->order < a->order)
290     return -1;
291   else
292     return 0;
293 }
294
295 static gboolean
296 gst_matroska_read_common_encoding_order_unique (GArray * encodings, guint64
297     order)
298 {
299   gint i;
300
301   if (encodings == NULL || encodings->len == 0)
302     return TRUE;
303
304   for (i = 0; i < encodings->len; i++)
305     if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
306       return FALSE;
307
308   return TRUE;
309 }
310
311 gint64
312 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common)
313 {
314   GstFormat fmt = GST_FORMAT_BYTES;
315   gint64 end = -1;
316
317   if (!gst_pad_query_peer_duration (common->sinkpad, &fmt, &end) ||
318       fmt != GST_FORMAT_BYTES || end < 0)
319     GST_DEBUG_OBJECT (common, "no upstream length");
320
321   return end;
322 }
323
324 /* skip unknown or alike element */
325 GstFlowReturn
326 gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
327     GstEbmlRead * ebml, const gchar * parent_name, guint id)
328 {
329   if (id == GST_EBML_ID_VOID) {
330     GST_DEBUG_OBJECT (common, "Skipping EBML Void element");
331   } else if (id == GST_EBML_ID_CRC32) {
332     GST_DEBUG_OBJECT (common, "Skipping EBML CRC32 element");
333   } else {
334     GST_WARNING_OBJECT (common,
335         "Unknown %s subelement 0x%x - ignoring", parent_name, id);
336   }
337
338   return gst_ebml_read_skip (ebml);
339 }
340
341 static GstFlowReturn
342 gst_matroska_read_common_parse_index_cuetrack (GstMatroskaReadCommon * common,
343     GstEbmlRead * ebml, guint * nentries)
344 {
345   guint32 id;
346   GstFlowReturn ret;
347   GstMatroskaIndex idx;
348
349   idx.pos = (guint64) - 1;
350   idx.track = 0;
351   idx.time = GST_CLOCK_TIME_NONE;
352   idx.block = 1;
353
354   DEBUG_ELEMENT_START (common, ebml, "CueTrackPositions");
355
356   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
357     DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
358     return ret;
359   }
360
361   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
362     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
363       break;
364
365     switch (id) {
366         /* track number */
367       case GST_MATROSKA_ID_CUETRACK:
368       {
369         guint64 num;
370
371         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
372           break;
373
374         if (num == 0) {
375           idx.track = 0;
376           GST_WARNING_OBJECT (common, "Invalid CueTrack 0");
377           break;
378         }
379
380         GST_DEBUG_OBJECT (common, "CueTrack: %" G_GUINT64_FORMAT, num);
381         idx.track = num;
382         break;
383       }
384
385         /* position in file */
386       case GST_MATROSKA_ID_CUECLUSTERPOSITION:
387       {
388         guint64 num;
389
390         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
391           break;
392
393         if (num > G_MAXINT64) {
394           GST_WARNING_OBJECT (common, "CueClusterPosition %" G_GUINT64_FORMAT
395               " too large", num);
396           break;
397         }
398
399         idx.pos = num;
400         break;
401       }
402
403         /* number of block in the cluster */
404       case GST_MATROSKA_ID_CUEBLOCKNUMBER:
405       {
406         guint64 num;
407
408         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
409           break;
410
411         if (num == 0) {
412           GST_WARNING_OBJECT (common, "Invalid CueBlockNumber 0");
413           break;
414         }
415
416         GST_DEBUG_OBJECT (common, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
417         idx.block = num;
418
419         /* mild sanity check, disregard strange cases ... */
420         if (idx.block > G_MAXUINT16) {
421           GST_DEBUG_OBJECT (common, "... looks suspicious, ignoring");
422           idx.block = 1;
423         }
424         break;
425       }
426
427       default:
428         ret = gst_matroska_read_common_parse_skip (common, ebml,
429             "CueTrackPositions", id);
430         break;
431
432       case GST_MATROSKA_ID_CUECODECSTATE:
433       case GST_MATROSKA_ID_CUEREFERENCE:
434         ret = gst_ebml_read_skip (ebml);
435         break;
436     }
437   }
438
439   DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
440
441   if ((ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
442       && idx.pos != (guint64) - 1 && idx.track > 0) {
443     g_array_append_val (common->index, idx);
444     (*nentries)++;
445   } else if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED) {
446     GST_DEBUG_OBJECT (common, "CueTrackPositions without valid content");
447   }
448
449   return ret;
450 }
451
452 static GstFlowReturn
453 gst_matroska_read_common_parse_index_pointentry (GstMatroskaReadCommon *
454     common, GstEbmlRead * ebml)
455 {
456   guint32 id;
457   GstFlowReturn ret;
458   GstClockTime time = GST_CLOCK_TIME_NONE;
459   guint nentries = 0;
460
461   DEBUG_ELEMENT_START (common, ebml, "CuePoint");
462
463   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
464     DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
465     return ret;
466   }
467
468   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
469     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
470       break;
471
472     switch (id) {
473         /* one single index entry ('point') */
474       case GST_MATROSKA_ID_CUETIME:
475       {
476         if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
477           break;
478
479         GST_DEBUG_OBJECT (common, "CueTime: %" G_GUINT64_FORMAT, time);
480         time = time * common->time_scale;
481         break;
482       }
483
484         /* position in the file + track to which it belongs */
485       case GST_MATROSKA_ID_CUETRACKPOSITIONS:
486       {
487         if ((ret =
488                 gst_matroska_read_common_parse_index_cuetrack (common, ebml,
489                     &nentries)) != GST_FLOW_OK)
490           break;
491         break;
492       }
493
494       default:
495         ret = gst_matroska_read_common_parse_skip (common, ebml, "CuePoint",
496             id);
497         break;
498     }
499   }
500
501   DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
502
503   if (nentries > 0) {
504     if (time == GST_CLOCK_TIME_NONE) {
505       GST_WARNING_OBJECT (common, "CuePoint without valid time");
506       g_array_remove_range (common->index, common->index->len - nentries,
507           nentries);
508     } else {
509       gint i;
510
511       for (i = common->index->len - nentries; i < common->index->len; i++) {
512         GstMatroskaIndex *idx =
513             &g_array_index (common->index, GstMatroskaIndex, i);
514
515         idx->time = time;
516         GST_DEBUG_OBJECT (common, "Index entry: pos=%" G_GUINT64_FORMAT
517             ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
518             GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
519       }
520     }
521   } else {
522     GST_DEBUG_OBJECT (common, "Empty CuePoint");
523   }
524
525   return ret;
526 }
527
528 gint
529 gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common,
530     guint track_num)
531 {
532   guint n;
533
534   g_assert (common->src->len == common->num_streams);
535   for (n = 0; n < common->src->len; n++) {
536     GstMatroskaTrackContext *context = g_ptr_array_index (common->src, n);
537
538     if (context->num == track_num) {
539       return n;
540     }
541   }
542
543   if (n == common->num_streams)
544     GST_WARNING_OBJECT (common,
545         "Failed to find corresponding pad for tracknum %d", track_num);
546
547   return -1;
548 }
549
550 GstFlowReturn
551 gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
552     GstEbmlRead * ebml)
553 {
554   guint32 id;
555   GstFlowReturn ret = GST_FLOW_OK;
556   guint i;
557
558   if (common->index)
559     g_array_free (common->index, TRUE);
560   common->index =
561       g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
562
563   DEBUG_ELEMENT_START (common, ebml, "Cues");
564
565   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
566     DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
567     return ret;
568   }
569
570   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
571     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
572       break;
573
574     switch (id) {
575         /* one single index entry ('point') */
576       case GST_MATROSKA_ID_POINTENTRY:
577         ret = gst_matroska_read_common_parse_index_pointentry (common, ebml);
578         break;
579
580       default:
581         ret = gst_matroska_read_common_parse_skip (common, ebml, "Cues", id);
582         break;
583     }
584   }
585   DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
586
587   /* Sort index by time, smallest time first, for easier searching */
588   g_array_sort (common->index, (GCompareFunc) gst_matroska_index_compare);
589
590   /* Now sort the track specific index entries into their own arrays */
591   for (i = 0; i < common->index->len; i++) {
592     GstMatroskaIndex *idx = &g_array_index (common->index, GstMatroskaIndex,
593         i);
594     gint track_num;
595     GstMatroskaTrackContext *ctx;
596
597     if (common->element_index) {
598       gint writer_id;
599
600       if (idx->track != 0 &&
601           (track_num =
602               gst_matroska_read_common_stream_from_num (common,
603                   idx->track)) != -1) {
604         ctx = g_ptr_array_index (common->src, track_num);
605
606         if (ctx->index_writer_id == -1)
607           gst_index_get_writer_id (common->element_index,
608               GST_OBJECT (ctx->pad), &ctx->index_writer_id);
609         writer_id = ctx->index_writer_id;
610       } else {
611         if (common->element_index_writer_id == -1)
612           gst_index_get_writer_id (common->element_index, GST_OBJECT (common),
613               &common->element_index_writer_id);
614         writer_id = common->element_index_writer_id;
615       }
616
617       GST_LOG_OBJECT (common, "adding association %" GST_TIME_FORMAT "-> %"
618           G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
619           idx->pos, writer_id);
620       gst_index_add_association (common->element_index, writer_id,
621           GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
622           GST_FORMAT_BYTES, idx->pos + common->ebml_segment_start, NULL);
623     }
624
625     if (idx->track == 0)
626       continue;
627
628     track_num = gst_matroska_read_common_stream_from_num (common, idx->track);
629     if (track_num == -1)
630       continue;
631
632     ctx = g_ptr_array_index (common->src, track_num);
633
634     if (ctx->index_table == NULL)
635       ctx->index_table =
636           g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
637
638     g_array_append_vals (ctx->index_table, idx, 1);
639   }
640
641   common->index_parsed = TRUE;
642
643   /* sanity check; empty index normalizes to no index */
644   if (common->index->len == 0) {
645     g_array_free (common->index, TRUE);
646     common->index = NULL;
647   }
648
649   return ret;
650 }
651
652 static const guint8 *
653 gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint
654     peek)
655 {
656   return gst_adapter_peek (common->adapter, peek);
657 }
658
659 /*
660  * Calls pull_range for (offset,size) without advancing our offset
661  */
662 GstFlowReturn
663 gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64
664     offset, guint size, GstBuffer ** p_buf, guint8 ** bytes)
665 {
666   GstFlowReturn ret;
667
668   /* Caching here actually makes much less difference than one would expect.
669    * We do it mainly to avoid pulling buffers of 1 byte all the time */
670   if (common->cached_buffer) {
671     guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer);
672     guint cache_size = GST_BUFFER_SIZE (common->cached_buffer);
673
674     if (cache_offset <= common->offset &&
675         (common->offset + size) <= (cache_offset + cache_size)) {
676       if (p_buf)
677         *p_buf = gst_buffer_create_sub (common->cached_buffer,
678             common->offset - cache_offset, size);
679       if (bytes)
680         *bytes = GST_BUFFER_DATA (common->cached_buffer) + common->offset -
681             cache_offset;
682       return GST_FLOW_OK;
683     }
684     /* not enough data in the cache, free cache and get a new one */
685     gst_buffer_unref (common->cached_buffer);
686     common->cached_buffer = NULL;
687   }
688
689   /* refill the cache */
690   ret = gst_pad_pull_range (common->sinkpad, common->offset,
691       MAX (size, 64 * 1024), &common->cached_buffer);
692   if (ret != GST_FLOW_OK) {
693     common->cached_buffer = NULL;
694     return ret;
695   }
696
697   if (GST_BUFFER_SIZE (common->cached_buffer) >= size) {
698     if (p_buf)
699       *p_buf = gst_buffer_create_sub (common->cached_buffer, 0, size);
700     if (bytes)
701       *bytes = GST_BUFFER_DATA (common->cached_buffer);
702     return GST_FLOW_OK;
703   }
704
705   /* Not possible to get enough data, try a last time with
706    * requesting exactly the size we need */
707   gst_buffer_unref (common->cached_buffer);
708   common->cached_buffer = NULL;
709
710   ret =
711       gst_pad_pull_range (common->sinkpad, common->offset, size,
712       &common->cached_buffer);
713   if (ret != GST_FLOW_OK) {
714     GST_DEBUG_OBJECT (common, "pull_range returned %d", ret);
715     if (p_buf)
716       *p_buf = NULL;
717     if (bytes)
718       *bytes = NULL;
719     return ret;
720   }
721
722   if (GST_BUFFER_SIZE (common->cached_buffer) < size) {
723     GST_WARNING_OBJECT (common, "Dropping short buffer at offset %"
724         G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", common->offset,
725         size, GST_BUFFER_SIZE (common->cached_buffer));
726
727     gst_buffer_unref (common->cached_buffer);
728     common->cached_buffer = NULL;
729     if (p_buf)
730       *p_buf = NULL;
731     if (bytes)
732       *bytes = NULL;
733     return GST_FLOW_UNEXPECTED;
734   }
735
736   if (p_buf)
737     *p_buf = gst_buffer_create_sub (common->cached_buffer, 0, size);
738   if (bytes)
739     *bytes = GST_BUFFER_DATA (common->cached_buffer);
740
741   return GST_FLOW_OK;
742 }
743
744 static const guint8 *
745 gst_matroska_read_common_peek_pull (GstMatroskaReadCommon * common, guint peek)
746 {
747   guint8 *data = NULL;
748
749   gst_matroska_read_common_peek_bytes (common, common->offset, peek, NULL,
750       &data);
751   return data;
752 }
753
754 GstFlowReturn
755 gst_matroska_read_common_peek_id_length_pull (GstMatroskaReadCommon * common,
756     GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
757 {
758   return gst_ebml_peek_id_length (_id, _length, _needed,
759       (GstPeekData) gst_matroska_read_common_peek_pull, (gpointer) common, el,
760       common->offset);
761 }
762
763 GstFlowReturn
764 gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common,
765     GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
766 {
767   return gst_ebml_peek_id_length (_id, _length, _needed,
768       (GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common,
769       el, common->offset);
770 }
771
772 static GstFlowReturn
773 gst_matroska_read_common_read_track_encoding (GstMatroskaReadCommon * common,
774     GstEbmlRead * ebml, GstMatroskaTrackContext * context)
775 {
776   GstMatroskaTrackEncoding enc = { 0, };
777   GstFlowReturn ret;
778   guint32 id;
779
780   DEBUG_ELEMENT_START (common, ebml, "ContentEncoding");
781   /* Set default values */
782   enc.scope = 1;
783   /* All other default values are 0 */
784
785   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
786     DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
787     return ret;
788   }
789
790   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
791     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
792       break;
793
794     switch (id) {
795       case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
796         guint64 num;
797
798         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
799           break;
800
801         if (!gst_matroska_read_common_encoding_order_unique (context->encodings,
802                 num)) {
803           GST_ERROR_OBJECT (common, "ContentEncodingOrder %" G_GUINT64_FORMAT
804               "is not unique for track %d", num, context->num);
805           ret = GST_FLOW_ERROR;
806           break;
807         }
808
809         GST_DEBUG_OBJECT (common, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
810             num);
811         enc.order = num;
812         break;
813       }
814       case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
815         guint64 num;
816
817         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
818           break;
819
820         if (num > 7 && num == 0) {
821           GST_ERROR_OBJECT (common, "Invalid ContentEncodingScope %"
822               G_GUINT64_FORMAT, num);
823           ret = GST_FLOW_ERROR;
824           break;
825         }
826
827         GST_DEBUG_OBJECT (common, "ContentEncodingScope: %" G_GUINT64_FORMAT,
828             num);
829         enc.scope = num;
830
831         break;
832       }
833       case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
834         guint64 num;
835
836         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
837           break;
838
839         if (num > 1) {
840           GST_ERROR_OBJECT (common, "Invalid ContentEncodingType %"
841               G_GUINT64_FORMAT, num);
842           ret = GST_FLOW_ERROR;
843           break;
844         } else if (num != 0) {
845           GST_ERROR_OBJECT (common, "Encrypted tracks are not supported yet");
846           ret = GST_FLOW_ERROR;
847           break;
848         }
849         GST_DEBUG_OBJECT (common, "ContentEncodingType: %" G_GUINT64_FORMAT,
850             num);
851         enc.type = num;
852         break;
853       }
854       case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
855
856         DEBUG_ELEMENT_START (common, ebml, "ContentCompression");
857
858         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
859           break;
860
861         while (ret == GST_FLOW_OK &&
862             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
863           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
864             break;
865
866           switch (id) {
867             case GST_MATROSKA_ID_CONTENTCOMPALGO:{
868               guint64 num;
869
870               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
871                 break;
872               }
873               if (num > 3) {
874                 GST_ERROR_OBJECT (common, "Invalid ContentCompAlgo %"
875                     G_GUINT64_FORMAT, num);
876                 ret = GST_FLOW_ERROR;
877                 break;
878               }
879               GST_DEBUG_OBJECT (common, "ContentCompAlgo: %" G_GUINT64_FORMAT,
880                   num);
881               enc.comp_algo = num;
882
883               break;
884             }
885             case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
886               guint8 *data;
887               guint64 size;
888
889               if ((ret =
890                       gst_ebml_read_binary (ebml, &id, &data,
891                           &size)) != GST_FLOW_OK) {
892                 break;
893               }
894               enc.comp_settings = data;
895               enc.comp_settings_length = size;
896               GST_DEBUG_OBJECT (common,
897                   "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
898               break;
899             }
900             default:
901               GST_WARNING_OBJECT (common,
902                   "Unknown ContentCompression subelement 0x%x - ignoring", id);
903               ret = gst_ebml_read_skip (ebml);
904               break;
905           }
906         }
907         DEBUG_ELEMENT_STOP (common, ebml, "ContentCompression", ret);
908         break;
909       }
910
911       case GST_MATROSKA_ID_CONTENTENCRYPTION:
912         GST_ERROR_OBJECT (common, "Encrypted tracks not yet supported");
913         gst_ebml_read_skip (ebml);
914         ret = GST_FLOW_ERROR;
915         break;
916       default:
917         GST_WARNING_OBJECT (common,
918             "Unknown ContentEncoding subelement 0x%x - ignoring", id);
919         ret = gst_ebml_read_skip (ebml);
920         break;
921     }
922   }
923
924   DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
925   if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
926     return ret;
927
928   /* TODO: Check if the combination of values is valid */
929
930   g_array_append_val (context->encodings, enc);
931
932   return ret;
933 }
934
935 GstFlowReturn
936 gst_matroska_read_common_read_track_encodings (GstMatroskaReadCommon * common,
937     GstEbmlRead * ebml, GstMatroskaTrackContext * context)
938 {
939   GstFlowReturn ret;
940   guint32 id;
941
942   DEBUG_ELEMENT_START (common, ebml, "ContentEncodings");
943
944   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
945     DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
946     return ret;
947   }
948
949   context->encodings =
950       g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
951
952   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
953     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
954       break;
955
956     switch (id) {
957       case GST_MATROSKA_ID_CONTENTENCODING:
958         ret = gst_matroska_read_common_read_track_encoding (common, ebml,
959             context);
960         break;
961       default:
962         GST_WARNING_OBJECT (common,
963             "Unknown ContentEncodings subelement 0x%x - ignoring", id);
964         ret = gst_ebml_read_skip (ebml);
965         break;
966     }
967   }
968
969   DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
970   if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
971     return ret;
972
973   /* Sort encodings according to their order */
974   g_array_sort (context->encodings,
975       (GCompareFunc) gst_matroska_read_common_encoding_cmp);
976
977   return gst_matroska_decode_content_encodings (context->encodings);
978 }