mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
mxfmux: Write index table segments
But only for the first essence track, and once for every keyframe every 2 seconds.
This commit is contained in:
parent
1addfcc0b2
commit
df7209a1c5
2 changed files with 81 additions and 3 deletions
|
@ -190,6 +190,7 @@ gst_mxf_mux_class_init (GstMXFMuxClass * klass)
|
||||||
static void
|
static void
|
||||||
gst_mxf_mux_init (GstMXFMux * mux)
|
gst_mxf_mux_init (GstMXFMux * mux)
|
||||||
{
|
{
|
||||||
|
mux->index_table = g_array_new (FALSE, FALSE, sizeof (MXFIndexTableSegment));
|
||||||
gst_mxf_mux_reset (mux);
|
gst_mxf_mux_reset (mux);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +208,11 @@ gst_mxf_mux_finalize (GObject * object)
|
||||||
mux->metadata_list = NULL;
|
mux->metadata_list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mux->index_table) {
|
||||||
|
g_array_free (mux->index_table, TRUE);
|
||||||
|
mux->index_table = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,6 +250,8 @@ gst_mxf_mux_reset (GstMXFMux * mux)
|
||||||
mux->last_gc_timestamp = 0;
|
mux->last_gc_timestamp = 0;
|
||||||
mux->last_gc_position = 0;
|
mux->last_gc_position = 0;
|
||||||
mux->offset = 0;
|
mux->offset = 0;
|
||||||
|
|
||||||
|
g_array_set_size (mux->index_table, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -958,7 +966,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
|
||||||
|
|
||||||
cstorage->essence_container_data[0]->linked_package =
|
cstorage->essence_container_data[0]->linked_package =
|
||||||
MXF_METADATA_SOURCE_PACKAGE (cstorage->packages[1]);
|
MXF_METADATA_SOURCE_PACKAGE (cstorage->packages[1]);
|
||||||
cstorage->essence_container_data[0]->index_sid = 0;
|
cstorage->essence_container_data[0]->index_sid = 1;
|
||||||
cstorage->essence_container_data[0]->body_sid = 1;
|
cstorage->essence_container_data[0]->body_sid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1124,6 +1132,8 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * pad)
|
||||||
guint8 slen, ber[9];
|
guint8 slen, ber[9];
|
||||||
gboolean flush = gst_aggregator_pad_is_eos (GST_AGGREGATOR_PAD (pad))
|
gboolean flush = gst_aggregator_pad_is_eos (GST_AGGREGATOR_PAD (pad))
|
||||||
&& !pad->have_complete_edit_unit && buf == NULL;
|
&& !pad->have_complete_edit_unit && buf == NULL;
|
||||||
|
gboolean is_keyframe =
|
||||||
|
!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
|
||||||
if (pad->have_complete_edit_unit) {
|
if (pad->have_complete_edit_unit) {
|
||||||
GST_DEBUG_OBJECT (pad,
|
GST_DEBUG_OBJECT (pad,
|
||||||
|
@ -1169,6 +1179,50 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * pad)
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* We currently only index the first essence stream */
|
||||||
|
if (pad == (GstMXFMuxPad *) GST_ELEMENT_CAST (mux)->sinkpads->data) {
|
||||||
|
MXFIndexTableSegment *segment;
|
||||||
|
const gint max_segment_size = G_MAXUINT16 / 11;
|
||||||
|
|
||||||
|
if (mux->index_table->len == 0 ||
|
||||||
|
g_array_index (mux->index_table, MXFIndexTableSegment,
|
||||||
|
mux->index_table->len - 1).index_duration >= max_segment_size) {
|
||||||
|
MXFIndexTableSegment s;
|
||||||
|
|
||||||
|
memset (&segment, 0, sizeof (segment));
|
||||||
|
|
||||||
|
mxf_uuid_init (&s.instance_id, mux->metadata);
|
||||||
|
memcpy (&s.index_edit_rate, &pad->source_track->edit_rate,
|
||||||
|
sizeof (s.index_edit_rate));
|
||||||
|
s.index_start_position = pad->pos;
|
||||||
|
s.index_duration = 0;
|
||||||
|
s.edit_unit_byte_count = 0;
|
||||||
|
s.index_sid =
|
||||||
|
mux->preface->content_storage->essence_container_data[0]->index_sid;
|
||||||
|
s.body_sid =
|
||||||
|
mux->preface->content_storage->essence_container_data[0]->body_sid;
|
||||||
|
s.slice_count = 0;
|
||||||
|
s.pos_table_count = 0;
|
||||||
|
s.n_delta_entries = 0;
|
||||||
|
s.delta_entries = NULL;
|
||||||
|
s.n_index_entries = 0;
|
||||||
|
s.index_entries = g_new0 (MXFIndexEntry, max_segment_size);
|
||||||
|
g_array_append_val (mux->index_table, s);
|
||||||
|
}
|
||||||
|
segment =
|
||||||
|
&g_array_index (mux->index_table, MXFIndexTableSegment,
|
||||||
|
mux->index_table->len - 1);
|
||||||
|
|
||||||
|
segment->index_entries[segment->n_index_entries].temporal_offset = 0;
|
||||||
|
segment->index_entries[segment->n_index_entries].key_frame_offset = 0;
|
||||||
|
segment->index_entries[segment->n_index_entries].flags = is_keyframe ? 0x80 : 0x20; /* FIXME: Need to distinguish all the cases */
|
||||||
|
segment->index_entries[segment->n_index_entries].stream_offset =
|
||||||
|
mux->partition.body_offset;
|
||||||
|
|
||||||
|
segment->n_index_entries++;
|
||||||
|
segment->index_duration++;
|
||||||
|
}
|
||||||
|
|
||||||
buf_size = gst_buffer_get_size (buf);
|
buf_size = gst_buffer_get_size (buf);
|
||||||
slen = mxf_ber_encode_size (buf_size, ber);
|
slen = mxf_ber_encode_size (buf_size, ber);
|
||||||
outbuf = gst_buffer_new_and_alloc (16 + slen);
|
outbuf = gst_buffer_new_and_alloc (16 + slen);
|
||||||
|
@ -1183,6 +1237,7 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * pad)
|
||||||
"Pushing buffer of size %" G_GSIZE_FORMAT " for track %u",
|
"Pushing buffer of size %" G_GSIZE_FORMAT " for track %u",
|
||||||
gst_buffer_get_size (outbuf), pad->source_track->parent.track_id);
|
gst_buffer_get_size (outbuf), pad->source_track->parent.track_id);
|
||||||
|
|
||||||
|
mux->partition.body_offset += gst_buffer_get_size (outbuf);
|
||||||
if ((ret = gst_mxf_mux_push (mux, outbuf)) != GST_FLOW_OK) {
|
if ((ret = gst_mxf_mux_push (mux, outbuf)) != GST_FLOW_OK) {
|
||||||
GST_ERROR_OBJECT (pad,
|
GST_ERROR_OBJECT (pad,
|
||||||
"Failed pushing buffer for track %u, reason %s",
|
"Failed pushing buffer for track %u, reason %s",
|
||||||
|
@ -1327,6 +1382,18 @@ gst_mxf_mux_handle_eos (GstMXFMux * mux)
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
MXFRandomIndexPackEntry entry;
|
MXFRandomIndexPackEntry entry;
|
||||||
|
GList *index_entries = NULL, *l;
|
||||||
|
guint index_byte_count = 0;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < mux->index_table->len; i++) {
|
||||||
|
MXFIndexTableSegment *segment =
|
||||||
|
&g_array_index (mux->index_table, MXFIndexTableSegment, i);
|
||||||
|
GstBuffer *segment_buffer = mxf_index_table_segment_to_buffer (segment);
|
||||||
|
|
||||||
|
index_byte_count += gst_buffer_get_size (segment_buffer);
|
||||||
|
index_entries = g_list_prepend (index_entries, segment_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
mux->partition.type = MXF_PARTITION_PACK_FOOTER;
|
mux->partition.type = MXF_PARTITION_PACK_FOOTER;
|
||||||
mux->partition.closed = TRUE;
|
mux->partition.closed = TRUE;
|
||||||
|
@ -1335,13 +1402,22 @@ gst_mxf_mux_handle_eos (GstMXFMux * mux)
|
||||||
mux->partition.prev_partition = body_partition;
|
mux->partition.prev_partition = body_partition;
|
||||||
mux->partition.footer_partition = mux->offset;
|
mux->partition.footer_partition = mux->offset;
|
||||||
mux->partition.header_byte_count = 0;
|
mux->partition.header_byte_count = 0;
|
||||||
mux->partition.index_byte_count = 0;
|
mux->partition.index_byte_count = index_byte_count;
|
||||||
mux->partition.index_sid = 0;
|
mux->partition.index_sid =
|
||||||
|
mux->preface->content_storage->essence_container_data[0]->index_sid;
|
||||||
mux->partition.body_offset = 0;
|
mux->partition.body_offset = 0;
|
||||||
mux->partition.body_sid = 0;
|
mux->partition.body_sid = 0;
|
||||||
|
|
||||||
gst_mxf_mux_write_header_metadata (mux);
|
gst_mxf_mux_write_header_metadata (mux);
|
||||||
|
|
||||||
|
index_entries = g_list_reverse (index_entries);
|
||||||
|
for (l = index_entries; l; l = l->next) {
|
||||||
|
if ((ret = gst_mxf_mux_push (mux, l->data)) != GST_FLOW_OK) {
|
||||||
|
GST_ERROR_OBJECT (mux, "Failed pushing index table segment");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_list_free (index_entries);
|
||||||
|
|
||||||
rip = g_array_sized_new (FALSE, FALSE, sizeof (MXFRandomIndexPackEntry), 3);
|
rip = g_array_sized_new (FALSE, FALSE, sizeof (MXFRandomIndexPackEntry), 3);
|
||||||
entry.offset = 0;
|
entry.offset = 0;
|
||||||
entry.body_sid = 0;
|
entry.body_sid = 0;
|
||||||
|
|
|
@ -68,6 +68,8 @@ typedef struct _GstMXFMux {
|
||||||
GstClockTime last_gc_timestamp;
|
GstClockTime last_gc_timestamp;
|
||||||
|
|
||||||
gchar *application;
|
gchar *application;
|
||||||
|
|
||||||
|
GArray *index_table;
|
||||||
} GstMXFMux;
|
} GstMXFMux;
|
||||||
|
|
||||||
typedef struct _GstMXFMuxClass {
|
typedef struct _GstMXFMuxClass {
|
||||||
|
|
Loading…
Reference in a new issue