diff options
Diffstat (limited to 'gst/mxf')
-rw-r--r-- | gst/mxf/mxf.c | 3 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.c | 161 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfmux.c | 107 | ||||
-rw-r--r-- | gst/mxf/mxfmux.h | 1 |
6 files changed, 178 insertions, 98 deletions
diff --git a/gst/mxf/mxf.c b/gst/mxf/mxf.c index c1a0a716..7469317c 100644 --- a/gst/mxf/mxf.c +++ b/gst/mxf/mxf.c @@ -71,7 +71,8 @@ plugin_init (GstPlugin * plugin) if (!gst_element_register (plugin, "mxfdemux", GST_RANK_PRIMARY, GST_TYPE_MXF_DEMUX) || - !gst_element_register (plugin, "mxfmux", GST_RANK_NONE, GST_TYPE_MXF_MUX)) + !gst_element_register (plugin, "mxfmux", GST_RANK_PRIMARY, + GST_TYPE_MXF_MUX)) return FALSE; return TRUE; diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c index 6d7ca034..c33650b5 100644 --- a/gst/mxf/mxfdemux.c +++ b/gst/mxf/mxfdemux.c @@ -203,7 +203,7 @@ gst_mxf_demux_reset_metadata (GstMXFDemux * demux) { GST_DEBUG_OBJECT (demux, "Resetting metadata"); - g_mutex_lock (demux->metadata_lock); + g_static_rw_lock_writer_lock (&demux->metadata_lock); demux->update_metadata = TRUE; demux->metadata_resolved = FALSE; @@ -217,7 +217,7 @@ gst_mxf_demux_reset_metadata (GstMXFDemux * demux) } demux->metadata = mxf_metadata_hash_table_new (); - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_writer_unlock (&demux->metadata_lock); } static void @@ -513,11 +513,14 @@ gst_mxf_demux_resolve_references (GstMXFDemux * demux) GstStructure *structure; GstTagList *taglist; + g_static_rw_lock_writer_lock (&demux->metadata_lock); + GST_DEBUG_OBJECT (demux, "Resolve metadata references"); demux->update_metadata = FALSE; if (!demux->metadata) { GST_ERROR_OBJECT (demux, "No metadata yet"); + g_static_rw_lock_writer_unlock (&demux->metadata_lock); return GST_FLOW_ERROR; } #if GLIB_CHECK_VERSION (2, 16, 0) @@ -565,6 +568,8 @@ gst_mxf_demux_resolve_references (GstMXFDemux * demux) g_list_free (values); #endif + g_static_rw_lock_writer_unlock (&demux->metadata_lock); + return ret; error: @@ -573,6 +578,7 @@ error: #endif demux->metadata_resolved = FALSE; + g_static_rw_lock_writer_unlock (&demux->metadata_lock); return ret; } @@ -913,24 +919,29 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) gboolean first_run; guint component_index; GstFlowReturn ret; + GList *pads = NULL, *l; + g_static_rw_lock_writer_lock (&demux->metadata_lock); GST_DEBUG_OBJECT (demux, "Updating tracks"); if ((ret = gst_mxf_demux_update_essence_tracks (demux)) != GST_FLOW_OK) { - return ret; + goto error; } current_package = gst_mxf_demux_choose_package (demux); if (!current_package) { GST_ERROR_OBJECT (demux, "Unable to find current package"); - return GST_FLOW_ERROR; + ret = GST_FLOW_ERROR; + goto error; } else if (!current_package->tracks) { GST_ERROR_OBJECT (demux, "Current package has no (resolved) tracks"); - return GST_FLOW_ERROR; + ret = GST_FLOW_ERROR; + goto error; } else if (!current_package->n_essence_tracks) { GST_ERROR_OBJECT (demux, "Current package has no essence tracks"); - return GST_FLOW_ERROR; + ret = GST_FLOW_ERROR; + goto error; } first_run = (demux->src->len == 0); @@ -977,10 +988,12 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) if (!track->parent.sequence) { GST_WARNING_OBJECT (demux, "Track with no sequence"); - if (!pad) + if (!pad) { continue; - else - return GST_FLOW_ERROR; + } else { + ret = GST_FLOW_ERROR; + goto error; + } } sequence = track->parent.sequence; @@ -1021,20 +1034,24 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) if (track->parent.type && (track->parent.type & 0xf0) != 0x30) { GST_DEBUG_OBJECT (demux, "No essence track"); - if (!pad) + if (!pad) { continue; - else - return GST_FLOW_ERROR; + } else { + ret = GST_FLOW_ERROR; + goto error; + } } if (!source_package || track->parent.type == MXF_METADATA_TRACK_UNKNOWN || !source_track) { GST_WARNING_OBJECT (demux, "No source package or track type for track found"); - if (!pad) + if (!pad) { continue; - else - return GST_FLOW_ERROR; + } else { + ret = GST_FLOW_ERROR; + goto error; + } } for (k = 0; k < demux->essence_tracks->len; k++) { @@ -1050,44 +1067,54 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) if (!etrack) { GST_WARNING_OBJECT (demux, "No essence track for this track found"); - if (!pad) + if (!pad) { continue; - else - return GST_FLOW_ERROR; + } else { + ret = GST_FLOW_ERROR; + goto error; + } } if (track->edit_rate.n <= 0 || track->edit_rate.d <= 0 || source_track->edit_rate.n <= 0 || source_track->edit_rate.d <= 0) { GST_WARNING_OBJECT (demux, "Track has an invalid edit rate"); - if (!pad) + if (!pad) { continue; - else - return GST_FLOW_ERROR; + } else { + ret = GST_FLOW_ERROR; + goto error; + } } if (MXF_IS_METADATA_MATERIAL_PACKAGE (current_package) && !component) { GST_WARNING_OBJECT (demux, "Playing material package but found no component for track"); - if (!pad) + if (!pad) { continue; - else - return GST_FLOW_ERROR; + } else { + ret = GST_FLOW_ERROR; + goto error; + } } if (!source_package->descriptor) { GST_WARNING_OBJECT (demux, "Source package has no descriptors"); - if (!pad) + if (!pad) { continue; - else - return GST_FLOW_ERROR; + } else { + ret = GST_FLOW_ERROR; + goto error; + } } if (!source_track->parent.descriptor) { GST_WARNING_OBJECT (demux, "No descriptor found for track"); - if (!pad) + if (!pad) { continue; - else - return GST_FLOW_ERROR; + } else { + ret = GST_FLOW_ERROR; + goto error; + } } if (!pad && first_run) { @@ -1178,31 +1205,43 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) gst_pad_use_fixed_caps (GST_PAD_CAST (pad)); gst_pad_set_active (GST_PAD_CAST (pad), TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (demux), gst_object_ref (pad)); + pads = g_list_prepend (pads, gst_object_ref (pad)); g_ptr_array_add (demux->src, pad); pad->discont = TRUE; } } - if (first_run) - gst_element_no_more_pads (GST_ELEMENT_CAST (demux)); - if (demux->src->len > 0) { for (i = 0; i < demux->src->len; i++) { GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i); if (!pad->material_track || !pad->material_package) { GST_ERROR_OBJECT (demux, "Unable to update existing pad"); - return GST_FLOW_ERROR; + ret = GST_FLOW_ERROR; + goto error; } } } else { GST_ERROR_OBJECT (demux, "Couldn't create any streams"); - return GST_FLOW_ERROR; + ret = GST_FLOW_ERROR; + goto error; } + g_static_rw_lock_writer_unlock (&demux->metadata_lock); + + for (l = pads; l; l = l->next) + gst_element_add_pad (GST_ELEMENT_CAST (demux), l->data); + g_list_free (pads); + + if (first_run) + gst_element_no_more_pads (GST_ELEMENT_CAST (demux)); + return GST_FLOW_OK; + +error: + g_static_rw_lock_writer_unlock (&demux->metadata_lock); + return ret; } static GstFlowReturn @@ -1276,7 +1315,7 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key, return GST_FLOW_OK; } - g_mutex_lock (demux->metadata_lock); + g_static_rw_lock_writer_lock (&demux->metadata_lock); demux->update_metadata = TRUE; if (MXF_IS_METADATA_PREFACE (metadata)) { @@ -1287,7 +1326,7 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key, g_hash_table_replace (demux->metadata, &MXF_METADATA_BASE (metadata)->instance_uid, metadata); - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_writer_unlock (&demux->metadata_lock); return ret; } @@ -1365,7 +1404,7 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux, return GST_FLOW_OK; } - g_mutex_lock (demux->metadata_lock); + g_static_rw_lock_writer_lock (&demux->metadata_lock); demux->update_metadata = TRUE; gst_mxf_demux_reset_linked_metadata (demux); @@ -1373,7 +1412,7 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux, g_hash_table_replace (demux->metadata, &MXF_METADATA_BASE (m)->instance_uid, m); - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_writer_unlock (&demux->metadata_lock); return ret; } @@ -2224,17 +2263,14 @@ next_try: /* resolve references etc */ - g_mutex_lock (demux->metadata_lock); if (gst_mxf_demux_resolve_references (demux) != GST_FLOW_OK || gst_mxf_demux_update_tracks (demux) != GST_FLOW_OK) { demux->current_partition->parsed_metadata = TRUE; demux->offset = demux->run_in + demux->current_partition->partition.this_partition - demux->current_partition->partition.prev_partition; - g_mutex_unlock (demux->metadata_lock); goto next_try; } - g_mutex_unlock (demux->metadata_lock); out: if (buffer) @@ -2253,7 +2289,6 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key, #endif GstFlowReturn ret = GST_FLOW_OK; - g_mutex_lock (demux->metadata_lock); if (demux->update_metadata && demux->preface && (demux->offset >= @@ -2265,16 +2300,13 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key, demux->current_partition->parsed_metadata = TRUE; if ((ret = gst_mxf_demux_resolve_references (demux)) != GST_FLOW_OK || (ret = gst_mxf_demux_update_tracks (demux)) != GST_FLOW_OK) { - g_mutex_unlock (demux->metadata_lock); goto beach; } } else if (demux->metadata_resolved && demux->requested_package_string) { if ((ret = gst_mxf_demux_update_tracks (demux)) != GST_FLOW_OK) { - g_mutex_unlock (demux->metadata_lock); goto beach; } } - g_mutex_unlock (demux->metadata_lock); if (!mxf_is_mxf_packet (key)) { GST_WARNING_OBJECT (demux, @@ -3106,15 +3138,12 @@ gst_mxf_demux_seek_push (GstMXFDemux * demux, GstEvent * event) guint64 new_offset = -1; GstEvent *e; - g_mutex_lock (demux->metadata_lock); if (!demux->metadata_resolved || demux->update_metadata) { if (gst_mxf_demux_resolve_references (demux) != GST_FLOW_OK || gst_mxf_demux_update_tracks (demux) != GST_FLOW_OK) { - g_mutex_unlock (demux->metadata_lock); goto unresolved_metadata; } } - g_mutex_unlock (demux->metadata_lock); /* Do the actual seeking */ for (i = 0; i < demux->src->len; i++) { @@ -3266,15 +3295,12 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) if (flush || seeksegment.last_stop != demux->segment.last_stop) { guint64 new_offset = -1; - g_mutex_lock (demux->metadata_lock); if (!demux->metadata_resolved || demux->update_metadata) { if (gst_mxf_demux_resolve_references (demux) != GST_FLOW_OK || gst_mxf_demux_update_tracks (demux) != GST_FLOW_OK) { - g_mutex_unlock (demux->metadata_lock); goto unresolved_metadata; } } - g_mutex_unlock (demux->metadata_lock); /* Do the actual seeking */ for (i = 0; i < demux->src->len; i++) { @@ -3455,11 +3481,11 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) pos = mxfpad->last_stop; - g_mutex_lock (demux->metadata_lock); + g_static_rw_lock_reader_lock (&demux->metadata_lock); if (format == GST_FORMAT_DEFAULT && pos != GST_CLOCK_TIME_NONE) { if (!mxfpad->material_track || mxfpad->material_track->edit_rate.n == 0 || mxfpad->material_track->edit_rate.d == 0) { - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_reader_unlock (&demux->metadata_lock); goto error; } @@ -3468,7 +3494,7 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) mxfpad->material_track->edit_rate.n, mxfpad->material_track->edit_rate.d * GST_SECOND); } - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_reader_unlock (&demux->metadata_lock); GST_DEBUG_OBJECT (pad, "Returning position %" G_GINT64_FORMAT " in format %s", pos, @@ -3487,9 +3513,9 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT) goto error; - g_mutex_lock (demux->metadata_lock); + g_static_rw_lock_reader_lock (&demux->metadata_lock); if (!mxfpad->material_track || !mxfpad->material_track->parent.sequence) { - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_reader_unlock (&demux->metadata_lock); goto error; } @@ -3500,7 +3526,7 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) if (duration != -1 && format == GST_FORMAT_TIME) { if (mxfpad->material_track->edit_rate.n == 0 || mxfpad->material_track->edit_rate.d == 0) { - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_reader_unlock (&demux->metadata_lock); goto error; } @@ -3509,7 +3535,7 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) GST_SECOND * mxfpad->material_track->edit_rate.d, mxfpad->material_track->edit_rate.n); } - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_reader_unlock (&demux->metadata_lock); GST_DEBUG_OBJECT (pad, "Returning duration %" G_GINT64_FORMAT " in format %s", duration, @@ -3746,7 +3772,7 @@ gst_mxf_demux_query (GstElement * element, GstQuery * query) if (demux->src->len == 0) goto done; - g_mutex_lock (demux->metadata_lock); + g_static_rw_lock_reader_lock (&demux->metadata_lock); for (i = 0; i < demux->src->len; i++) { GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i); gint64 pdur = -1; @@ -3765,7 +3791,7 @@ gst_mxf_demux_query (GstElement * element, GstQuery * query) pad->material_track->edit_rate.n); duration = MAX (duration, pdur); } - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_reader_unlock (&demux->metadata_lock); if (duration == -1) { GST_DEBUG_OBJECT (demux, "No duration known (yet)"); @@ -3862,7 +3888,7 @@ gst_mxf_demux_get_property (GObject * object, guint prop_id, case PROP_STRUCTURE:{ GstStructure *s; - g_mutex_lock (demux->metadata_lock); + g_static_rw_lock_reader_lock (&demux->metadata_lock); if (demux->preface) s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (demux->preface)); else @@ -3873,7 +3899,7 @@ gst_mxf_demux_get_property (GObject * object, guint prop_id, if (s) gst_structure_free (s); - g_mutex_unlock (demux->metadata_lock); + g_static_rw_lock_reader_unlock (&demux->metadata_lock); break; } default: @@ -3911,10 +3937,7 @@ gst_mxf_demux_finalize (GObject * object) g_hash_table_destroy (demux->metadata); - if (demux->metadata_lock) { - g_mutex_free (demux->metadata_lock); - demux->metadata_lock = NULL; - } + g_static_rw_lock_free (&demux->metadata_lock); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -3990,7 +4013,7 @@ gst_mxf_demux_init (GstMXFDemux * demux, GstMXFDemuxClass * g_class) demux->max_drift = 500 * GST_MSECOND; demux->adapter = gst_adapter_new (); - demux->metadata_lock = g_mutex_new (); + g_static_rw_lock_init (&demux->metadata_lock); demux->src = g_ptr_array_new (); demux->essence_tracks = diff --git a/gst/mxf/mxfdemux.h b/gst/mxf/mxfdemux.h index c8439cf6..e8b90261 100644 --- a/gst/mxf/mxfdemux.h +++ b/gst/mxf/mxfdemux.h @@ -154,7 +154,7 @@ struct _GstMXFDemux GArray *random_index_pack; /* Metadata */ - GMutex *metadata_lock; + GStaticRWLock metadata_lock; gboolean update_metadata; gboolean pull_footer_metadata; diff --git a/gst/mxf/mxfmetadata.c b/gst/mxf/mxfmetadata.c index 2237bc60..7d1af0c1 100644 --- a/gst/mxf/mxfmetadata.c +++ b/gst/mxf/mxfmetadata.c @@ -4984,7 +4984,7 @@ gboolean s = gst_caps_get_structure (caps, 0); if (!gst_structure_get_boolean (s, "interlaced", &interlaced) || !interlaced) - self->frame_layout = 1; + self->frame_layout = 0; else self->frame_layout = 3; diff --git a/gst/mxf/mxfmux.c b/gst/mxf/mxfmux.c index 3ca60a4e..fdc1bc61 100644 --- a/gst/mxf/mxfmux.c +++ b/gst/mxf/mxfmux.c @@ -163,6 +163,8 @@ gst_mxf_mux_finalize (GObject * object) if (mux->metadata) { g_hash_table_destroy (mux->metadata); mux->metadata = NULL; + g_list_free (mux->metadata_list); + mux->metadata_list = NULL; } gst_object_unref (mux->collect); @@ -216,6 +218,8 @@ gst_mxf_mux_reset (GstMXFMux * mux) if (mux->metadata) { g_hash_table_destroy (mux->metadata); mux->preface = NULL; + g_list_free (mux->metadata_list); + mux->metadata_list = NULL; } mux->metadata = mxf_metadata_hash_table_new (); @@ -280,6 +284,7 @@ gst_mxf_mux_setcaps (GstPad * pad, GstCaps * caps) gboolean ret = TRUE; MXFUUID d_instance_uid = { {0,} }; MXFMetadataFileDescriptor *old_descriptor = cpad->descriptor; + GList *l; GST_DEBUG_OBJECT (pad, "Setting caps %" GST_PTR_FORMAT, caps); @@ -309,6 +314,19 @@ gst_mxf_mux_setcaps (GstPad * pad, GstCaps * caps) memcpy (&MXF_METADATA_BASE (cpad->descriptor)->instance_uid, &d_instance_uid, 16); + if (old_descriptor) { + for (l = mux->metadata_list; l; l = l->next) { + MXFMetadataBase *tmp = l->data; + + if (mxf_uuid_is_equal (&d_instance_uid, &tmp->instance_uid)) { + l->data = cpad->descriptor; + break; + } + } + } else { + mux->metadata_list = g_list_prepend (mux->metadata_list, cpad->descriptor); + } + g_hash_table_replace (mux->metadata, &MXF_METADATA_BASE (cpad->descriptor)->instance_uid, cpad->descriptor); @@ -449,6 +467,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (mux->preface)->instance_uid, mux->preface); + mux->metadata_list = g_list_prepend (mux->metadata_list, mux->preface); mxf_timestamp_set_now (&mux->preface->last_modified_date); mux->preface->version = 258; @@ -505,6 +524,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (identification)->instance_uid, identification); + mux->metadata_list = g_list_prepend (mux->metadata_list, identification); mxf_uuid_init (&identification->this_generation_uid, NULL); @@ -561,6 +581,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mxf_uuid_init (&MXF_METADATA_BASE (cstorage)->instance_uid, mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (cstorage)->instance_uid, cstorage); + mux->metadata_list = g_list_prepend (mux->metadata_list, cstorage); cstorage->n_packages = 2; cstorage->packages = g_new0 (MXFMetadataGenericPackage *, 2); @@ -576,6 +597,8 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (cstorage->packages[1])->instance_uid, cstorage->packages[1]); + mux->metadata_list = + g_list_prepend (mux->metadata_list, cstorage->packages[1]); p = (MXFMetadataSourcePackage *) cstorage->packages[1]; mxf_umid_init (&p->parent.package_uid); @@ -601,6 +624,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mxf_uuid_init (&MXF_METADATA_BASE (d)->instance_uid, mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (d)->instance_uid, d); + mux->metadata_list = g_list_prepend (mux->metadata_list, d); } /* Tracks */ @@ -621,6 +645,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (track)->instance_uid, track); + mux->metadata_list = g_list_prepend (mux->metadata_list, track); track->parent.track_id = n + 1; track->parent.track_number = @@ -637,6 +662,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (sequence)->instance_uid, sequence); + mux->metadata_list = g_list_prepend (mux->metadata_list, sequence); memcpy (&sequence->data_definition, &cpad->writer->data_definition, 16); @@ -653,6 +679,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (clip)->instance_uid, clip); + mux->metadata_list = g_list_prepend (mux->metadata_list, clip); memcpy (&clip->parent.data_definition, &sequence->data_definition, 16); @@ -687,6 +714,8 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (cstorage->packages[0])->instance_uid, cstorage->packages[0]); + mux->metadata_list = + g_list_prepend (mux->metadata_list, cstorage->packages[0]); p = (MXFMetadataMaterialPackage *) cstorage->packages[0]; mxf_umid_init (&p->package_uid); @@ -724,6 +753,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (track)->instance_uid, track); + mux->metadata_list = g_list_prepend (mux->metadata_list, track); track->parent.track_id = n + 1; track->parent.track_number = 0; @@ -757,6 +787,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (sequence)->instance_uid, sequence); + mux->metadata_list = g_list_prepend (mux->metadata_list, sequence); memcpy (&sequence->data_definition, &cpad->writer->data_definition, 16); @@ -772,6 +803,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (clip)->instance_uid, clip); + mux->metadata_list = g_list_prepend (mux->metadata_list, clip); memcpy (&clip->parent.data_definition, &sequence->data_definition, 16); @@ -798,6 +830,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (track)->instance_uid, track); + mux->metadata_list = g_list_prepend (mux->metadata_list, track); track->parent.track_id = n + 1; track->parent.track_number = 0; @@ -811,6 +844,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (sequence)->instance_uid, sequence); + mux->metadata_list = g_list_prepend (mux->metadata_list, sequence); memcpy (&sequence->data_definition, mxf_metadata_track_identifier_get @@ -828,6 +862,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (component)->instance_uid, component); + mux->metadata_list = g_list_prepend (mux->metadata_list, component); memcpy (&component->parent.data_definition, &sequence->data_definition, 16); @@ -884,6 +919,9 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (cstorage->essence_container_data[0])->instance_uid, cstorage->essence_container_data[0]); + mux->metadata_list = + g_list_prepend (mux->metadata_list, + cstorage->essence_container_data[0]); cstorage->essence_container_data[0]->linked_package = MXF_METADATA_SOURCE_PACKAGE (cstorage->packages[1]); @@ -891,6 +929,43 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) cstorage->essence_container_data[0]->body_sid = 1; } + /* Sort descriptors at the correct places */ + { + GList *l; + GList *descriptors = NULL; + + for (l = mux->metadata_list; l; l = l->next) { + MXFMetadataBase *m = l->data; + + if (MXF_IS_METADATA_GENERIC_DESCRIPTOR (m) + && !MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (m)) { + descriptors = l; + l->prev->next = NULL; + l->prev = NULL; + break; + } + } + + g_assert (descriptors != NULL); + + for (l = mux->metadata_list; l; l = l->next) { + MXFMetadataBase *m = l->data; + GList *s; + + if (MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (m) || + MXF_IS_METADATA_SOURCE_PACKAGE (m)) { + s = l->prev; + l->prev = g_list_last (descriptors); + s->next = descriptors; + descriptors->prev = s; + l->prev->next = l; + break; + } + } + } + + mux->metadata_list = g_list_reverse (mux->metadata_list); + return ret; } @@ -953,38 +1028,17 @@ gst_mxf_mux_write_header_metadata (GstMXFMux * mux) GstFlowReturn ret = GST_FLOW_OK; GstBuffer *buf; GList *buffers = NULL; -#if GLIB_CHECK_VERSION (2, 16, 0) - GHashTableIter iter; -#else - GList *values; -#endif - MXFMetadataBase *m; GList *l; + MXFMetadataBase *m; guint64 header_byte_count = 0; - buf = - mxf_metadata_base_to_buffer (MXF_METADATA_BASE (mux->preface), - &mux->primer); - header_byte_count += GST_BUFFER_SIZE (buf); - buffers = g_list_prepend (buffers, buf); - -#if GLIB_CHECK_VERSION (2, 16, 0) - g_hash_table_iter_init (&iter, mux->metadata); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) & m)) { -#else - values = g_hash_table_get_values (mux->metadata); - for (l = values; l; l = l->next) { + for (l = mux->metadata_list; l; l = l->next) { m = l->data; -#endif buf = mxf_metadata_base_to_buffer (m, &mux->primer); header_byte_count += GST_BUFFER_SIZE (buf); buffers = g_list_prepend (buffers, buf); } -#if !GLIB_CHECK_VERSION (2, 16, 0) - g_list_free (values); -#endif - buffers = g_list_reverse (buffers); buf = mxf_primer_pack_to_buffer (&mux->primer); header_byte_count += GST_BUFFER_SIZE (buf); @@ -1006,7 +1060,7 @@ gst_mxf_mux_write_header_metadata (GstMXFMux * mux) if ((ret = gst_mxf_mux_push (mux, buf)) != GST_FLOW_OK) { GST_ERROR_OBJECT (mux, "Failed pushing buffer: %s", gst_flow_get_name (ret)); - g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL); + g_list_foreach (l, (GFunc) gst_mini_object_unref, NULL); g_list_free (buffers); return ret; } @@ -1150,10 +1204,11 @@ gst_mxf_mux_handle_eos (GstMXFMux * mux) best = cpad; break; } - } else if (have_data && !l->next) { + } + + if (have_data && !l->next) { mux->last_gc_position++; mux->last_gc_timestamp = next_gc_timestamp; - have_data = FALSE; best = NULL; break; } diff --git a/gst/mxf/mxfmux.h b/gst/mxf/mxfmux.h index c8fd0b09..94330c46 100644 --- a/gst/mxf/mxfmux.h +++ b/gst/mxf/mxfmux.h @@ -85,6 +85,7 @@ typedef struct _GstMXFMux { MXFPrimerPack primer; GHashTable *metadata; + GList *metadata_list; MXFMetadataPreface *preface; MXFFraction min_edit_rate; |