484
490
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MJPEG);
487
} else if (!strcmp (mimetype, "video/x-divx")) {
489
BITMAPINFOHEADER *bih;
491
bih = (BITMAPINFOHEADER *) g_malloc0 (sizeof (BITMAPINFOHEADER));
492
GST_WRITE_UINT32_LE (&bih->bi_size, sizeof (BITMAPINFOHEADER));
493
GST_WRITE_UINT32_LE (&bih->bi_width, videocontext->pixel_width);
494
GST_WRITE_UINT32_LE (&bih->bi_height, videocontext->pixel_height);
495
GST_WRITE_UINT16_LE (&bih->bi_planes, (guint16) 1);
496
GST_WRITE_UINT16_LE (&bih->bi_bit_count, (guint16) 24);
497
GST_WRITE_UINT32_LE (&bih->bi_size_image, videocontext->pixel_width *
498
videocontext->pixel_height * 3);
500
gst_structure_get_int (structure, "divxversion", &divxversion);
501
switch (divxversion) {
503
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("DIV3"));
506
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("DIVX"));
509
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("DX50"));
513
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC);
514
context->codec_priv = (gpointer) bih;
515
context->codec_priv_size = sizeof (BITMAPINFOHEADER);
518
} else if (!strcmp (mimetype, "video/x-xvid")) {
519
BITMAPINFOHEADER *bih;
521
bih = (BITMAPINFOHEADER *) g_malloc0 (sizeof (BITMAPINFOHEADER));
522
GST_WRITE_UINT32_LE (&bih->bi_size, sizeof (BITMAPINFOHEADER));
523
GST_WRITE_UINT32_LE (&bih->bi_width, videocontext->pixel_width);
524
GST_WRITE_UINT32_LE (&bih->bi_height, videocontext->pixel_height);
525
GST_WRITE_UINT16_LE (&bih->bi_planes, (guint16) 1);
526
GST_WRITE_UINT16_LE (&bih->bi_bit_count, (guint16) 24);
527
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("XVID"));
528
GST_WRITE_UINT32_LE (&bih->bi_size_image, videocontext->pixel_width *
529
videocontext->pixel_height * 3);
531
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC);
532
context->codec_priv = (gpointer) bih;
533
context->codec_priv_size = sizeof (BITMAPINFOHEADER);
493
} else if (!strcmp (mimetype, "video/x-xvid") /* MS/VfW compatibility cases */
494
||!strcmp (mimetype, "video/x-huffyuv")
495
|| !strcmp (mimetype, "video/x-divx")
496
|| !strcmp (mimetype, "video/x-dv")
497
|| !strcmp (mimetype, "video/x-h263")) {
498
BITMAPINFOHEADER *bih;
499
const GValue *codec_data;
500
gint size = sizeof (BITMAPINFOHEADER);
502
bih = g_new0 (BITMAPINFOHEADER, 1);
503
GST_WRITE_UINT32_LE (&bih->bi_size, size);
504
GST_WRITE_UINT32_LE (&bih->bi_width, videocontext->pixel_width);
505
GST_WRITE_UINT32_LE (&bih->bi_height, videocontext->pixel_height);
506
GST_WRITE_UINT16_LE (&bih->bi_planes, (guint16) 1);
507
GST_WRITE_UINT16_LE (&bih->bi_bit_count, (guint16) 24);
508
GST_WRITE_UINT32_LE (&bih->bi_size_image, videocontext->pixel_width *
509
videocontext->pixel_height * 3);
511
if (!strcmp (mimetype, "video/x-xvid"))
512
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("XVID"));
513
else if (!strcmp (mimetype, "video/x-huffyuv"))
514
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("HFYU"));
515
else if (!strcmp (mimetype, "video/x-dv"))
516
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("DVSD"));
517
else if (!strcmp (mimetype, "video/x-h263"))
518
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("H263"));
519
else if (!strcmp (mimetype, "video/x-divx")) {
522
gst_structure_get_int (structure, "divxversion", &divxversion);
523
switch (divxversion) {
525
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("DIV3"));
528
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("DIVX"));
531
GST_WRITE_UINT32_LE (&bih->bi_compression, GST_STR_FOURCC ("DX50"));
536
/* process codec private/initialization data, if any */
537
codec_data = gst_structure_get_value (structure, "codec_data");
539
GstBuffer *codec_data_buf;
541
codec_data_buf = g_value_peek_pointer (codec_data);
542
size += GST_BUFFER_SIZE (codec_data_buf);
543
bih = g_realloc (bih, size);
544
GST_WRITE_UINT32_LE (&bih->bi_size, size);
545
memcpy ((guint8 *) bih + sizeof (BITMAPINFOHEADER),
546
GST_BUFFER_DATA (codec_data_buf), GST_BUFFER_SIZE (codec_data_buf));
549
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC);
550
context->codec_priv = (gpointer) bih;
551
context->codec_priv_size = size;
536
554
} else if (!strcmp (mimetype, "video/x-h264")) {
1330
1377
GstBuffer *buf, *hdr;
1331
1378
guint64 cluster, blockgroup;
1332
1379
gboolean write_duration;
1333
guint16 relative_timestamp;
1380
gint16 relative_timestamp;
1381
gint64 relative_timestamp64;
1334
1382
guint64 block_duration;
1383
gboolean is_video_keyframe = FALSE;
1336
1385
/* write data */
1337
1386
buf = collect_pad->buffer;
1338
1387
collect_pad->buffer = NULL;
1389
/* vorbis header are retrieved from caps and placed in CodecPrivate */
1390
if (gst_matroska_mux_stream_is_vorbis_header (mux, collect_pad)) {
1391
GST_LOG_OBJECT (collect_pad->collect.pad, "dropping vorbis header buffer");
1392
gst_buffer_unref (buf);
1396
/* hm, invalid timestamp (due to --to be fixed--- element upstream);
1397
* this would wreak havoc with time stored in matroska file */
1398
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1399
GST_WARNING_OBJECT (collect_pad->collect.pad,
1400
"Invalid buffer timestamp; dropping buffer");
1401
gst_buffer_unref (buf);
1340
1405
/* set the timestamp for outgoing buffers */
1341
1406
ebml->timestamp = GST_BUFFER_TIMESTAMP (buf);
1408
if (collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1409
!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
1410
GST_LOG_OBJECT (mux, "have video keyframe, ts=%" GST_TIME_FORMAT,
1411
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1412
is_video_keyframe = TRUE;
1343
1415
if (mux->cluster) {
1344
/* start a new cluster every two seconds */
1345
if (mux->cluster_time + GST_SECOND * 2 < GST_BUFFER_TIMESTAMP (buf)) {
1416
/* start a new cluster every two seconds or at keyframe */
1417
if (mux->cluster_time + GST_SECOND * 2 < GST_BUFFER_TIMESTAMP (buf)
1418
|| is_video_keyframe) {
1346
1419
GstMatroskaMetaSeekIndex *idx;
1348
1421
gst_ebml_write_master_finish (ebml, mux->cluster);