summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2017-06-27 15:01:22 +0300
committerSebastian Dröge <sebastian@centricular.com>2017-07-04 09:16:34 +0300
commitc470925d26099c797e63fd1ce72cd3ff7f742f7a (patch)
tree52623518412afc5a6a6cbeb9ed68756c9f16bb07
parent655781ad1af90d991af10294c4acb908813b74fb (diff)
downloadgstreamer-plugins-bad-c470925d26099c797e63fd1ce72cd3ff7f742f7a.tar.gz
mxfmux: Write temporal offset and correct keyframe offset into index table
https://bugzilla.gnome.org/show_bug.cgi?id=784027
-rw-r--r--gst/mxf/mxfmux.c143
-rw-r--r--gst/mxf/mxfmux.h2
2 files changed, 120 insertions, 25 deletions
diff --git a/gst/mxf/mxfmux.c b/gst/mxf/mxfmux.c
index 4f6632107..02a476eb3 100644
--- a/gst/mxf/mxfmux.c
+++ b/gst/mxf/mxfmux.c
@@ -265,6 +265,8 @@ gst_mxf_mux_reset (GstMXFMux * mux)
g_free (g_array_index (mux->index_table, MXFIndexTableSegment,
n).index_entries);
g_array_set_size (mux->index_table, 0);
+ mux->current_index_pos = 0;
+ mux->last_keyframe_pos = 0;
}
static gboolean
@@ -1216,6 +1218,8 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * pad)
&& !pad->have_complete_edit_unit && buf == NULL;
gboolean is_keyframe = buf ?
!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT) : TRUE;
+ GstClockTime pts = buf ? GST_BUFFER_PTS (buf) : GST_CLOCK_TIME_NONE;
+ GstClockTime dts = buf ? GST_BUFFER_DTS (buf) : GST_CLOCK_TIME_NONE;
if (pad->have_complete_edit_unit) {
GST_DEBUG_OBJECT (pad,
@@ -1268,35 +1272,124 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * pad)
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);
+ mux->current_index_pos).index_duration >= max_segment_size) {
+
+ if (mux->index_table->len > 0)
+ mux->current_index_pos++;
+
+ if (mux->index_table->len <= mux->current_index_pos) {
+ 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));
+ if (mux->index_table->len > 0)
+ s.index_start_position =
+ g_array_index (mux->index_table, MXFIndexTableSegment,
+ mux->index_table->len - 1).index_start_position;
+ else
+ s.index_start_position = 0;
+ 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);
+ mux->current_index_pos);
+
+ if (dts != GST_CLOCK_TIME_NONE && pts != GST_CLOCK_TIME_NONE) {
+ guint64 pts_pos;
+ guint64 pts_index_pos, pts_segment_pos;
+ gint64 index_pos_diff;
+ MXFIndexTableSegment *pts_segment;
+
+ pts =
+ gst_segment_to_running_time (&pad->parent.segment, GST_FORMAT_TIME,
+ pts);
+ pts_pos =
+ gst_util_uint64_scale_round (pts, pad->source_track->edit_rate.n,
+ pad->source_track->edit_rate.d * GST_SECOND);
+
+ index_pos_diff = pts_pos - pad->pos;
+ pts_index_pos = mux->current_index_pos;
+ pts_segment_pos = segment->n_index_entries;
+ if (index_pos_diff >= 0) {
+ while (pts_segment_pos + index_pos_diff >= max_segment_size) {
+ index_pos_diff -= max_segment_size - pts_segment_pos;
+ pts_segment_pos = 0;
+ pts_index_pos++;
+
+ if (pts_index_pos >= mux->index_table->len) {
+ 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));
+ if (mux->index_table->len > 0)
+ s.index_start_position =
+ g_array_index (mux->index_table, MXFIndexTableSegment,
+ mux->index_table->len - 1).index_start_position;
+ else
+ s.index_start_position = 0;
+ 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);
+ }
+ }
+ } else {
+ while (pts_segment_pos + index_pos_diff <= 0) {
+ if (pts_index_pos == 0) {
+ pts_index_pos = G_MAXUINT64;
+ break;
+ }
+ index_pos_diff += pts_segment_pos;
+ pts_segment_pos = max_segment_size;
+ pts_index_pos--;
+ }
+ }
+ if (pts_index_pos != G_MAXUINT64) {
+ g_assert (index_pos_diff < 127 && index_pos_diff >= -127);
+ pts_segment =
+ &g_array_index (mux->index_table, MXFIndexTableSegment,
+ pts_index_pos);
+ pts_segment->index_entries[pts_segment_pos +
+ index_pos_diff].temporal_offset = -index_pos_diff;
+ }
+ }
- segment->index_entries[segment->n_index_entries].temporal_offset = 0;
- segment->index_entries[segment->n_index_entries].key_frame_offset = 0;
+ /* Leave temporal offset initialized at 0, above code will set it as necessary */
+ ;
+ if (is_keyframe)
+ mux->last_keyframe_pos = pad->pos;
+ segment->index_entries[segment->n_index_entries].key_frame_offset =
+ MIN (pad->pos - mux->last_keyframe_pos, 127);
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;
diff --git a/gst/mxf/mxfmux.h b/gst/mxf/mxfmux.h
index e88736255..eb8291ee1 100644
--- a/gst/mxf/mxfmux.h
+++ b/gst/mxf/mxfmux.h
@@ -70,6 +70,8 @@ typedef struct _GstMXFMux {
gchar *application;
GArray *index_table;
+ guint current_index_pos;
+ guint64 last_keyframe_pos;
} GstMXFMux;
typedef struct _GstMXFMuxClass {