From 26d5ba42eaa4298818fc0b38d7a61e7d769c0611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 24 Jul 2017 16:49:19 +0300 Subject: mxfdemux: Output timecodes for video streams --- gst/mxf/mxfdemux.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ gst/mxf/mxfdemux.h | 3 +++ 2 files changed, 69 insertions(+) (limited to 'gst') diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c index 7da340162..e71dcb7c3 100644 --- a/gst/mxf/mxfdemux.c +++ b/gst/mxf/mxfdemux.c @@ -916,6 +916,7 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) guint component_index; GstFlowReturn ret; GList *pads = NULL, *l; + GstVideoTimeCode start_timecode = { 0, }; g_rw_lock_writer_lock (&demux->metadata_lock); GST_DEBUG_OBJECT (demux, "Updating tracks"); @@ -942,6 +943,60 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) first_run = (demux->src->len == 0); + /* For material packages, there must be one timecode track with one + * continuous timecode. For source packages there might be multiple, + * discontinuous timecode components. + * TODO: Support multiple timecode components + */ + for (i = 0; i < current_package->n_tracks; i++) { + MXFMetadataTimelineTrack *track = NULL; + MXFMetadataSequence *sequence = NULL; + MXFMetadataTimecodeComponent *component = NULL; + + if (!current_package->tracks[i]) { + GST_WARNING_OBJECT (demux, "Unresolved track"); + continue; + } + + if (!MXF_IS_METADATA_TIMELINE_TRACK (current_package->tracks[i])) { + GST_DEBUG_OBJECT (demux, "No timeline track"); + continue; + } + + + track = MXF_METADATA_TIMELINE_TRACK (current_package->tracks[i]); + + if (!track->parent.sequence) + continue; + sequence = track->parent.sequence; + if (sequence->n_structural_components != 1 || + !sequence->structural_components[0] + || + !MXF_IS_METADATA_TIMECODE_COMPONENT (sequence->structural_components + [0])) + continue; + + component = + MXF_METADATA_TIMECODE_COMPONENT (sequence->structural_components[0]); + + /* Not a timecode track */ + if (track->parent.type && (track->parent.type & 0xf0) != 0x10) + continue; + + /* Main timecode track must have id 1, all others must be 0 */ + if (track->parent.track_id != 1) + continue; + + gst_video_time_code_init (&start_timecode, track->edit_rate.n, + track->edit_rate.d, NULL, (component->drop_frame + ? + GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME + : GST_VIDEO_TIME_CODE_FLAGS_NONE), 0, 0, 0, 0, 0); + gst_video_time_code_add_frames (&start_timecode, track->origin); + gst_video_time_code_add_frames (&start_timecode, component->start_timecode); + break; + } + for (i = 0; i < current_package->n_tracks; i++) { MXFMetadataTimelineTrack *track = NULL; MXFMetadataSequence *sequence; @@ -1157,6 +1212,8 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) pad->material_package = current_package; pad->material_track = track; + pad->start_timecode = start_timecode; + /* If we just added the pad initialize for the current component */ if (first_run && MXF_IS_METADATA_MATERIAL_PACKAGE (current_package)) { pad->current_component_index = 0; @@ -1880,6 +1937,15 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE; GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE; + if (pad->material_track->parent.type == MXF_METADATA_TRACK_PICTURE_ESSENCE + && pad->start_timecode.config.fps_n != 0 + && pad->start_timecode.config.fps_d != 0) { + GstVideoTimeCode timecode = pad->start_timecode; + gst_video_time_code_add_frames (&timecode, + pad->current_material_track_position); + gst_buffer_add_video_time_code_meta (outbuf, &timecode); + } + /* Update accumulated error and compensate */ { guint64 abs_error = diff --git a/gst/mxf/mxfdemux.h b/gst/mxf/mxfdemux.h index 1daff8a88..aac3e67d0 100644 --- a/gst/mxf/mxfdemux.h +++ b/gst/mxf/mxfdemux.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "mxfessence.h" @@ -126,6 +127,8 @@ struct _GstMXFDemuxPad MXFMetadataGenericPackage *material_package; MXFMetadataTimelineTrack *material_track; + GstVideoTimeCode start_timecode; + guint current_component_index; MXFMetadataSourceClip *current_component; -- cgit v1.2.1