~ubuntu-branches/ubuntu/feisty/gst-plugins-good0.10/feisty-security

« back to all changes in this revision

Viewing changes to gst/matroska/matroska-demux.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-12-21 21:12:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20061221211215-3uukkusokhe0nk4f
Tags: 0.10.5-0ubuntu1
* Sync with pkg-gstreamer SVN:
  + debian/rules:
    - Use Ubuntu as distribution name and point to the proper Launchpad URL
  + debian/patches/01_esdsink-priority.patch:
    - Mark the esdsink with rank primary-2 to get
      pulse > alsadmix > esd > alsa > oss

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <gst/riff/riff-ids.h>
34
34
#include <gst/riff/riff-media.h>
35
35
 
 
36
#ifdef HAVE_ZLIB
 
37
#include <zlib.h>
 
38
#endif
 
39
 
36
40
#include "matroska-demux.h"
37
41
#include "matroska-ids.h"
38
42
 
71
75
    GST_PAD_SRC,
72
76
    GST_PAD_SOMETIMES,
73
77
    GST_STATIC_CAPS ("text/plain; application/x-ssa; application/x-ass; "
74
 
        "application/x-usf; application/x-subtitle-unknown")
 
78
        "application/x-usf; video/x-dvd-subpicture; "
 
79
        "application/x-subtitle-unknown")
75
80
    );
76
81
 
77
82
static void gst_matroska_demux_base_init (GstMatroskaDemuxClass * klass);
213
218
}
214
219
 
215
220
static void
 
221
gst_matroska_track_free (GstMatroskaTrackContext * track)
 
222
{
 
223
  g_free (track->codec_id);
 
224
  g_free (track->codec_name);
 
225
  g_free (track->name);
 
226
  g_free (track->language);
 
227
  g_free (track->codec_priv);
 
228
 
 
229
  if (track->encodings != NULL) {
 
230
    int i;
 
231
 
 
232
    for (i = 0; i < track->encodings->len; ++i) {
 
233
      GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
 
234
          GstMatroskaTrackEncoding,
 
235
          i);
 
236
 
 
237
      g_free (enc->comp_settings);
 
238
    }
 
239
    g_array_free (track->encodings, TRUE);
 
240
  }
 
241
 
 
242
  g_free (track);
 
243
}
 
244
 
 
245
static void
216
246
gst_matroska_demux_reset (GstElement * element)
217
247
{
218
248
  GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
228
258
        gst_element_remove_pad (GST_ELEMENT (demux), demux->src[i]->pad);
229
259
      }
230
260
      gst_caps_replace (&demux->src[i]->caps, NULL);
231
 
      g_free (demux->src[i]->codec_id);
232
 
      g_free (demux->src[i]->codec_name);
233
 
      g_free (demux->src[i]->name);
234
 
      g_free (demux->src[i]->language);
235
 
      g_free (demux->src[i]->codec_priv);
236
 
      g_free (demux->src[i]);
 
261
      gst_matroska_track_free (demux->src[i]);
237
262
      demux->src[i] = NULL;
238
263
    }
239
264
  }
288
313
  return -1;
289
314
}
290
315
 
 
316
static gint
 
317
gst_matroska_demux_encoding_cmp (gconstpointer a, gconstpointer b)
 
318
{
 
319
  const GstMatroskaTrackEncoding *enc_a;
 
320
  const GstMatroskaTrackEncoding *enc_b;
 
321
 
 
322
  enc_a = (const GstMatroskaTrackEncoding *) a;
 
323
  enc_b = (const GstMatroskaTrackEncoding *) b;
 
324
 
 
325
  return (gint) enc_b->order - (gint) enc_a->order;
 
326
}
 
327
 
 
328
static gboolean
 
329
gst_matroska_demux_read_track_encodings (GstEbmlRead * ebml,
 
330
    GstMatroskaDemux * demux, GstMatroskaTrackContext * context)
 
331
{
 
332
  gboolean res = TRUE;
 
333
  guint32 id;
 
334
 
 
335
  if (!gst_ebml_read_master (ebml, &id))
 
336
    return FALSE;
 
337
 
 
338
  context->encodings =
 
339
      g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
 
340
 
 
341
  while (res) {
 
342
    if (!gst_ebml_peek_id (ebml, &demux->level_up, &id)) {
 
343
      res = FALSE;
 
344
      break;
 
345
    } else if (demux->level_up > 0) {
 
346
      demux->level_up--;
 
347
      break;
 
348
    }
 
349
 
 
350
    switch (id) {
 
351
      case GST_MATROSKA_ID_CONTENTENCODING:{
 
352
        GstMatroskaTrackEncoding enc = { 0, };
 
353
 
 
354
        if (!gst_ebml_read_master (ebml, &id)) {
 
355
          res = FALSE;
 
356
          break;
 
357
        }
 
358
 
 
359
        while (res) {
 
360
          if (!gst_ebml_peek_id (ebml, &demux->level_up, &id)) {
 
361
            res = FALSE;
 
362
            break;
 
363
          } else if (demux->level_up > 0) {
 
364
            demux->level_up--;
 
365
            break;
 
366
          }
 
367
 
 
368
          switch (id) {
 
369
            case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
 
370
              guint64 num;
 
371
 
 
372
              if (!gst_ebml_read_uint (ebml, &id, &num)) {
 
373
                res = FALSE;
 
374
                break;
 
375
              }
 
376
              enc.order = num;
 
377
              break;
 
378
            }
 
379
            case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
 
380
              guint64 num;
 
381
 
 
382
              if (!gst_ebml_read_uint (ebml, &id, &num)) {
 
383
                res = FALSE;
 
384
                break;
 
385
              }
 
386
              if (num > 7)
 
387
                GST_WARNING ("Unknown scope value in contents encoding.");
 
388
              else
 
389
                enc.scope = num;
 
390
              break;
 
391
            }
 
392
            case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
 
393
              guint64 num;
 
394
 
 
395
              if (!gst_ebml_read_uint (ebml, &id, &num)) {
 
396
                res = FALSE;
 
397
                break;
 
398
              }
 
399
              if (num > 1)
 
400
                GST_WARNING ("Unknown type value in contents encoding.");
 
401
              else
 
402
                enc.type = num;
 
403
              break;
 
404
            }
 
405
            case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
 
406
 
 
407
              if (!gst_ebml_read_master (ebml, &id)) {
 
408
                res = FALSE;
 
409
                break;
 
410
              }
 
411
 
 
412
              while (res) {
 
413
 
 
414
                if (!gst_ebml_peek_id (ebml, &demux->level_up, &id)) {
 
415
                  res = FALSE;
 
416
                  break;
 
417
                } else if (demux->level_up > 0) {
 
418
                  demux->level_up--;
 
419
                  break;
 
420
                }
 
421
 
 
422
                switch (id) {
 
423
                  case GST_MATROSKA_ID_CONTENTCOMPALGO:{
 
424
                    guint64 num;
 
425
 
 
426
                    if (!gst_ebml_read_uint (ebml, &id, &num)) {
 
427
                      res = FALSE;
 
428
                      break;
 
429
                    }
 
430
                    if (num > 3)
 
431
                      GST_WARNING ("Unknown scope value in encoding compalgo.");
 
432
                    else
 
433
                      enc.comp_algo = num;
 
434
                    break;
 
435
                  }
 
436
                  case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
 
437
                    guint8 *data;
 
438
                    guint64 size;
 
439
 
 
440
 
 
441
                    if (!gst_ebml_read_binary (ebml, &id, &data, &size)) {
 
442
                      res = FALSE;
 
443
                      break;
 
444
                    }
 
445
                    enc.comp_settings = data;
 
446
                    enc.comp_settings_length = size;
 
447
                    break;
 
448
                  }
 
449
                  default:
 
450
                    GST_WARNING ("Unknown track compression header entry 0x%x"
 
451
                        " - ignoring", id);
 
452
                    if (!gst_ebml_read_skip (ebml))
 
453
                      res = FALSE;
 
454
                    break;
 
455
                }
 
456
 
 
457
                if (demux->level_up) {
 
458
                  demux->level_up--;
 
459
                  break;
 
460
                }
 
461
              }
 
462
              break;
 
463
            }
 
464
 
 
465
            case GST_MATROSKA_ID_CONTENTENCRYPTION:
 
466
              GST_WARNING ("Encrypted tracks not yet supported");
 
467
              /* pass-through */
 
468
            default:
 
469
              GST_WARNING
 
470
                  ("Unknown track encoding header entry 0x%x - ignoring", id);
 
471
              if (!gst_ebml_read_skip (ebml))
 
472
                res = FALSE;
 
473
              break;
 
474
          }
 
475
 
 
476
          if (demux->level_up) {
 
477
            demux->level_up--;
 
478
            break;
 
479
          }
 
480
        }
 
481
 
 
482
        g_array_append_val (context->encodings, enc);
 
483
        break;
 
484
      }
 
485
 
 
486
      default:
 
487
        GST_WARNING ("Unknown track encodings header entry 0x%x - ignoring",
 
488
            id);
 
489
        if (!gst_ebml_read_skip (ebml))
 
490
          res = FALSE;
 
491
        break;
 
492
    }
 
493
 
 
494
    if (demux->level_up) {
 
495
      demux->level_up--;
 
496
      break;
 
497
    }
 
498
  }
 
499
 
 
500
  /* Sort encodings according to their order */
 
501
  g_array_sort (context->encodings, gst_matroska_demux_encoding_cmp);
 
502
 
 
503
  return res;
 
504
}
 
505
 
291
506
static gboolean
292
507
gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
293
508
{
390
605
          case GST_MATROSKA_TRACK_TYPE_LOGO:
391
606
          case GST_MATROSKA_TRACK_TYPE_CONTROL:
392
607
          default:
393
 
            GST_WARNING ("Unknown or unsupported track type 0x%x", track_type);
 
608
            GST_WARNING ("Unknown or unsupported track type %"
 
609
                G_GUINT64_FORMAT, track_type);
394
610
            context->type = 0;
395
611
            break;
396
612
        }
444
660
                res = FALSE;
445
661
                break;
446
662
              }
447
 
              context->default_duration = GST_SECOND * (1. / num);
 
663
              context->default_duration =
 
664
                  gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
 
665
              videocontext->default_fps = num;
448
666
              break;
449
667
            }
450
668
 
690
908
        }
691
909
        context->codec_priv = data;
692
910
        context->codec_priv_size = size;
693
 
        GST_LOG_OBJECT (demux, "%u bytes of codec private data", size);
 
911
        GST_LOG_OBJECT (demux, "%u bytes of codec private data", (guint) size);
694
912
        break;
695
913
      }
696
914
 
795
1013
        break;
796
1014
      }
797
1015
 
 
1016
      case GST_MATROSKA_ID_CONTENTENCODINGS:{
 
1017
        if (!gst_matroska_demux_read_track_encodings (ebml, demux, context)) {
 
1018
          res = FALSE;
 
1019
        }
 
1020
        break;
 
1021
      }
 
1022
 
798
1023
      default:
799
1024
        GST_WARNING ("Unknown track header entry 0x%x - ignoring", id);
800
1025
        /* pass-through */
823
1048
    demux->num_streams--;
824
1049
    demux->src[demux->num_streams] = NULL;
825
1050
    if (context) {
826
 
      g_free (context->codec_id);
827
 
      g_free (context->codec_name);
828
 
      g_free (context->name);
829
 
      g_free (context->language);
830
 
      g_free (context->codec_priv);
831
 
      g_free (context);
 
1051
      gst_matroska_track_free (context);
832
1052
    }
833
1053
 
834
1054
    return res;
929
1149
        caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
930
1150
        break;
931
1151
    }
 
1152
    gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
 
1153
        NULL);
932
1154
  }
933
1155
 
934
1156
  /* the pad in here */
2041
2263
}
2042
2264
 
2043
2265
static gboolean
 
2266
gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
 
2267
    GstMatroskaTrackContext * stream, guint8 * data, guint len)
 
2268
{
 
2269
  GstFlowReturn flow;
 
2270
  GstBuffer *header_buf = NULL;
 
2271
 
 
2272
  flow = gst_pad_alloc_buffer_and_set_caps (stream->pad,
 
2273
      GST_BUFFER_OFFSET_NONE, len, stream->caps, &header_buf);
 
2274
 
 
2275
  if (flow == GST_FLOW_OK) {
 
2276
    memcpy (GST_BUFFER_DATA (header_buf), data, len);
 
2277
    flow = gst_pad_push (stream->pad, header_buf);
 
2278
  }
 
2279
 
 
2280
  if (flow != GST_FLOW_OK && flow != GST_FLOW_NOT_LINKED)
 
2281
    return FALSE;
 
2282
 
 
2283
  return TRUE;
 
2284
}
 
2285
 
 
2286
static gboolean
 
2287
gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
 
2288
    GstMatroskaTrackContext * stream)
 
2289
{
 
2290
  guint8 *pdata;
 
2291
  guint off, len;
 
2292
 
 
2293
  GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
 
2294
 
 
2295
  pdata = (guint8 *) stream->codec_priv;
 
2296
 
 
2297
  /* need at least 'fLaC' marker + STREAMINFO metadata block */
 
2298
  if (stream->codec_priv_size < ((4) + (4 + 34))) {
 
2299
    GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
 
2300
    return FALSE;
 
2301
  }
 
2302
 
 
2303
  if (memcmp (pdata, "fLaC", 4) != 0) {
 
2304
    GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
 
2305
    return FALSE;
 
2306
  }
 
2307
 
 
2308
  if (!gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4))
 
2309
    return FALSE;
 
2310
 
 
2311
  off = 4;                      /* skip fLaC marker */
 
2312
  while (off < stream->codec_priv_size) {
 
2313
    len = GST_READ_UINT8 (pdata + off + 1) << 16;
 
2314
    len |= GST_READ_UINT8 (pdata + off + 2) << 8;
 
2315
    len |= GST_READ_UINT8 (pdata + off + 3);
 
2316
 
 
2317
    GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
 
2318
        len, (guint) pdata[off]);
 
2319
 
 
2320
    if (!gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len))
 
2321
      return FALSE;
 
2322
 
 
2323
    off += 4 + len;
 
2324
  }
 
2325
 
 
2326
  return TRUE;
 
2327
}
 
2328
 
 
2329
static gboolean
2044
2330
gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2045
2331
    GstMatroskaTrackContext * stream)
2046
2332
{
2047
 
  GstFlowReturn ret;
2048
 
  GstBuffer *priv;
2049
 
  guint32 offset, length;
2050
 
  guchar *p;
2051
 
  gint i;
 
2333
  guint8 *p = (guint8 *) stream->codec_priv;
 
2334
  gint i, offset, length, num_packets;
2052
2335
 
2053
2336
  /* start of the stream and vorbis audio or theora video, need to
2054
2337
   * send the codec_priv data as first three packets */
2055
 
  p = (guchar *) stream->codec_priv;
2056
 
  offset = 3;
2057
 
 
2058
 
  for (i = 0; i < 2; i++) {
 
2338
  num_packets = p[0] + 1;
 
2339
  GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
 
2340
      (guint) num_packets, stream->codec_priv_size);
 
2341
 
 
2342
  offset = num_packets;         /* offset to data of first packet */
 
2343
 
 
2344
  for (i = 0; i < num_packets - 1; i++) {
2059
2345
    length = p[i + 1];
2060
 
    if (gst_pad_alloc_buffer_and_set_caps (stream->pad, GST_BUFFER_OFFSET_NONE,
2061
 
            length, stream->caps, &priv) == GST_FLOW_OK) {
2062
 
      memcpy (GST_BUFFER_DATA (priv), &p[offset], length);
2063
 
 
2064
 
      ret = gst_pad_push (stream->pad, priv);
2065
 
      if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED)
2066
 
        return FALSE;
2067
 
    }
 
2346
 
 
2347
    GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i, (guint) length);
 
2348
    if (offset + length > stream->codec_priv_size)
 
2349
      return FALSE;
 
2350
 
 
2351
    if (!gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length))
 
2352
      return FALSE;
 
2353
 
2068
2354
    offset += length;
2069
2355
  }
 
2356
 
2070
2357
  length = stream->codec_priv_size - offset;
2071
 
  if (gst_pad_alloc_buffer_and_set_caps (stream->pad, GST_BUFFER_OFFSET_NONE,
2072
 
          length, stream->caps, &priv) == GST_FLOW_OK) {
2073
 
    memcpy (GST_BUFFER_DATA (priv), &p[offset], length);
2074
 
    ret = gst_pad_push (stream->pad, priv);
2075
 
    if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED)
2076
 
      return FALSE;
2077
 
  }
 
2358
  GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i, (guint) length);
 
2359
  if (!gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length))
 
2360
    return FALSE;
 
2361
 
2078
2362
  return TRUE;
2079
2363
}
2080
2364
 
2207
2491
  return newbuf;
2208
2492
}
2209
2493
 
 
2494
static GstBuffer *
 
2495
gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
 
2496
{
 
2497
  gint i;
 
2498
 
 
2499
  g_assert (context->encodings != NULL);
 
2500
 
 
2501
  for (i = 0; i < context->encodings->len; i++) {
 
2502
    GstMatroskaTrackEncoding *enc;
 
2503
    guint8 *new_data = NULL;
 
2504
    guint new_size = 0;
 
2505
    GstBuffer *new_buf;
 
2506
 
 
2507
    enc = &g_array_index (context->encodings, GstMatroskaTrackEncoding, i);
 
2508
 
 
2509
    /* Currently only compression is supported */
 
2510
    if (enc->type != 0)
 
2511
      break;
 
2512
 
 
2513
    /* FIXME: use enc->scope ? */
 
2514
 
 
2515
    if (enc->comp_algo == 0) {
 
2516
#ifdef HAVE_ZLIB
 
2517
      /* zlib encoded track */
 
2518
      z_stream zstream;
 
2519
      guint orig_size;
 
2520
      int result;
 
2521
 
 
2522
      orig_size = GST_BUFFER_SIZE (buf);
 
2523
      zstream.zalloc = (alloc_func) 0;
 
2524
      zstream.zfree = (free_func) 0;
 
2525
      zstream.opaque = (voidpf) 0;
 
2526
      if (inflateInit (&zstream) != Z_OK) {
 
2527
        GST_WARNING ("zlib initialization failed.");
 
2528
        break;
 
2529
      }
 
2530
      zstream.next_in = (Bytef *) GST_BUFFER_DATA (buf);
 
2531
      zstream.avail_in = orig_size;
 
2532
      new_size = orig_size;
 
2533
      new_data = g_malloc (new_size);
 
2534
      zstream.avail_out = new_size;
 
2535
      do {
 
2536
        new_size += 4000;
 
2537
        new_data = g_realloc (new_data, new_size);
 
2538
        zstream.next_out = (Bytef *) (new_data + zstream.total_out);
 
2539
        result = inflate (&zstream, Z_NO_FLUSH);
 
2540
        if (result != Z_OK && result != Z_STREAM_END) {
 
2541
          GST_WARNING ("zlib decompression failed.");
 
2542
          g_free (new_data);
 
2543
          inflateEnd (&zstream);
 
2544
          break;
 
2545
        }
 
2546
        zstream.avail_out += 4000;
 
2547
      } while (zstream.avail_out == 4000 &&
 
2548
          zstream.avail_in != 0 && result != Z_STREAM_END);
 
2549
 
 
2550
      new_size = zstream.total_out;
 
2551
      inflateEnd (&zstream);
 
2552
#else
 
2553
      GST_WARNING ("GZIP encoded tracks not supported.");
 
2554
      break;
 
2555
#endif
 
2556
    } else if (enc->comp_algo == 1) {
 
2557
      GST_WARNING ("BZIP encoded tracks not supported.");
 
2558
      break;
 
2559
    } else if (enc->comp_algo == 2) {
 
2560
      GST_WARNING ("LZO encoded tracks not supported.");
 
2561
      break;
 
2562
    } else if (enc->comp_algo == 3) {
 
2563
      GST_WARNING ("Header-stripped tracks not supported.");
 
2564
      break;
 
2565
    } else {
 
2566
      g_assert_not_reached ();
 
2567
    }
 
2568
 
 
2569
    g_assert (new_data != NULL);
 
2570
 
 
2571
    new_buf = gst_buffer_new ();
 
2572
    GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) new_data;
 
2573
    GST_BUFFER_DATA (new_buf) = (guint8 *) new_data;
 
2574
    GST_BUFFER_SIZE (new_buf) = new_size;
 
2575
    gst_buffer_stamp (new_buf, buf);
 
2576
 
 
2577
    gst_buffer_unref (buf);
 
2578
    buf = new_buf;
 
2579
  }
 
2580
 
 
2581
  return buf;
 
2582
}
 
2583
 
2210
2584
static gboolean
2211
2585
gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
2212
2586
    guint64 cluster_time, gboolean is_simpleblock)
2224
2598
  gint64 time = 0;
2225
2599
  gint64 lace_time = 0;
2226
2600
  gint flags = 0;
 
2601
  gint64 referenceblock = 0;
2227
2602
 
2228
2603
  while (!got_error) {
2229
2604
    if (!is_simpleblock) {
2373
2748
          stream->send_xiph_headers = FALSE;
2374
2749
        }
2375
2750
 
 
2751
        if (stream->send_flac_headers) {
 
2752
          if (!gst_matroska_demux_push_flac_codec_priv_data (demux, stream)) {
 
2753
            got_error = TRUE;
 
2754
          }
 
2755
          stream->send_flac_headers = FALSE;
 
2756
        }
 
2757
 
2376
2758
        if (got_error)
2377
2759
          break;
2378
2760
 
2387
2769
      }
2388
2770
 
2389
2771
      case GST_MATROSKA_ID_REFERENCEBLOCK:{
2390
 
        /* FIXME: implement support for ReferenceBlock
2391
 
           gint64 num;
2392
 
           if (!gst_ebml_read_sint (ebml, &id, &num)) {
2393
 
           res = FALSE;
2394
 
           break;
2395
 
           }
2396
 
           GST_WARNING ("FIXME: implement support for ReferenceBlock");
2397
 
         */
2398
 
        if (!gst_ebml_read_skip (ebml))
 
2772
        if (!gst_ebml_read_sint (ebml, &id, &referenceblock))
2399
2773
          got_error = TRUE;
2400
2774
        break;
2401
2775
      }
2428
2802
    lace_time = GST_CLOCK_TIME_NONE;
2429
2803
  }
2430
2804
 
 
2805
  if (referenceblock && readblock && demux->src[stream_num]->set_discont) {
 
2806
    /* When doing seeks or such, we need to restart on key frames or
 
2807
       decoders might choke. */
 
2808
    readblock = FALSE;
 
2809
    gst_buffer_unref (buf);
 
2810
  }
 
2811
 
2431
2812
  if (!got_error && readblock) {
2432
2813
    guint64 duration = 0;
2433
2814
 
2449
2830
      sub = gst_buffer_create_sub (buf,
2450
2831
          GST_BUFFER_SIZE (buf) - size, lace_size[n]);
2451
2832
 
 
2833
      if (stream->encodings != NULL && stream->encodings->len > 0)
 
2834
        sub = gst_matroska_decode_buffer (stream, sub);
 
2835
 
2452
2836
      GST_BUFFER_TIMESTAMP (sub) = lace_time;
2453
2837
      if (lace_time != GST_CLOCK_TIME_NONE)
2454
2838
        demux->pos = lace_time;
3044
3428
  g_assert (codec_name != NULL);
3045
3429
 
3046
3430
  context->send_xiph_headers = FALSE;
 
3431
  context->send_flac_headers = FALSE;
3047
3432
 
3048
3433
  if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
3049
3434
    gst_riff_strf_vids *vids = NULL;
3232
3617
            videocontext->display_height * videocontext->pixel_width, NULL);
3233
3618
      }
3234
3619
 
3235
 
      if (context->default_duration > 0) {
3236
 
        GValue fps_double = { 0 };
3237
 
        GValue fps_fraction = { 0 };
3238
 
 
3239
 
        g_value_init (&fps_double, G_TYPE_DOUBLE);
3240
 
        g_value_init (&fps_fraction, GST_TYPE_FRACTION);
3241
 
        g_value_set_double (&fps_double,
3242
 
            gst_guint64_to_gdouble (GST_SECOND / context->default_duration));
 
3620
      if (videocontext->default_fps > 0.0) {
 
3621
        GValue fps_double = { 0, };
 
3622
        GValue fps_fraction = { 0, };
 
3623
 
 
3624
        g_value_init (&fps_double, G_TYPE_DOUBLE);
 
3625
        g_value_init (&fps_fraction, GST_TYPE_FRACTION);
 
3626
        g_value_set_double (&fps_double, videocontext->default_fps);
 
3627
        g_value_transform (&fps_double, &fps_fraction);
 
3628
 
 
3629
        gst_structure_set_value (structure, "framerate", &fps_fraction);
 
3630
        g_value_unset (&fps_double);
 
3631
        g_value_unset (&fps_fraction);
 
3632
      } else if (context->default_duration > 0) {
 
3633
        GValue fps_double = { 0, };
 
3634
        GValue fps_fraction = { 0, };
 
3635
 
 
3636
        g_value_init (&fps_double, G_TYPE_DOUBLE);
 
3637
        g_value_init (&fps_fraction, GST_TYPE_FRACTION);
 
3638
        g_value_set_double (&fps_double, (gdouble) GST_SECOND * 1.0 /
 
3639
            gst_guint64_to_gdouble (context->default_duration));
3243
3640
        g_value_transform (&fps_double, &fps_fraction);
3244
3641
 
3245
3642
        gst_structure_set_value (structure, "framerate", &fps_fraction);
3261
3658
 
3262
3659
/*
3263
3660
 * Some AAC specific code... *sigh*
 
3661
 * FIXME: maybe we should use '15' and code the sample rate explicitly
 
3662
 * if the sample rate doesn't match the predefined rates exactly? (tpm)
3264
3663
 */
3265
3664
 
3266
3665
static gint
3325
3724
  g_assert (codec_name != NULL);
3326
3725
 
3327
3726
  context->send_xiph_headers = FALSE;
 
3727
  context->send_flac_headers = FALSE;
3328
3728
 
3329
3729
  if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
3330
3730
      !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
3379
3779
    caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
3380
3780
    context->send_xiph_headers = TRUE;
3381
3781
    /* vorbis decoder does tags */
 
3782
  } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
 
3783
    caps = gst_caps_new_simple ("audio/x-flac", NULL);
 
3784
    context->send_flac_headers = TRUE;
3382
3785
  } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
3383
3786
    gst_riff_strf_auds *auds = NULL;
3384
3787
 
3396
3799
      caps = gst_riff_create_audio_caps (auds->format, NULL, auds, NULL,
3397
3800
          NULL, codec_name);
3398
3801
    }
3399
 
  } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG2,
3400
 
          strlen (GST_MATROSKA_CODEC_ID_AUDIO_MPEG2)) ||
3401
 
      !strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG4,
3402
 
          strlen (GST_MATROSKA_CODEC_ID_AUDIO_MPEG4))) {
 
3802
  } else if (g_str_has_prefix (codec_id, "A_AAC")) {
3403
3803
    GstBuffer *priv = NULL;
3404
3804
    gint mpegversion = -1;
3405
3805
    gint rate_idx, profile;
3406
 
    guint8 *data;
3407
 
 
3408
 
    /* make up decoderspecificdata */
3409
 
    priv = gst_buffer_new_and_alloc (5);
3410
 
    data = GST_BUFFER_DATA (priv);
3411
 
    rate_idx = aac_rate_idx (audiocontext->samplerate);
3412
 
    profile = aac_profile_idx (codec_id);
3413
 
 
3414
 
    data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
3415
 
    data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
3416
 
    GST_BUFFER_SIZE (priv) = 2;
 
3806
    guint8 *data = NULL;
 
3807
 
 
3808
    /* unspecified AAC profile with opaque private codec data */
 
3809
    if (strcmp (codec_id, "A_AAC") == 0) {
 
3810
      if (context->codec_priv_size >= 2) {
 
3811
        guint obj_type, freq_index, explicit_freq_bytes = 0;
 
3812
 
 
3813
        codec_id = GST_MATROSKA_CODEC_ID_AUDIO_MPEG4;
 
3814
        freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
 
3815
        obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
 
3816
        if (freq_index == 15)
 
3817
          explicit_freq_bytes = 3;
 
3818
        GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
 
3819
        priv = gst_buffer_new_and_alloc (context->codec_priv_size);
 
3820
        memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
 
3821
            context->codec_priv_size);
 
3822
        /* assume SBR if samplerate <= 24kHz */
 
3823
        if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
 
3824
            (context->codec_priv_size == (5 + explicit_freq_bytes))) {
 
3825
          audiocontext->samplerate *= 2;
 
3826
        }
 
3827
      } else {
 
3828
        GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
 
3829
        /* just try this and see what happens ... */
 
3830
        codec_id = GST_MATROSKA_CODEC_ID_AUDIO_MPEG4;
 
3831
      }
 
3832
    }
 
3833
 
 
3834
    /* make up decoder-specific data if it is not supplied */
 
3835
    if (priv == NULL) {
 
3836
      priv = gst_buffer_new_and_alloc (5);
 
3837
      data = GST_BUFFER_DATA (priv);
 
3838
      rate_idx = aac_rate_idx (audiocontext->samplerate);
 
3839
      profile = aac_profile_idx (codec_id);
 
3840
 
 
3841
      data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
 
3842
      data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
 
3843
      GST_BUFFER_SIZE (priv) = 2;
 
3844
    }
3417
3845
 
3418
3846
    if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG2,
3419
3847
            strlen (GST_MATROSKA_CODEC_ID_AUDIO_MPEG2))) {
3535
3963
  } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
3536
3964
    caps = gst_caps_new_simple ("application/x-usf", NULL);
3537
3965
    subtitlecontext->check_utf8 = TRUE;
 
3966
  } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
 
3967
    caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
 
3968
    subtitlecontext->check_utf8 = FALSE;
3538
3969
  } else {
3539
3970
    GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
3540
3971
    caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);