diff options
author | Edgard Lima <edgard.lima@indt.org.br> | 2007-12-14 18:18:37 +0000 |
---|---|---|
committer | Edgard Lima <edgard.lima@indt.org.br> | 2007-12-14 18:18:37 +0000 |
commit | b2a023be7baa09662fc63cf177a1adc79b0b3cf2 (patch) | |
tree | 513245f11375fe70acc57f25d6fe0f1d0eb72ca4 /ext/metadata/gstmetadatamux.c | |
parent | 91bb79004f36a6cb50c7b46f6e014e660a90b297 (diff) | |
download | gst-plugins-bad-b2a023be7baa09662fc63cf177a1adc79b0b3cf2.tar.gz gst-plugins-bad-b2a023be7baa09662fc63cf177a1adc79b0b3cf2.tar.bz2 gst-plugins-bad-b2a023be7baa09662fc63cf177a1adc79b0b3cf2.zip |
Added new module for common functions. Using GST_TYPE_FRACTION for Exif (S)Rational types.
Original commit message from CVS:
Added new module for common functions. Using GST_TYPE_FRACTION for Exif (S)Rational types.
Diffstat (limited to 'ext/metadata/gstmetadatamux.c')
-rw-r--r-- | ext/metadata/gstmetadatamux.c | 759 |
1 files changed, 107 insertions, 652 deletions
diff --git a/ext/metadata/gstmetadatamux.c b/ext/metadata/gstmetadatamux.c index 5c1a3bed..f2c2a895 100644 --- a/ext/metadata/gstmetadatamux.c +++ b/ext/metadata/gstmetadatamux.c @@ -154,6 +154,7 @@ static void gst_metadata_mux_init_members (GstMetadataMux * filter); static void gst_metadata_mux_dispose_members (GstMetadataMux * filter); static gboolean gst_metadata_mux_configure_srccaps (GstMetadataMux * filter); + static gboolean gst_metadata_mux_configure_caps (GstMetadataMux * filter); static int @@ -162,25 +163,10 @@ gst_metadata_mux_parse (GstMetadataMux * filter, const guint8 * buf, static void gst_metadata_mux_create_chunks_from_tags (GstMetadataMux * filter); -static int -gst_metadata_mux_get_strip_seg (const gint64 offset, guint32 size, - const gint64 seg_offset, const guint32 seg_size, - gint64 * boffset, guint32 * bsize, guint32 * seg_binter); - -static gboolean -gst_metadata_mux_strip_push_buffer (GstMetadataMux * filter, - gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf); - -static gboolean -gst_metadata_mux_translate_pos_to_orig (GstMetadataMux * filter, gint64 pos, - gint64 * orig_pos, GstBuffer ** buf); - static const GstQueryType *gst_metadata_mux_get_query_types (GstPad * pad); static gboolean gst_metadata_mux_src_query (GstPad * pad, GstQuery * query); -static gboolean gst_metadata_mux_calculate_offsets (GstMetadataMux * filter); - static void gst_metadata_mux_base_init (gpointer gclass) { @@ -283,11 +269,11 @@ gst_metadata_mux_init (GstMetadataMux * filter, GstMetadataMuxClass * gclass) gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); - metadataparse_xmp_init (); /* init members */ filter->options = META_OPT_EXIF | META_OPT_IPTC | META_OPT_XMP; + gst_metadata_mux_init_members (filter); } @@ -415,6 +401,48 @@ done: } +static void +gst_metadata_create_chunks_from_tags (GstMetadataMux * filter) +{ + + GstMessage *msg; + GstTagSetter *setter = GST_TAG_SETTER (filter); + const GstTagList *taglist = gst_tag_setter_get_tag_list (setter); + GstEvent *event; + guint8 *buf = NULL; + guint32 size = 0; + + if (taglist) { + + if (filter->options & META_OPT_EXIF) { + metadatamux_exif_create_chunk_from_tag_list (&buf, &size, taglist); + gst_metadata_common_update_segment_with_new_buffer (&filter->common, &buf, + &size, MD_CHUNK_EXIF); + } + + if (filter->options & META_OPT_IPTC) { + metadatamux_iptc_create_chunk_from_tag_list (&buf, &size, taglist); + gst_metadata_common_update_segment_with_new_buffer (&filter->common, &buf, + &size, MD_CHUNK_IPTC); + } + + if (filter->options & META_OPT_XMP) { + metadatamux_xmp_create_chunk_from_tag_list (&buf, &size, taglist); + gst_metadata_common_update_segment_with_new_buffer (&filter->common, &buf, + &size, MD_CHUNK_XMP); + } + + } + + if (buf) { + g_free (buf); + } + + metadata_chunk_array_remove_zero_size (&filter->common.metadata. + inject_chunks); + +} + static gboolean gst_metadata_mux_src_event (GstPad * pad, GstEvent * event) { @@ -436,7 +464,10 @@ gst_metadata_mux_src_event (GstPad * pad, GstEvent * event) /* we don't know where are the chunks to be stripped before mux */ if (filter->need_calculate_offset) { - if (!gst_metadata_mux_calculate_offsets (filter)) + gst_metadata_create_chunks_from_tags (filter); + if (gst_metadata_common_calculate_offsets (&filter->common)) + filter->need_calculate_offset = FALSE; + else goto done; } @@ -447,10 +478,10 @@ gst_metadata_mux_src_event (GstPad * pad, GstEvent * event) case GST_FORMAT_BYTES: break; case GST_FORMAT_PERCENT: - if (filter->duration < 0) + if (filter->common.duration < 0) goto done; - start = start * filter->duration / 100; - stop = stop * filter->duration / 100; + start = start * filter->common.duration / 100; + stop = stop * filter->common.duration / 100; break; default: goto done; @@ -460,9 +491,9 @@ gst_metadata_mux_src_event (GstPad * pad, GstEvent * event) if (start_type == GST_SEEK_TYPE_CUR) start = filter->offset + start; else if (start_type == GST_SEEK_TYPE_END) { - if (filter->duration < 0) + if (filter->common.duration < 0) goto done; - start = filter->duration + start; + start = filter->common.duration + start; } start_type == GST_SEEK_TYPE_SET; @@ -473,20 +504,21 @@ gst_metadata_mux_src_event (GstPad * pad, GstEvent * event) /* FIXME: related to append */ filter->offset = start; - gst_metadata_mux_translate_pos_to_orig (filter, start, &start, + gst_metadata_common_translate_pos_to_orig (&filter->common, start, &start, &filter->prepend_buffer); filter->offset_orig = start; if (stop_type == GST_SEEK_TYPE_CUR) stop = filter->offset + stop; else if (stop_type == GST_SEEK_TYPE_END) { - if (filter->duration < 0) + if (filter->common.duration < 0) goto done; - stop = filter->duration + stop; + stop = filter->common.duration + stop; } stop_type == GST_SEEK_TYPE_SET; - gst_metadata_mux_translate_pos_to_orig (filter, stop, &stop, NULL); + gst_metadata_common_translate_pos_to_orig (&filter->common, stop, &stop, + NULL); gst_event_unref (event); event = gst_event_new_seek (rate, format, flags, @@ -573,7 +605,7 @@ gst_metadata_mux_finalize (GObject * object) static void gst_metadata_mux_dispose_members (GstMetadataMux * filter) { - metadata_dispose (&filter->mux_data); + gst_metadata_common_dispose (&filter->common); if (filter->adapter_parsing) { gst_object_unref (filter->adapter_parsing); @@ -585,11 +617,6 @@ gst_metadata_mux_dispose_members (GstMetadataMux * filter) filter->adapter_holding = NULL; } - if (filter->append_buffer) { - gst_buffer_unref (filter->append_buffer); - filter->append_buffer = NULL; - } - if (filter->prepend_buffer) { gst_buffer_unref (filter->prepend_buffer); filter->prepend_buffer = NULL; @@ -607,16 +634,12 @@ gst_metadata_mux_init_members (GstMetadataMux * filter) filter->next_size = 0; filter->img_type = IMG_NONE; filter->offset_orig = 0; - filter->duration_orig = 0; filter->offset = 0; - filter->duration = 0; - filter->state = MT_STATE_NULL; filter->need_more_data = FALSE; - filter->append_buffer = NULL; filter->prepend_buffer = NULL; - memset (&filter->mux_data, 0x00, sizeof (MetaData)); + memset (&filter->common, 0x00, sizeof (filter->common)); } @@ -742,96 +765,6 @@ done: return ret; } -static const gchar * -gst_metadata_mux_get_type_name (int img_type) -{ - gchar *type_name = NULL; - - switch (img_type) { - case IMG_JPEG: - type_name = "jpeg"; - break; - case IMG_PNG: - type_name = "png"; - break; - default: - type_name = "invalid type"; - break; - } - return type_name; -} - -static void -gst_metadata_update_segment (GstMetadataMux * filter, guint8 ** buf, - guint32 * size, MetadataChunkType type) -{ - int i; - MetadataChunk *inject = filter->mux_data.inject_chunks.chunk; - const gsize inject_len = filter->mux_data.inject_chunks.len; - - if (!(buf && size)) - goto done; - if (*buf == 0) - goto done; - if (*size == 0) - goto done; - - for (i = 0; i < inject_len; ++i) { - if (inject[i].type == type) { - inject[i].size = *size; - if (inject[i].data) - g_free (inject[i].data); - inject[i].data = *buf; - *size = 0; - *buf = 0; - break; - } - } - -done: - - return; - -} - -static void -gst_metadata_create_chunks_from_tags (GstMetadataMux * filter) -{ - - GstMessage *msg; - GstTagSetter *setter = GST_TAG_SETTER (filter); - const GstTagList *taglist = gst_tag_setter_get_tag_list (setter); - GstEvent *event; - guint8 *buf = NULL; - guint32 size = 0; - - if (taglist) { - - if (filter->options & META_OPT_EXIF) { - metadatamux_exif_create_chunk_from_tag_list (&buf, &size, taglist); - gst_metadata_update_segment (filter, &buf, &size, MD_CHUNK_EXIF); - } - - if (filter->options & META_OPT_IPTC) { - metadatamux_iptc_create_chunk_from_tag_list (&buf, &size, taglist); - gst_metadata_update_segment (filter, &buf, &size, MD_CHUNK_IPTC); - } - - if (filter->options & META_OPT_XMP) { - metadatamux_xmp_create_chunk_from_tag_list (&buf, &size, taglist); - gst_metadata_update_segment (filter, &buf, &size, MD_CHUNK_XMP); - } - - } - - if (buf) { - g_free (buf); - } - - metadata_chunk_array_remove_zero_size (&filter->mux_data.inject_chunks); - -} - static const GstQueryType * gst_metadata_mux_get_query_types (GstPad * pad) { @@ -863,15 +796,19 @@ gst_metadata_mux_src_query (GstPad * pad, GstQuery * query) break; case GST_QUERY_DURATION: if (filter->need_calculate_offset) { - if (!gst_metadata_mux_calculate_offsets (filter)) + gst_metadata_create_chunks_from_tags (filter); + if (gst_metadata_common_calculate_offsets (&filter->common)) + filter->need_calculate_offset = FALSE; + else goto done; } gst_query_parse_duration (query, &format, NULL); if (format == GST_FORMAT_BYTES) { - if (filter->duration >= 0) { - gst_query_set_duration (query, GST_FORMAT_BYTES, filter->duration); + if (filter->common.duration >= 0) { + gst_query_set_duration (query, GST_FORMAT_BYTES, + filter->common.duration); ret = TRUE; } } @@ -893,91 +830,6 @@ done: } /* - * return: - * -1 -> error - * 0 -> succeded - * 1 -> need more data - */ - -static gboolean -gst_metadata_mux_calculate_offsets (GstMetadataMux * filter) -{ - int i, j; - guint32 append_size; - guint32 bytes_striped, bytes_inject; - MetadataChunk *strip = filter->mux_data.strip_chunks.chunk; - MetadataChunk *inject = filter->mux_data.inject_chunks.chunk; - gsize strip_len; - gsize inject_len; - - if (filter->state != MT_STATE_MUXED) - return FALSE; - - gst_metadata_create_chunks_from_tags (filter); - - metadata_lazy_update (&filter->mux_data); - - strip_len = filter->mux_data.strip_chunks.len; - inject_len = filter->mux_data.inject_chunks.len; - - bytes_striped = 0; - bytes_inject = 0; - - /* calculate the new position off injected chunks */ - j = 0; - for (i = 0; i < inject_len; ++i) { - for (; j < strip_len; ++j) { - if (strip[j].offset_orig >= inject[i].offset_orig) { - break; - } - bytes_striped += strip[j].size; - } - inject[i].offset = inject[i].offset_orig - bytes_striped + bytes_inject; - bytes_inject += inject[i].size; - } - - /* calculate append (doesnt make much sense, but, anyway..) */ - append_size = 0; - for (i = inject_len - 1; i >= 0; --i) { - if (inject[i].offset_orig == filter->duration_orig) - append_size += inject[i].size; - else - break; - } - if (append_size) { - guint8 *data; - - filter->append_buffer = gst_buffer_new_and_alloc (append_size); - GST_BUFFER_FLAG_SET (filter->append_buffer, GST_BUFFER_FLAG_READONLY); - data = GST_BUFFER_DATA (filter->append_buffer); - for (i = inject_len - 1; i >= 0; --i) { - if (inject[i].offset_orig == filter->duration_orig) { - memcpy (data, inject[i].data, inject[i].size); - data += inject[i].size; - } else { - break; - } - } - } - - if (filter->duration_orig) { - filter->duration = filter->duration_orig; - for (i = 0; i < inject_len; ++i) { - filter->duration += inject[i].size; - } - for (i = 0; i < strip_len; ++i) { - filter->duration -= strip[i].size; - } - } - - filter->need_calculate_offset = FALSE; - - return TRUE; - -} - - -/* * Do parsing step-by-step and reconfigure caps if need * return: * META_PARSING_ERROR @@ -995,11 +847,11 @@ gst_metadata_mux_parse (GstMetadataMux * filter, const guint8 * buf, filter->next_offset = 0; filter->next_size = 0; - ret = metadata_parse (&filter->mux_data, buf, size, + ret = metadata_parse (&filter->common.metadata, buf, size, &filter->next_offset, &filter->next_size); if (ret == META_PARSING_ERROR) { - if (META_DATA_IMG_TYPE (filter->mux_data) == IMG_NONE) { + if (META_DATA_IMG_TYPE (filter->common.metadata) == IMG_NONE) { /* image type not recognized */ GST_ELEMENT_ERROR (filter, STREAM, TYPE_NOT_FOUND, (NULL), ("Only jpeg and png are supported")); @@ -1008,17 +860,18 @@ gst_metadata_mux_parse (GstMetadataMux * filter, const guint8 * buf, } else if (ret == META_PARSING_NEED_MORE_DATA) { filter->need_more_data = TRUE; } else { - filter->state = MT_STATE_MUXED; + filter->common.state = MT_STATE_PARSED; filter->need_more_data = FALSE; filter->need_calculate_offset = TRUE; } - if (filter->img_type != META_DATA_IMG_TYPE (filter->mux_data)) { - filter->img_type = META_DATA_IMG_TYPE (filter->mux_data); + /* reconfigure caps if it is different from type detected by 'metadata_mux' function */ + if (filter->img_type != META_DATA_IMG_TYPE (filter->common.metadata)) { + filter->img_type = META_DATA_IMG_TYPE (filter->common.metadata); if (!gst_metadata_mux_configure_caps (filter)) { GST_ELEMENT_ERROR (filter, STREAM, FORMAT, (NULL), ("Couldn't reconfigure caps for %s", - gst_metadata_mux_get_type_name (filter->img_type))); + gst_metadata_common_get_type_name (filter->img_type))); ret = META_PARSING_ERROR; goto done; } @@ -1051,7 +904,7 @@ gst_metadata_mux_chain (GstPad * pad, GstBuffer * buf) filter = GST_METADATA_MUX (gst_pad_get_parent (pad)); - if (filter->state != MT_STATE_MUXED) { + if (filter->common.state != MT_STATE_PARSED) { guint32 adpt_size = gst_adapter_available (filter->adapter_parsing); if (filter->next_offset) { @@ -1100,7 +953,7 @@ gst_metadata_mux_chain (GstPad * pad, GstBuffer * buf) } } - if (filter->state == MT_STATE_MUXED) { + if (filter->common.state == MT_STATE_PARSED) { if (filter->adapter_holding) { gst_adapter_push (filter->adapter_holding, buf); @@ -1111,18 +964,22 @@ gst_metadata_mux_chain (GstPad * pad, GstBuffer * buf) } if (filter->need_calculate_offset) { - if (!gst_metadata_mux_calculate_offsets (filter)) { + gst_metadata_create_chunks_from_tags (filter); + if (gst_metadata_common_calculate_offsets (&filter->common)) { + filter->need_calculate_offset = FALSE; + } else { ret = GST_FLOW_ERROR; goto done; } } - if (filter->offset_orig + GST_BUFFER_SIZE (buf) == filter->duration_orig) + if (filter->offset_orig + GST_BUFFER_SIZE (buf) == + filter->common.duration_orig) append = TRUE; buf_size = GST_BUFFER_SIZE (buf); - gst_metadata_mux_strip_push_buffer (filter, filter->offset_orig, + gst_metadata_common_strip_push_buffer (&filter->common, filter->offset_orig, &filter->prepend_buffer, &buf); if (buf) { /* may be all buffer has been striped */ @@ -1137,11 +994,11 @@ gst_metadata_mux_chain (GstPad * pad, GstBuffer * buf) ret = GST_FLOW_OK; } - if (append && filter->append_buffer) { - gst_buffer_set_caps (filter->append_buffer, + if (append && filter->common.append_buffer) { + gst_buffer_set_caps (filter->common.append_buffer, GST_PAD_CAPS (filter->srcpad)); - gst_buffer_ref (filter->append_buffer); - ret = gst_pad_push (filter->srcpad, filter->append_buffer); + gst_buffer_ref (filter->common.append_buffer); + ret = gst_pad_push (filter->srcpad, filter->common.append_buffer); if (ret != GST_FLOW_OK) goto done; } @@ -1189,7 +1046,7 @@ gst_metadata_mux_pull_range_mux (GstMetadataMux * filter) ret = TRUE; goto done; } - filter->duration_orig = duration; + filter->common.duration_orig = duration; if (format != GST_FORMAT_BYTES) { /* this should never happen, but try chain anyway */ @@ -1235,7 +1092,6 @@ gst_metadata_mux_pull_range_mux (GstMetadataMux * filter) } while (res == META_PARSING_NEED_MORE_DATA); - done: return ret; @@ -1259,7 +1115,7 @@ gst_metadata_mux_sink_activate (GstPad * pad) } /* try to mux */ - if (filter->state == MT_STATE_NULL) { + if (filter->common.state == MT_STATE_NULL) { ret = gst_metadata_mux_pull_range_mux (filter); } @@ -1278,411 +1134,6 @@ done: } -/* - * offset - offset of buffer in original stream - * size - size of buffer - * seg_offset - offset of segment in original stream - * seg_size - size of segment - * boffset - offset inside buffer where segment starts (-1 for no intersection) - * bsize - size of intersection - * seg_binter - if segment start inside buffer is zero. if segment start before - * buffer and intersect, it is the offset inside segment. - * - * ret: - * -1 - segment before buffer - * 0 - segment intersects - * 1 - segment after buffer - */ - -static int -gst_metadata_mux_get_strip_seg (const gint64 offset, guint32 size, - const gint64 seg_offset, const guint32 seg_size, - gint64 * boffset, guint32 * bsize, guint32 * seg_binter) -{ - int ret = -1; - - *boffset = -1; - *bsize = 0; - *seg_binter = -1; - - /* all segment after buffer */ - if (seg_offset >= offset + size) { - ret = 1; - goto done; - } - - if (seg_offset < offset) { - /* segment start somewhere before buffer */ - - /* all segment before buffer */ - if (seg_offset + seg_size <= offset) { - ret = -1; - goto done; - } - - *seg_binter = offset - seg_offset; - *boffset = 0; - - /* FIXME : optimize to >= size -> = size */ - if (seg_offset + seg_size >= offset + size) { - /* segment cover all buffer */ - *bsize = size; - } else { - /* segment goes from start of buffer to somewhere before end */ - *bsize = seg_size - *seg_binter; - } - - ret = 0; - - } else { - /* segment start somewhere into buffer */ - - *boffset = seg_offset - offset; - *seg_binter = 0; - - if (seg_offset + seg_size <= offset + size) { - /* all segment into buffer */ - *bsize = seg_size; - } else { - *bsize = size - *boffset; - } - - ret = 0; - - } - -done: - - return ret; - -} - -/* - * TRUE -> buffer striped or injeted - * FALSE -> buffer unmodified - */ - -static gboolean -gst_metadata_mux_strip_push_buffer (GstMetadataMux * filter, - gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf) -{ - MetadataChunk *strip = filter->mux_data.strip_chunks.chunk; - MetadataChunk *inject = filter->mux_data.inject_chunks.chunk; - const gsize strip_len = filter->mux_data.strip_chunks.len; - const gsize inject_len = filter->mux_data.inject_chunks.len; - gboolean buffer_reallocated = FALSE; - - guint32 size_buf_in = GST_BUFFER_SIZE (*buf); - - gint64 *boffset_strip = NULL; - guint32 *bsize_strip = NULL; - guint32 *seg_binter_strip = NULL; - - int i, j; - gboolean need_free_strip = FALSE; - - guint32 striped_bytes = 0; - guint32 injected_bytes = 0; - - guint32 prepend_size = prepend && *prepend ? GST_BUFFER_SIZE (*prepend) : 0; - - if (inject_len) { - - for (i = 0; i < inject_len; ++i) { - int res; - - if (inject[i].offset_orig >= offset_orig) { - if (inject[i].offset_orig < offset_orig + size_buf_in) { - injected_bytes += inject[i].size; - } else { - /* segment is after size (segments are sorted) */ - break; - } - } - } - - } - - /* - * strip segments - */ - - if (strip_len == 0) - goto inject; - - if (G_UNLIKELY (strip_len > 16)) { - boffset_strip = g_new (gint64, strip_len); - bsize_strip = g_new (guint32, strip_len); - seg_binter_strip = g_new (guint32, strip_len); - need_free_strip = TRUE; - } else { - boffset_strip = g_alloca (sizeof (boffset_strip[0]) * strip_len); - bsize_strip = g_alloca (sizeof (bsize_strip[0]) * strip_len); - seg_binter_strip = g_alloca (sizeof (seg_binter_strip[0]) * strip_len); - } - - memset (bsize_strip, 0x00, sizeof (bsize_strip[0]) * strip_len); - - for (i = 0; i < strip_len; ++i) { - int res; - - res = gst_metadata_mux_get_strip_seg (offset_orig, size_buf_in, - strip[i].offset_orig, strip[i].size, &boffset_strip[i], &bsize_strip[i], - &seg_binter_strip[i]); - - /* segment is after size (segments are sorted) */ - striped_bytes += bsize_strip[i]; - if (res > 0) { - break; - } - - } - - if (striped_bytes) { - - guint8 *data; - - if (!buffer_reallocated) { - buffer_reallocated = TRUE; - if (injected_bytes + prepend_size > striped_bytes) { - GstBuffer *new_buf = - gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + injected_bytes + - prepend_size - striped_bytes); - - memcpy (GST_BUFFER_DATA (new_buf), GST_BUFFER_DATA (*buf), - GST_BUFFER_SIZE (*buf)); - - gst_buffer_unref (*buf); - *buf = new_buf; - - } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY)) { - GstBuffer *new_buf = gst_buffer_copy (*buf); - - gst_buffer_unref (*buf); - *buf = new_buf; - GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY); - GST_BUFFER_SIZE (*buf) += injected_bytes + prepend_size - striped_bytes; - } - } - - data = GST_BUFFER_DATA (*buf); - - striped_bytes = 0; - for (i = 0; i < strip_len; ++i) { - /* intersect */ - if (bsize_strip[i]) { - memmove (data + boffset_strip[i] - striped_bytes, - data + boffset_strip[i] + bsize_strip[i] - striped_bytes, - size_buf_in - boffset_strip[i] - bsize_strip[i]); - striped_bytes += bsize_strip[i]; - } - } - size_buf_in -= striped_bytes; - - } - -inject: - - /* - * inject segments - */ - - if (inject_len) { - - guint8 *data; - guint32 striped_so_far; - - if (!buffer_reallocated) { - buffer_reallocated = TRUE; - if (injected_bytes + prepend_size > striped_bytes) { - GstBuffer *new_buf = - gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + injected_bytes + - prepend_size - striped_bytes); - - memcpy (GST_BUFFER_DATA (new_buf), GST_BUFFER_DATA (*buf), - GST_BUFFER_SIZE (*buf)); - - gst_buffer_unref (*buf); - *buf = new_buf; - - } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY)) { - GstBuffer *new_buf = gst_buffer_copy (*buf); - - gst_buffer_unref (*buf); - *buf = new_buf; - GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY); - GST_BUFFER_SIZE (*buf) += injected_bytes + prepend_size - striped_bytes; - } - } - - data = GST_BUFFER_DATA (*buf); - - injected_bytes = 0; - striped_so_far = 0; - j = 0; - for (i = 0; i < inject_len; ++i) { - int res; - - while (j < strip_len) { - if (strip[j].offset_orig < inject[i].offset_orig) - striped_so_far += bsize_strip[j++]; - else - break; - } - - if (inject[i].offset_orig >= offset_orig) { - if (inject[i].offset_orig < - offset_orig + size_buf_in + striped_bytes - injected_bytes) { - /* insert */ - guint32 buf_off = - inject[i].offset_orig - offset_orig - striped_so_far + - injected_bytes; - memmove (data + buf_off + inject[i].size, data + buf_off, - size_buf_in - buf_off); - memcpy (data + buf_off, inject[i].data, inject[i].size); - injected_bytes += inject[i].size; - size_buf_in += inject[i].size; - } else { - /* segment is after size (segments are sorted) */ - break; - } - } - } - - } - - -done: - - if (prepend_size) { - if (injected_bytes == 0 && striped_bytes == 0) { - GstBuffer *new_buf = - gst_buffer_new_and_alloc (size_buf_in + prepend_size); - - memcpy (GST_BUFFER_DATA (new_buf) + prepend_size, GST_BUFFER_DATA (*buf), - size_buf_in); - - gst_buffer_unref (*buf); - *buf = new_buf; - } else { - memmove (GST_BUFFER_DATA (*buf) + prepend_size, GST_BUFFER_DATA (*buf), - size_buf_in); - } - memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (*prepend), prepend_size); - gst_buffer_unref (*prepend); - *prepend = NULL; - } - - GST_BUFFER_SIZE (*buf) = size_buf_in + prepend_size; - - if (need_free_strip) { - g_free (boffset_strip); - g_free (bsize_strip); - g_free (seg_binter_strip); - } - - return injected_bytes || striped_bytes; - -} - -/* - * pos - position in stream striped - * orig_pos - position in original stream - * return TRUE - position in original buffer - * FALSE - position in inserted chunk - */ -static gboolean -gst_metadata_mux_translate_pos_to_orig (GstMetadataMux * filter, gint64 pos, - gint64 * orig_pos, GstBuffer ** buf) -{ - int i; - MetadataChunk *strip = filter->mux_data.strip_chunks.chunk; - MetadataChunk *inject = filter->mux_data.inject_chunks.chunk; - const gsize strip_len = filter->mux_data.strip_chunks.len; - const gsize inject_len = filter->mux_data.inject_chunks.len; - gboolean ret = TRUE; - guint64 new_buf_size = 0; - guint64 injected_before = 0; - - if (G_UNLIKELY (pos == -1)) { - *orig_pos = -1; - return TRUE; - } else if (G_UNLIKELY (pos >= filter->duration)) { - /* this should never happen */ - *orig_pos = filter->duration_orig; - return TRUE; - } - - /* calculate for injected */ - - /* just calculate size */ - *orig_pos = pos; /* save pos */ - for (i = 0; i < inject_len; ++i) { - /* check if pos in inside chunk */ - if (inject[i].offset <= pos) { - if (pos < inject[i].offset + inject[i].size) { - /* orig pos points after insert chunk */ - new_buf_size += inject[i].size; - /* put pos after current chunk */ - pos = inject[i].offset + inject[i].size; - ret = FALSE; - } else { - /* in case pos is not inside a injected chunk */ - injected_before += inject[i].size; - } - } else { - break; - } - } - - /* alloc buffer and calcute original pos */ - if (buf && ret == FALSE) { - guint8 *data; - - if (*buf) - gst_buffer_unref (*buf); - *buf = gst_buffer_new_and_alloc (new_buf_size); - data = GST_BUFFER_DATA (*buf); - pos = *orig_pos; /* recover saved pos */ - for (i = 0; i < inject_len; ++i) { - if (inject[i].offset > pos) { - break; - } - if (inject[i].offset <= pos && pos < inject[i].offset + inject[i].size) { - memcpy (data, inject[i].data, inject[i].size); - data += inject[i].size; - pos = inject[i].offset + inject[i].size; - /* out position after insert chunk orig */ - *orig_pos = inject[i].offset_orig + inject[i].size; - } - } - } - - if (ret == FALSE) { - /* if it inside a injected is already done */ - goto done; - } - - /* calculate for striped */ - - *orig_pos = pos - injected_before; - for (i = 0; i < strip_len; ++i) { - if (strip[i].offset_orig > pos) { - break; - } - *orig_pos += strip[i].size; - } - -done: - - if (G_UNLIKELY (*orig_pos >= filter->duration_orig)) { - *orig_pos = filter->duration_orig - 1; - } - - return ret; - -} - static gboolean gst_metadata_mux_checkgetrange (GstPad * srcpad) { @@ -1707,26 +1158,30 @@ gst_metadata_mux_get_range (GstPad * pad, filter = GST_METADATA_MUX (GST_PAD_PARENT (pad)); if (filter->need_calculate_offset) { - if (!gst_metadata_mux_calculate_offsets (filter)) { + gst_metadata_create_chunks_from_tags (filter); + if (gst_metadata_common_calculate_offsets (&filter->common)) { + filter->need_calculate_offset = FALSE; + } else { ret = GST_FLOW_ERROR; goto done; } } - if (offset + size > filter->duration) { - size = filter->duration - offset; + if (offset + size > filter->common.duration) { + size = filter->common.duration - offset; } size_orig = size; - gst_metadata_mux_translate_pos_to_orig (filter, offset, &offset_orig, - &prepend); + gst_metadata_common_translate_pos_to_orig (&filter->common, offset, + &offset_orig, &prepend); if (size > 1) { gint64 pos; pos = offset + size - 1; - gst_metadata_mux_translate_pos_to_orig (filter, pos, &pos, NULL); + gst_metadata_common_translate_pos_to_orig (&filter->common, pos, &pos, + NULL); size_orig = pos + 1 - offset_orig; } @@ -1735,7 +1190,8 @@ gst_metadata_mux_get_range (GstPad * pad, ret = gst_pad_pull_range (filter->sinkpad, offset_orig, size_orig, buf); if (ret == GST_FLOW_OK && *buf) { - gst_metadata_mux_strip_push_buffer (filter, offset_orig, &prepend, buf); + gst_metadata_common_strip_push_buffer (&filter->common, offset_orig, + &prepend, buf); if (GST_BUFFER_SIZE (*buf) < size) { /* need append */ @@ -1751,7 +1207,7 @@ done: if (need_append) { /* FIXME: together with SEEK and - * gst_metadata_parse_translate_pos_to_orig + * gst_metadata_common_translate_pos_to_orig * this way if chunk is added in the end we are in trolble * ...still not implemented 'cause it will not be the * case for the time being @@ -1772,7 +1228,7 @@ gst_metadata_mux_src_activate_pull (GstPad * pad, gboolean active) ret = gst_pad_activate_pull (filter->sinkpad, active); - if (ret && filter->state == MT_STATE_NULL) { + if (ret && filter->common.state == MT_STATE_NULL) { ret = gst_metadata_mux_pull_range_mux (filter); } @@ -1792,7 +1248,7 @@ gst_metadata_mux_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_NULL_TO_READY: gst_metadata_mux_init_members (filter); filter->adapter_parsing = gst_adapter_new (); - metadata_init (&filter->mux_data, FALSE, filter->options); + gst_metadata_common_init (&filter->common, FALSE, filter->options); break; default: break; @@ -1812,11 +1268,10 @@ gst_metadata_mux_change_state (GstElement * element, GstStateChange transition) if (filter->adapter_holding) { gst_adapter_clear (filter->adapter_holding); } - if (filter->state != MT_STATE_MUXED) { + if (filter->common.state != MT_STATE_PARSED) { /* cleanup parser */ - /* FIXME: could be improved a bit to avoid mem allocation */ - metadata_dispose (&filter->mux_data); - metadata_init (&filter->mux_data, FALSE, filter->options); + gst_metadata_common_dispose (&filter->common); + gst_metadata_common_init (&filter->common, FALSE, filter->options); } break; case GST_STATE_CHANGE_READY_TO_NULL: |