mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
Merge branch 'master' of ssh://git.freedesktop.org/git/gstreamer/gst-plugins-bad
This commit is contained in:
commit
b7198258f2
5 changed files with 175 additions and 85 deletions
|
@ -45,8 +45,8 @@ AC_LIBTOOL_WIN32_DLL
|
||||||
AM_PROG_LIBTOOL
|
AM_PROG_LIBTOOL
|
||||||
|
|
||||||
dnl *** required versions of GStreamer stuff ***
|
dnl *** required versions of GStreamer stuff ***
|
||||||
GST_REQ=0.10.21.1
|
GST_REQ=0.10.22
|
||||||
GSTPB_REQ=0.10.20
|
GSTPB_REQ=0.10.22
|
||||||
|
|
||||||
dnl *** autotools stuff ****
|
dnl *** autotools stuff ****
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,17 @@
|
||||||
GST_DEBUG_CATEGORY (mxf_debug);
|
GST_DEBUG_CATEGORY (mxf_debug);
|
||||||
#define GST_CAT_DEFAULT mxf_debug
|
#define GST_CAT_DEFAULT mxf_debug
|
||||||
|
|
||||||
|
static void
|
||||||
|
mxf_init (void)
|
||||||
|
{
|
||||||
|
gst_tag_register (GST_TAG_MXF_UMID, GST_TAG_FLAG_META,
|
||||||
|
G_TYPE_STRING, "UMID", "Unique Material Identifier", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_init (GstPlugin * plugin)
|
plugin_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
|
mxf_init ();
|
||||||
mxf_metadata_init_types ();
|
mxf_metadata_init_types ();
|
||||||
mxf_aes_bwf_init ();
|
mxf_aes_bwf_init ();
|
||||||
mxf_mpeg_init ();
|
mxf_mpeg_init ();
|
||||||
|
|
|
@ -36,8 +36,7 @@
|
||||||
* The latter are just 16 byte unique identifiers
|
* The latter are just 16 byte unique identifiers
|
||||||
* - Check everything for correctness vs. SMPTE S336M, some things can probably
|
* - Check everything for correctness vs. SMPTE S336M, some things can probably
|
||||||
* be generalized/simplified
|
* be generalized/simplified
|
||||||
* - Seeking support: IndexTableSegments and skip-to-position seeks, needs correct
|
* - Seeking support: Use IndexTableSegments
|
||||||
* timestamp calculation, etc.
|
|
||||||
* - Handle timecode tracks correctly (where is this documented?)
|
* - Handle timecode tracks correctly (where is this documented?)
|
||||||
* - Handle Generic container system items
|
* - Handle Generic container system items
|
||||||
* - Implement correct support for clip-wrapped essence elements.
|
* - Implement correct support for clip-wrapped essence elements.
|
||||||
|
@ -49,6 +48,9 @@
|
||||||
* - Correctly handle the different rectangles and aspect-ratio for video
|
* - Correctly handle the different rectangles and aspect-ratio for video
|
||||||
* - Add support for non-standard MXF used by Avid (bug #561922).
|
* - Add support for non-standard MXF used by Avid (bug #561922).
|
||||||
* - Fix frame layout stuff, i.e. interlaced/progressive
|
* - Fix frame layout stuff, i.e. interlaced/progressive
|
||||||
|
* - Extend essence element handlers to set DELTA_UNIT flag.
|
||||||
|
* - In pull mode first find the first buffer for every pad before pushing
|
||||||
|
* to prevent jumpy playback in the beginning due to resynchronization.
|
||||||
*
|
*
|
||||||
* - Implement SMPTE D11 essence and the digital cinema/MXF specs
|
* - Implement SMPTE D11 essence and the digital cinema/MXF specs
|
||||||
*
|
*
|
||||||
|
@ -113,7 +115,8 @@ gst_mxf_demux_pad_init (GstMXFDemuxPad * pad)
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_PACKAGE
|
PROP_PACKAGE,
|
||||||
|
PROP_MAX_DRIFT
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event);
|
||||||
|
@ -132,12 +135,9 @@ gst_mxf_demux_remove_pad (GstMXFDemuxPad * pad, GstMXFDemux * demux)
|
||||||
static void
|
static void
|
||||||
gst_mxf_demux_remove_pads (GstMXFDemux * demux)
|
gst_mxf_demux_remove_pads (GstMXFDemux * demux)
|
||||||
{
|
{
|
||||||
if (demux->src) {
|
g_ptr_array_foreach (demux->src, (GFunc) gst_mxf_demux_remove_pad, demux);
|
||||||
g_ptr_array_foreach (demux->src, (GFunc) gst_mxf_demux_remove_pad, demux);
|
g_ptr_array_foreach (demux->src, (GFunc) gst_object_unref, NULL);
|
||||||
g_ptr_array_foreach (demux->src, (GFunc) gst_object_unref, NULL);
|
g_ptr_array_set_size (demux->src, 0);
|
||||||
g_ptr_array_free (demux->src, TRUE);
|
|
||||||
demux->src = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -189,14 +189,12 @@ gst_mxf_demux_reset_linked_metadata (GstMXFDemux * demux)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (demux->src) {
|
for (i = 0; i < demux->src->len; i++) {
|
||||||
for (i = 0; i < demux->src->len; i++) {
|
GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
|
||||||
GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
|
|
||||||
|
|
||||||
pad->material_track = NULL;
|
pad->material_track = NULL;
|
||||||
pad->material_package = NULL;
|
pad->material_package = NULL;
|
||||||
pad->current_component = NULL;
|
pad->current_component = NULL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (demux->essence_tracks) {
|
if (demux->essence_tracks) {
|
||||||
|
@ -350,7 +348,7 @@ gst_mxf_demux_push_src_event (GstMXFDemux * demux, GstEvent * event)
|
||||||
GST_DEBUG_OBJECT (demux, "Pushing '%s' event downstream",
|
GST_DEBUG_OBJECT (demux, "Pushing '%s' event downstream",
|
||||||
GST_EVENT_TYPE_NAME (event));
|
GST_EVENT_TYPE_NAME (event));
|
||||||
|
|
||||||
if (!demux->src)
|
if (demux->src->len == 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
for (i = 0; i < demux->src->len; i++) {
|
for (i = 0; i < demux->src->len; i++) {
|
||||||
|
@ -374,9 +372,6 @@ gst_mxf_demux_get_earliest_pad (GstMXFDemux * demux)
|
||||||
GstClockTime earliest = GST_CLOCK_TIME_NONE;
|
GstClockTime earliest = GST_CLOCK_TIME_NONE;
|
||||||
GstMXFDemuxPad *pad = NULL;
|
GstMXFDemuxPad *pad = NULL;
|
||||||
|
|
||||||
if (!demux->src)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < demux->src->len; i++) {
|
for (i = 0; i < demux->src->len; i++) {
|
||||||
GstMXFDemuxPad *p = g_ptr_array_index (demux->src, i);
|
GstMXFDemuxPad *p = g_ptr_array_index (demux->src, i);
|
||||||
|
|
||||||
|
@ -638,11 +633,11 @@ gst_mxf_demux_choose_package (GstMXFDemux * demux)
|
||||||
|
|
||||||
for (i = 0; i < demux->preface->content_storage->n_packages; i++) {
|
for (i = 0; i < demux->preface->content_storage->n_packages; i++) {
|
||||||
if (demux->preface->content_storage->packages[i] &&
|
if (demux->preface->content_storage->packages[i] &&
|
||||||
MXF_IS_METADATA_MATERIAL_PACKAGE (demux->preface->content_storage->
|
MXF_IS_METADATA_MATERIAL_PACKAGE (demux->preface->
|
||||||
packages[i])) {
|
content_storage->packages[i])) {
|
||||||
ret =
|
ret =
|
||||||
MXF_METADATA_GENERIC_PACKAGE (demux->preface->content_storage->
|
MXF_METADATA_GENERIC_PACKAGE (demux->preface->
|
||||||
packages[i]);
|
content_storage->packages[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,15 +650,20 @@ gst_mxf_demux_choose_package (GstMXFDemux * demux)
|
||||||
done:
|
done:
|
||||||
if (memcmp (&ret->package_uid, &demux->current_package_uid, 32) != 0) {
|
if (memcmp (&ret->package_uid, &demux->current_package_uid, 32) != 0) {
|
||||||
gchar current_package_string[96];
|
gchar current_package_string[96];
|
||||||
|
GstTagList *tags = gst_tag_list_new ();
|
||||||
|
|
||||||
gst_mxf_demux_remove_pads (demux);
|
gst_mxf_demux_remove_pads (demux);
|
||||||
memcpy (&demux->current_package_uid, &ret->package_uid, 32);
|
memcpy (&demux->current_package_uid, &ret->package_uid, 32);
|
||||||
|
|
||||||
mxf_umid_to_string (&ret->package_uid, current_package_string);
|
mxf_umid_to_string (&ret->package_uid, current_package_string);
|
||||||
demux->current_package = ret;
|
|
||||||
demux->current_package_string = g_strdup (current_package_string);
|
demux->current_package_string = g_strdup (current_package_string);
|
||||||
g_object_notify (G_OBJECT (demux), "package");
|
g_object_notify (G_OBJECT (demux), "package");
|
||||||
|
|
||||||
|
gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_MXF_UMID,
|
||||||
|
demux->current_package_string, NULL);
|
||||||
|
gst_element_found_tags (GST_ELEMENT_CAST (demux), tags);
|
||||||
}
|
}
|
||||||
|
demux->current_package = ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -859,7 +859,7 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux)
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
first_run = (demux->src == NULL);
|
first_run = (demux->src->len == 0);
|
||||||
|
|
||||||
for (i = 0; i < current_package->n_tracks; i++) {
|
for (i = 0; i < current_package->n_tracks; i++) {
|
||||||
MXFMetadataTimelineTrack *track = NULL;
|
MXFMetadataTimelineTrack *track = NULL;
|
||||||
|
@ -884,7 +884,7 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux)
|
||||||
|
|
||||||
track = MXF_METADATA_TIMELINE_TRACK (current_package->tracks[i]);
|
track = MXF_METADATA_TIMELINE_TRACK (current_package->tracks[i]);
|
||||||
|
|
||||||
if (demux->src && demux->src->len > 0) {
|
if (demux->src->len > 0) {
|
||||||
/* Find pad from track_id */
|
/* Find pad from track_id */
|
||||||
for (j = 0; j < demux->src->len; j++) {
|
for (j = 0; j < demux->src->len; j++) {
|
||||||
GstMXFDemuxPad *tmp = g_ptr_array_index (demux->src, j);
|
GstMXFDemuxPad *tmp = g_ptr_array_index (demux->src, j);
|
||||||
|
@ -1095,8 +1095,6 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux)
|
||||||
|
|
||||||
gst_element_add_pad (GST_ELEMENT_CAST (demux), gst_object_ref (pad));
|
gst_element_add_pad (GST_ELEMENT_CAST (demux), gst_object_ref (pad));
|
||||||
|
|
||||||
if (!demux->src)
|
|
||||||
demux->src = g_ptr_array_new ();
|
|
||||||
g_ptr_array_add (demux->src, pad);
|
g_ptr_array_add (demux->src, pad);
|
||||||
pad->discont = TRUE;
|
pad->discont = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1105,7 +1103,7 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux)
|
||||||
if (first_run)
|
if (first_run)
|
||||||
gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
|
gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
|
||||||
|
|
||||||
if (demux->src) {
|
if (demux->src->len > 0) {
|
||||||
for (i = 0; i < demux->src->len; i++) {
|
for (i = 0; i < demux->src->len; i++) {
|
||||||
GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
|
GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
|
||||||
|
|
||||||
|
@ -1336,8 +1334,8 @@ gst_mxf_demux_pad_set_component (GstMXFDemux * demux, GstMXFDemuxPad * pad,
|
||||||
pad->current_component_index);
|
pad->current_component_index);
|
||||||
|
|
||||||
pad->current_component =
|
pad->current_component =
|
||||||
MXF_METADATA_SOURCE_CLIP (sequence->structural_components[pad->
|
MXF_METADATA_SOURCE_CLIP (sequence->
|
||||||
current_component_index]);
|
structural_components[pad->current_component_index]);
|
||||||
if (pad->current_component == NULL) {
|
if (pad->current_component == NULL) {
|
||||||
GST_ERROR_OBJECT (demux, "No such structural component");
|
GST_ERROR_OBJECT (demux, "No such structural component");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
@ -1345,8 +1343,8 @@ gst_mxf_demux_pad_set_component (GstMXFDemux * demux, GstMXFDemuxPad * pad,
|
||||||
|
|
||||||
if (!pad->current_component->source_package
|
if (!pad->current_component->source_package
|
||||||
|| !pad->current_component->source_package->top_level
|
|| !pad->current_component->source_package->top_level
|
||||||
|| !MXF_METADATA_GENERIC_PACKAGE (pad->current_component->
|
|| !MXF_METADATA_GENERIC_PACKAGE (pad->
|
||||||
source_package)->tracks) {
|
current_component->source_package)->tracks) {
|
||||||
GST_ERROR_OBJECT (demux, "Invalid component");
|
GST_ERROR_OBJECT (demux, "Invalid component");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1463,7 +1461,7 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!demux->src || demux->src->len == 0) {
|
if (demux->src->len == 0) {
|
||||||
GST_ERROR_OBJECT (demux, "No streams created yet");
|
GST_ERROR_OBJECT (demux, "No streams created yet");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1600,7 +1598,7 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
GstMXFDemuxPad *earliest = gst_mxf_demux_get_earliest_pad (demux);
|
GstMXFDemuxPad *earliest = gst_mxf_demux_get_earliest_pad (demux);
|
||||||
|
|
||||||
if (earliest && earliest != pad && earliest->last_stop < pad->last_stop &&
|
if (earliest && earliest != pad && earliest->last_stop < pad->last_stop &&
|
||||||
pad->last_stop - earliest->last_stop > 500 * GST_MSECOND) {
|
pad->last_stop - earliest->last_stop > demux->max_drift) {
|
||||||
GST_DEBUG_OBJECT (demux, "Pad is too far ahead of time");
|
GST_DEBUG_OBJECT (demux, "Pad is too far ahead of time");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2244,7 +2242,7 @@ gst_mxf_demux_set_partition_for_offset (GstMXFDemux * demux, guint64 offset)
|
||||||
for (l = demux->partitions; l; l = l->next) {
|
for (l = demux->partitions; l; l = l->next) {
|
||||||
GstMXFDemuxPartition *p = l->data;
|
GstMXFDemuxPartition *p = l->data;
|
||||||
|
|
||||||
if (p->partition.this_partition <= offset)
|
if (p->partition.this_partition + demux->run_in <= offset)
|
||||||
demux->current_partition = p;
|
demux->current_partition = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2421,7 +2419,7 @@ gst_mxf_demux_pull_and_handle_klv_packet (GstMXFDemux * demux)
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
guint read = 0;
|
guint read = 0;
|
||||||
|
|
||||||
if (demux->src) {
|
if (demux->src->len > 0) {
|
||||||
if (!gst_mxf_demux_get_earliest_pad (demux)) {
|
if (!gst_mxf_demux_get_earliest_pad (demux)) {
|
||||||
ret = GST_FLOW_UNEXPECTED;
|
ret = GST_FLOW_UNEXPECTED;
|
||||||
GST_DEBUG_OBJECT (demux, "All tracks are EOS");
|
GST_DEBUG_OBJECT (demux, "All tracks are EOS");
|
||||||
|
@ -2495,50 +2493,48 @@ gst_mxf_demux_pull_and_handle_klv_packet (GstMXFDemux * demux)
|
||||||
demux->offset += read;
|
demux->offset += read;
|
||||||
|
|
||||||
if (ret == GST_FLOW_OK && demux->src && demux->essence_tracks) {
|
if (ret == GST_FLOW_OK && demux->src && demux->essence_tracks) {
|
||||||
guint i;
|
|
||||||
GstMXFDemuxPad *earliest = NULL;
|
GstMXFDemuxPad *earliest = NULL;
|
||||||
guint64 offset;
|
|
||||||
gint64 position;
|
|
||||||
|
|
||||||
earliest = gst_mxf_demux_get_earliest_pad (demux);
|
|
||||||
if (!earliest)
|
|
||||||
goto beach;
|
|
||||||
|
|
||||||
/* We allow time drifts of at most 500ms */
|
/* We allow time drifts of at most 500ms */
|
||||||
if (demux->segment.last_stop - earliest->last_stop <= 500 * GST_MSECOND)
|
while ((earliest = gst_mxf_demux_get_earliest_pad (demux)) &&
|
||||||
goto beach;
|
demux->segment.last_stop - earliest->last_stop > demux->max_drift) {
|
||||||
|
guint i;
|
||||||
|
guint64 offset;
|
||||||
|
gint64 position;
|
||||||
|
|
||||||
GST_WARNING_OBJECT (demux,
|
GST_WARNING_OBJECT (demux,
|
||||||
"Found synchronization issue -- trying to solve");
|
"Found synchronization issue -- trying to solve");
|
||||||
|
|
||||||
position = earliest->current_essence_track_position;
|
position = earliest->current_essence_track_position;
|
||||||
|
|
||||||
/* FIXME: This can probably be improved by using the
|
/* FIXME: This can probably be improved by using the
|
||||||
* offset of position-1 if it's in the same partition
|
* offset of position-1 if it's in the same partition
|
||||||
* or the start of the position otherwise.
|
* or the start of the position otherwise.
|
||||||
* This way we won't skip elements from the same essence
|
* This way we won't skip elements from the same essence
|
||||||
* container as etrack->position
|
* container as etrack->position
|
||||||
*/
|
*/
|
||||||
offset =
|
offset =
|
||||||
gst_mxf_demux_find_essence_element (demux,
|
gst_mxf_demux_find_essence_element (demux,
|
||||||
earliest->current_essence_track, &position, FALSE);
|
earliest->current_essence_track, &position, FALSE);
|
||||||
if (offset == -1) {
|
if (offset == -1) {
|
||||||
GST_ERROR_OBJECT (demux, "Failed to find offset for late essence track");
|
GST_ERROR_OBJECT (demux,
|
||||||
earliest->eos = TRUE;
|
"Failed to find offset for late essence track");
|
||||||
gst_pad_push_event (GST_PAD_CAST (earliest), gst_event_new_eos ());
|
earliest->eos = TRUE;
|
||||||
goto beach;
|
gst_pad_push_event (GST_PAD_CAST (earliest), gst_event_new_eos ());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
demux->offset = offset + demux->run_in;
|
||||||
|
gst_mxf_demux_set_partition_for_offset (demux, demux->offset);
|
||||||
|
|
||||||
|
for (i = 0; i < demux->essence_tracks->len; i++) {
|
||||||
|
GstMXFDemuxEssenceTrack *etrack =
|
||||||
|
&g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack, i);
|
||||||
|
|
||||||
|
etrack->position = -1;
|
||||||
|
}
|
||||||
|
earliest->current_essence_track->position = position;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
demux->offset = offset + demux->run_in;
|
|
||||||
gst_mxf_demux_set_partition_for_offset (demux, demux->offset);
|
|
||||||
|
|
||||||
for (i = 0; i < demux->essence_tracks->len; i++) {
|
|
||||||
GstMXFDemuxEssenceTrack *etrack =
|
|
||||||
&g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack, i);
|
|
||||||
|
|
||||||
etrack->position = -1;
|
|
||||||
}
|
|
||||||
earliest->current_essence_track->position = position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
|
@ -2670,7 +2666,7 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf)
|
||||||
GST_LOG_OBJECT (demux, "received buffer of %u bytes at offset %"
|
GST_LOG_OBJECT (demux, "received buffer of %u bytes at offset %"
|
||||||
G_GUINT64_FORMAT, GST_BUFFER_SIZE (inbuf), GST_BUFFER_OFFSET (inbuf));
|
G_GUINT64_FORMAT, GST_BUFFER_SIZE (inbuf), GST_BUFFER_OFFSET (inbuf));
|
||||||
|
|
||||||
if (demux->src) {
|
if (demux->src->len > 0) {
|
||||||
if (!gst_mxf_demux_get_earliest_pad (demux)) {
|
if (!gst_mxf_demux_get_earliest_pad (demux)) {
|
||||||
ret = GST_FLOW_UNEXPECTED;
|
ret = GST_FLOW_UNEXPECTED;
|
||||||
GST_DEBUG_OBJECT (demux, "All tracks are EOS");
|
GST_DEBUG_OBJECT (demux, "All tracks are EOS");
|
||||||
|
@ -2687,6 +2683,9 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf)
|
||||||
if (G_UNLIKELY (demux->offset == 0 && GST_BUFFER_OFFSET (inbuf) != 0)) {
|
if (G_UNLIKELY (demux->offset == 0 && GST_BUFFER_OFFSET (inbuf) != 0)) {
|
||||||
GST_DEBUG_OBJECT (demux, "offset was zero, synchronizing with buffer's");
|
GST_DEBUG_OBJECT (demux, "offset was zero, synchronizing with buffer's");
|
||||||
demux->offset = GST_BUFFER_OFFSET (inbuf);
|
demux->offset = GST_BUFFER_OFFSET (inbuf);
|
||||||
|
gst_mxf_demux_set_partition_for_offset (demux, demux->offset);
|
||||||
|
} else if (demux->current_partition == NULL) {
|
||||||
|
gst_mxf_demux_set_partition_for_offset (demux, demux->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_adapter_push (demux->adapter, inbuf);
|
gst_adapter_push (demux->adapter, inbuf);
|
||||||
|
@ -2844,8 +2843,8 @@ gst_mxf_demux_pad_set_position (GstMXFDemux * demux, GstMXFDemuxPad * p,
|
||||||
for (i = 0; i < p->material_track->parent.sequence->n_structural_components;
|
for (i = 0; i < p->material_track->parent.sequence->n_structural_components;
|
||||||
i++) {
|
i++) {
|
||||||
clip =
|
clip =
|
||||||
MXF_METADATA_SOURCE_CLIP (p->material_track->parent.sequence->
|
MXF_METADATA_SOURCE_CLIP (p->material_track->parent.
|
||||||
structural_components[i]);
|
sequence->structural_components[i]);
|
||||||
|
|
||||||
if (clip->parent.duration <= 0)
|
if (clip->parent.duration <= 0)
|
||||||
break;
|
break;
|
||||||
|
@ -3105,6 +3104,7 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event)
|
||||||
goto no_new_offset;
|
goto no_new_offset;
|
||||||
|
|
||||||
demux->offset = new_offset + demux->run_in;
|
demux->offset = new_offset + demux->run_in;
|
||||||
|
gst_mxf_demux_set_partition_for_offset (demux, demux->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (demux->close_seg_event)) {
|
if (G_UNLIKELY (demux->close_seg_event)) {
|
||||||
|
@ -3373,11 +3373,69 @@ gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event)
|
||||||
demux->offset = 0;
|
demux->offset = 0;
|
||||||
ret = gst_mxf_demux_push_src_event (demux, event);
|
ret = gst_mxf_demux_push_src_event (demux, event);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:{
|
||||||
if (!gst_mxf_demux_push_src_event (demux, event))
|
GstMXFDemuxPad *p = NULL;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < demux->essence_tracks->len; i++) {
|
||||||
|
GstMXFDemuxEssenceTrack *t =
|
||||||
|
&g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack, i);
|
||||||
|
|
||||||
|
if (t->position > 0)
|
||||||
|
t->duration = t->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < demux->src->len; i++) {
|
||||||
|
GstMXFDemuxPad *p = g_ptr_array_index (demux->src, i);
|
||||||
|
|
||||||
|
if (!p->eos
|
||||||
|
&& p->current_essence_track_position >=
|
||||||
|
p->current_essence_track->duration) {
|
||||||
|
p->eos = TRUE;
|
||||||
|
gst_pad_push_event (GST_PAD_CAST (p), gst_event_new_eos ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((p = gst_mxf_demux_get_earliest_pad (demux))) {
|
||||||
|
guint64 offset;
|
||||||
|
gint64 position;
|
||||||
|
|
||||||
|
position = p->current_essence_track_position;
|
||||||
|
|
||||||
|
offset =
|
||||||
|
gst_mxf_demux_find_essence_element (demux, p->current_essence_track,
|
||||||
|
&position, FALSE);
|
||||||
|
if (offset == -1) {
|
||||||
|
GST_ERROR_OBJECT (demux, "Failed to find offset for essence track");
|
||||||
|
p->eos = TRUE;
|
||||||
|
gst_pad_push_event (GST_PAD_CAST (p), gst_event_new_eos ());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_pad_push_event (demux->sinkpad,
|
||||||
|
gst_event_new_seek (demux->segment.rate, GST_FORMAT_BYTES,
|
||||||
|
demux->segment.flags | GST_SEEK_FLAG_ACCURATE,
|
||||||
|
GST_SEEK_TYPE_SET, offset + demux->run_in,
|
||||||
|
GST_SEEK_TYPE_NONE, 0))) {
|
||||||
|
|
||||||
|
for (i = 0; i < demux->essence_tracks->len; i++) {
|
||||||
|
GstMXFDemuxEssenceTrack *etrack =
|
||||||
|
&g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack,
|
||||||
|
i);
|
||||||
|
etrack->position = -1;
|
||||||
|
}
|
||||||
|
ret = TRUE;
|
||||||
|
goto out;
|
||||||
|
} else {
|
||||||
|
GST_WARNING_OBJECT (demux,
|
||||||
|
"Seek to remaining part of the file failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ret = gst_mxf_demux_push_src_event (demux, event)))
|
||||||
GST_WARNING_OBJECT (pad, "failed pushing EOS on streams");
|
GST_WARNING_OBJECT (pad, "failed pushing EOS on streams");
|
||||||
ret = TRUE;
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GST_EVENT_NEWSEGMENT:{
|
case GST_EVENT_NEWSEGMENT:{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
|
@ -3389,6 +3447,7 @@ gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event)
|
||||||
t->position = -1;
|
t->position = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
demux->current_partition = NULL;
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -3398,6 +3457,7 @@ gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
gst_object_unref (demux);
|
gst_object_unref (demux);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -3454,7 +3514,7 @@ gst_mxf_demux_query (GstElement * element, GstQuery * query)
|
||||||
if (format != GST_FORMAT_TIME)
|
if (format != GST_FORMAT_TIME)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!demux->src)
|
if (demux->src->len == 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
for (i = 0; i < demux->src->len; i++) {
|
for (i = 0; i < demux->src->len; i++) {
|
||||||
|
@ -3545,6 +3605,9 @@ gst_mxf_demux_set_property (GObject * object, guint prop_id,
|
||||||
g_free (demux->requested_package_string);
|
g_free (demux->requested_package_string);
|
||||||
demux->requested_package_string = g_value_dup_string (value);
|
demux->requested_package_string = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_DRIFT:
|
||||||
|
demux->max_drift = g_value_get_uint64 (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -3561,6 +3624,9 @@ gst_mxf_demux_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_PACKAGE:
|
case PROP_PACKAGE:
|
||||||
g_value_set_string (value, demux->current_package_string);
|
g_value_set_string (value, demux->current_package_string);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_DRIFT:
|
||||||
|
g_value_set_uint64 (value, demux->max_drift);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -3589,6 +3655,9 @@ gst_mxf_demux_finalize (GObject * object)
|
||||||
g_free (demux->requested_package_string);
|
g_free (demux->requested_package_string);
|
||||||
demux->requested_package_string = NULL;
|
demux->requested_package_string = NULL;
|
||||||
|
|
||||||
|
g_ptr_array_free (demux->src, TRUE);
|
||||||
|
demux->src = NULL;
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3623,6 +3692,12 @@ gst_mxf_demux_class_init (GstMXFDemuxClass * klass)
|
||||||
"Material or Source package to use for playback", NULL,
|
"Material or Source package to use for playback", NULL,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MAX_DRIFT,
|
||||||
|
g_param_spec_uint64 ("max-drift", "Maximum drift",
|
||||||
|
"Maximum number of nanoseconds by which tracks can differ",
|
||||||
|
100 * GST_MSECOND, G_MAXUINT64, 500 * GST_MSECOND,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gstelement_class->change_state =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_mxf_demux_change_state);
|
GST_DEBUG_FUNCPTR (gst_mxf_demux_change_state);
|
||||||
gstelement_class->query = GST_DEBUG_FUNCPTR (gst_mxf_demux_query);
|
gstelement_class->query = GST_DEBUG_FUNCPTR (gst_mxf_demux_query);
|
||||||
|
@ -3649,6 +3724,8 @@ gst_mxf_demux_init (GstMXFDemux * demux, GstMXFDemuxClass * g_class)
|
||||||
|
|
||||||
gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
|
||||||
|
|
||||||
|
demux->max_drift = 500 * GST_MSECOND;
|
||||||
|
|
||||||
demux->adapter = gst_adapter_new ();
|
demux->adapter = gst_adapter_new ();
|
||||||
demux->src = g_ptr_array_new ();
|
demux->src = g_ptr_array_new ();
|
||||||
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
||||||
|
|
|
@ -161,7 +161,10 @@ struct _GstMXFDemux
|
||||||
MXFUMID current_package_uid;
|
MXFUMID current_package_uid;
|
||||||
MXFMetadataGenericPackage *current_package;
|
MXFMetadataGenericPackage *current_package;
|
||||||
gchar *current_package_string;
|
gchar *current_package_string;
|
||||||
|
|
||||||
|
/* Properties */
|
||||||
gchar *requested_package_string;
|
gchar *requested_package_string;
|
||||||
|
GstClockTime max_drift;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstMXFDemuxClass
|
struct _GstMXFDemuxClass
|
||||||
|
|
|
@ -154,4 +154,6 @@ typedef struct {
|
||||||
GHashTable *other_tags;
|
GHashTable *other_tags;
|
||||||
} MXFIndexTableSegment;
|
} MXFIndexTableSegment;
|
||||||
|
|
||||||
|
#define GST_TAG_MXF_UMID "mxf-umid"
|
||||||
|
|
||||||
#endif /* __MXF_TYPES_H__ */
|
#endif /* __MXF_TYPES_H__ */
|
||||||
|
|
Loading…
Reference in a new issue