diff options
Diffstat (limited to 'ext/metadata/gstbasemetadata.c')
-rw-r--r-- | ext/metadata/gstbasemetadata.c | 747 |
1 files changed, 672 insertions, 75 deletions
diff --git a/ext/metadata/gstbasemetadata.c b/ext/metadata/gstbasemetadata.c index 962edd3b..858145fe 100644 --- a/ext/metadata/gstbasemetadata.c +++ b/ext/metadata/gstbasemetadata.c @@ -167,6 +167,525 @@ gst_base_metadata_get_type (void) return base_metadata_type; } +/* static helper function */ + +/* + * 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_base_metadata_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; + +} + +/* + * extern functions declaration + */ + +/* + +/* + * TRUE -> buffer striped or injeted + * FALSE -> buffer unmodified + */ + +gboolean +gst_base_metadata_strip_push_buffer (GstBaseMetadata * base, + gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf) +{ + MetadataChunk *strip = base->metadata->strip_chunks.chunk; + MetadataChunk *inject = base->metadata->inject_chunks.chunk; + const gsize strip_len = base->metadata->strip_chunks.len; + const gsize inject_len = base->metadata->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_base_metadata_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 + */ +gboolean +gst_base_metadata_translate_pos_to_orig (GstBaseMetadata * base, + gint64 pos, gint64 * orig_pos, GstBuffer ** buf) +{ + MetadataChunk *strip = base->metadata->strip_chunks.chunk; + MetadataChunk *inject = base->metadata->inject_chunks.chunk; + const gsize strip_len = base->metadata->strip_chunks.len; + const gsize inject_len = base->metadata->inject_chunks.len; + const gint64 duration_orig = base->duration_orig; + const gint64 duration = base->duration; + + int i; + 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 >= duration)) { + /* this should never happen */ + *orig_pos = 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 >= duration_orig)) { + *orig_pos = duration_orig - 1; + } + + return ret; + +} + +/* + * return: + * -1 -> error + * 0 -> succeded + * 1 -> need more data + */ + +gboolean +gst_base_metadata_calculate_offsets (GstBaseMetadata * base) +{ + int i, j; + guint32 append_size; + guint32 bytes_striped, bytes_inject; + MetadataChunk *strip = base->metadata->strip_chunks.chunk; + MetadataChunk *inject = base->metadata->inject_chunks.chunk; + gsize strip_len; + gsize inject_len; + + if (base->state != MT_STATE_PARSED) + return FALSE; + + metadata_lazy_update (base->metadata); + + strip_len = base->metadata->strip_chunks.len; + inject_len = base->metadata->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 == base->duration_orig) + append_size += inject[i].size; + else + break; + } + if (append_size) { + guint8 *data; + + base->append_buffer = gst_buffer_new_and_alloc (append_size); + GST_BUFFER_FLAG_SET (base->append_buffer, GST_BUFFER_FLAG_READONLY); + data = GST_BUFFER_DATA (base->append_buffer); + for (i = inject_len - 1; i >= 0; --i) { + if (inject[i].offset_orig == base->duration_orig) { + memcpy (data, inject[i].data, inject[i].size); + data += inject[i].size; + } else { + break; + } + } + } + + if (base->duration_orig) { + base->duration = base->duration_orig; + for (i = 0; i < inject_len; ++i) { + base->duration += inject[i].size; + } + for (i = 0; i < strip_len; ++i) { + base->duration -= strip[i].size; + } + } + + return TRUE; + +} + +const gchar * +gst_base_metadata_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; +} + + +/* gstreamer functions */ + static void gst_base_metadata_base_init (gpointer gclass) @@ -260,8 +779,6 @@ gst_base_metadata_init (GstBaseMetadata * filter, GstBaseMetadataClass * gclass) metadataparse_xmp_init (); /* init members */ - filter->options = META_OPT_EXIF | META_OPT_IPTC | META_OPT_XMP; - gst_base_metadata_init_members (filter); } @@ -329,7 +846,7 @@ gst_base_metadata_processing (GstBaseMetadata * filter) if (filter->need_processing) { bclass->processing (filter); - if (gst_metadata_common_calculate_offsets (&filter->common)) { + if (gst_base_metadata_calculate_offsets (filter)) { filter->need_processing = FALSE; } else { ret = FALSE; @@ -404,10 +921,10 @@ gst_base_metadata_src_event (GstPad * pad, GstEvent * event) case GST_FORMAT_BYTES: break; case GST_FORMAT_PERCENT: - if (filter->common.duration < 0) + if (filter->duration < 0) goto done; - start = start * filter->common.duration / 100; - stop = stop * filter->common.duration / 100; + start = start * filter->duration / 100; + stop = stop * filter->duration / 100; break; default: goto done; @@ -417,9 +934,9 @@ gst_base_metadata_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->common.duration < 0) + if (filter->duration < 0) goto done; - start = filter->common.duration + start; + start = filter->duration + start; } start_type == GST_SEEK_TYPE_SET; @@ -430,21 +947,20 @@ gst_base_metadata_src_event (GstPad * pad, GstEvent * event) /* FIXME: related to append */ filter->offset = start; - gst_metadata_common_translate_pos_to_orig (&filter->common, start, &start, + gst_base_metadata_translate_pos_to_orig (filter, 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->common.duration < 0) + if (filter->duration < 0) goto done; - stop = filter->common.duration + stop; + stop = filter->duration + stop; } stop_type == GST_SEEK_TYPE_SET; - gst_metadata_common_translate_pos_to_orig (&filter->common, stop, &stop, - NULL); + gst_base_metadata_translate_pos_to_orig (filter, stop, &stop, NULL); gst_event_unref (event); event = gst_event_new_seek (rate, format, flags, @@ -494,7 +1010,20 @@ gst_base_metadata_finalize (GObject * object) static void gst_base_metadata_dispose_members (GstBaseMetadata * filter) { - gst_metadata_common_dispose (&filter->common); + + /* buffers used to build output buffer */ + + if (filter->prepend_buffer) { + gst_buffer_unref (filter->prepend_buffer); + filter->prepend_buffer = NULL; + } + + if (filter->append_buffer) { + gst_buffer_unref (filter->append_buffer); + filter->append_buffer = NULL; + } + + /* adapter used during parsing process */ if (filter->adapter_parsing) { gst_object_unref (filter->adapter_parsing); @@ -506,29 +1035,82 @@ gst_base_metadata_dispose_members (GstBaseMetadata * filter) filter->adapter_holding = NULL; } - if (filter->prepend_buffer) { - gst_buffer_unref (filter->prepend_buffer); - filter->prepend_buffer = NULL; - } + metadata_dispose (&filter->metadata); + } static void gst_base_metadata_init_members (GstBaseMetadata * filter) { + + filter->metadata = NULL; + + filter->img_type = IMG_NONE; + + filter->duration_orig = 0; + filter->duration = 0; + + filter->state = MT_STATE_NULL; + + filter->options = META_OPT_EXIF | META_OPT_IPTC | META_OPT_XMP; + filter->need_processing = FALSE; filter->adapter_parsing = NULL; filter->adapter_holding = NULL; filter->next_offset = 0; filter->next_size = 0; - filter->img_type = IMG_NONE; + filter->need_more_data = FALSE; filter->offset_orig = 0; filter->offset = 0; - filter->need_more_data = FALSE; + filter->append_buffer = NULL; filter->prepend_buffer = NULL; - memset (&filter->common, 0x00, sizeof (filter->common)); +} + +static void +gst_base_metadata_reset_streaming (GstBaseMetadata * filter) +{ + filter->offset_orig = 0; + filter->offset = 0; + if (filter->adapter_holding) + gst_adapter_clear (filter->adapter_holding); +} + +static void +gst_base_metadata_reset_parsing (GstBaseMetadata * filter) +{ + + + if (filter->prepend_buffer) { + gst_buffer_unref (filter->prepend_buffer); + filter->prepend_buffer = NULL; + } + + if (filter->append_buffer) { + gst_buffer_unref (filter->append_buffer); + filter->append_buffer = NULL; + } + + if (filter->adapter_parsing) + gst_adapter_clear (filter->adapter_parsing); + + if (filter->adapter_holding) + gst_adapter_clear (filter->adapter_holding); + + filter->img_type = IMG_NONE; + filter->duration_orig = 0; + filter->duration = 0; + filter->state = MT_STATE_NULL; + filter->need_processing = FALSE; + filter->next_offset = 0; + filter->next_size = 0; + filter->need_more_data = FALSE; + filter->offset_orig = 0; + filter->offset = 0; + + metadata_dispose (&filter->metadata); } @@ -617,9 +1199,8 @@ gst_base_metadata_src_query (GstPad * pad, GstQuery * query) gst_query_parse_duration (query, &format, NULL); if (format == GST_FORMAT_BYTES) { - if (filter->common.duration >= 0) { - gst_query_set_duration (query, GST_FORMAT_BYTES, - filter->common.duration); + if (filter->duration >= 0) { + gst_query_set_duration (query, GST_FORMAT_BYTES, filter->duration); ret = TRUE; } } @@ -658,11 +1239,11 @@ gst_base_metadata_parse (GstBaseMetadata * filter, const guint8 * buf, filter->next_offset = 0; filter->next_size = 0; - ret = metadata_parse (&filter->common.metadata, buf, size, + ret = metadata_parse (filter->metadata, buf, size, &filter->next_offset, &filter->next_size); if (ret == META_PARSING_ERROR) { - if (META_DATA_IMG_TYPE (filter->common.metadata) == IMG_NONE) { + if (META_DATA_IMG_TYPE (filter->metadata) == IMG_NONE) { /* image type not recognized */ GST_ELEMENT_ERROR (filter, STREAM, TYPE_NOT_FOUND, (NULL), ("Only jpeg and png are supported")); @@ -671,18 +1252,18 @@ gst_base_metadata_parse (GstBaseMetadata * filter, const guint8 * buf, } else if (ret == META_PARSING_NEED_MORE_DATA) { filter->need_more_data = TRUE; } else { - filter->common.state = MT_STATE_PARSED; + filter->state = MT_STATE_PARSED; filter->need_more_data = FALSE; filter->need_processing = TRUE; } /* reconfigure caps if it is different from type detected by 'base_metadata' function */ - if (filter->img_type != META_DATA_IMG_TYPE (filter->common.metadata)) { - filter->img_type = META_DATA_IMG_TYPE (filter->common.metadata); + if (filter->img_type != META_DATA_IMG_TYPE (filter->metadata)) { + filter->img_type = META_DATA_IMG_TYPE (filter->metadata); if (!gst_base_metadata_configure_caps (filter)) { GST_ELEMENT_ERROR (filter, STREAM, FORMAT, (NULL), ("Couldn't reconfigure caps for %s", - gst_metadata_common_get_type_name (filter->img_type))); + gst_base_metadata_get_type_name (filter->img_type))); ret = META_PARSING_ERROR; goto done; } @@ -715,8 +1296,13 @@ gst_base_metadata_chain (GstPad * pad, GstBuffer * buf) filter = GST_BASE_METADATA (gst_pad_get_parent (pad)); - if (filter->common.state != MT_STATE_PARSED) { - guint32 adpt_size = gst_adapter_available (filter->adapter_parsing); + if (filter->state != MT_STATE_PARSED) { + guint32 adpt_size; + + if (G_UNLIKELY (filter->adapter_parsing == NULL)) + filter->adapter_parsing = gst_adapter_new (); + + adpt_size = gst_adapter_available (filter->adapter_parsing); if (filter->next_offset) { if (filter->next_offset >= adpt_size) { @@ -764,7 +1350,7 @@ gst_base_metadata_chain (GstPad * pad, GstBuffer * buf) } } - if (filter->common.state == MT_STATE_PARSED) { + if (filter->state == MT_STATE_PARSED) { if (!gst_base_metadata_processing (filter)) { ret = GST_FLOW_ERROR; @@ -779,13 +1365,12 @@ gst_base_metadata_chain (GstPad * pad, GstBuffer * buf) filter->adapter_holding = NULL; } - if (filter->offset_orig + GST_BUFFER_SIZE (buf) == - filter->common.duration_orig) + if (filter->offset_orig + GST_BUFFER_SIZE (buf) == filter->duration_orig) append = TRUE; buf_size = GST_BUFFER_SIZE (buf); - gst_metadata_common_strip_push_buffer (&filter->common, filter->offset_orig, + gst_base_metadata_strip_push_buffer (filter, filter->offset_orig, &filter->prepend_buffer, &buf); if (buf) { /* may be all buffer has been striped */ @@ -800,11 +1385,11 @@ gst_base_metadata_chain (GstPad * pad, GstBuffer * buf) ret = GST_FLOW_OK; } - if (append && filter->common.append_buffer) { - gst_buffer_set_caps (filter->common.append_buffer, + if (append && filter->append_buffer) { + gst_buffer_set_caps (filter->append_buffer, GST_PAD_CAPS (filter->srcpad)); - gst_buffer_ref (filter->common.append_buffer); - ret = gst_pad_push (filter->srcpad, filter->common.append_buffer); + gst_buffer_ref (filter->append_buffer); + ret = gst_pad_push (filter->srcpad, filter->append_buffer); if (ret != GST_FLOW_OK) goto done; } @@ -852,7 +1437,7 @@ gst_base_metadata_pull_range_base (GstBaseMetadata * filter) ret = TRUE; goto done; } - filter->common.duration_orig = duration; + filter->duration_orig = duration; if (format != GST_FORMAT_BYTES) { /* this should never happen, but try chain anyway */ @@ -921,7 +1506,7 @@ gst_base_metadata_sink_activate (GstPad * pad) } /* try to base */ - if (filter->common.state == MT_STATE_NULL) { + if (filter->state == MT_STATE_NULL) { ret = gst_base_metadata_pull_range_base (filter); } @@ -968,21 +1553,20 @@ gst_base_metadata_get_range (GstPad * pad, goto done; } - if (offset + size > filter->common.duration) { - size = filter->common.duration - offset; + if (offset + size > filter->duration) { + size = filter->duration - offset; } size_orig = size; - gst_metadata_common_translate_pos_to_orig (&filter->common, offset, + gst_base_metadata_translate_pos_to_orig (filter, offset, &offset_orig, &prepend); if (size > 1) { gint64 pos; pos = offset + size - 1; - gst_metadata_common_translate_pos_to_orig (&filter->common, pos, &pos, - NULL); + gst_base_metadata_translate_pos_to_orig (filter, pos, &pos, NULL); size_orig = pos + 1 - offset_orig; } @@ -991,8 +1575,7 @@ gst_base_metadata_get_range (GstPad * pad, ret = gst_pad_pull_range (filter->sinkpad, offset_orig, size_orig, buf); if (ret == GST_FLOW_OK && *buf) { - gst_metadata_common_strip_push_buffer (&filter->common, offset_orig, - &prepend, buf); + gst_base_metadata_strip_push_buffer (filter, offset_orig, &prepend, buf); if (GST_BUFFER_SIZE (*buf) < size) { /* need append */ @@ -1008,7 +1591,7 @@ done: if (need_append) { /* FIXME: together with SEEK and - * gst_metadata_common_translate_pos_to_orig + * gst_base_metadata_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 @@ -1029,7 +1612,7 @@ gst_base_metadata_src_activate_pull (GstPad * pad, gboolean active) ret = gst_pad_activate_pull (filter->sinkpad, active); - if (ret && filter->common.state == MT_STATE_NULL) { + if (ret && filter->state == MT_STATE_NULL) { ret = gst_base_metadata_pull_range_base (filter); } @@ -1047,9 +1630,12 @@ gst_base_metadata_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - gst_base_metadata_init_members (filter); - filter->adapter_parsing = gst_adapter_new (); - gst_metadata_common_init (&filter->common, filter->options); + gst_base_metadata_reset_parsing (filter); + metadata_init (&filter->metadata, filter->options); + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + if (filter->metadata == NULL) + metadata_init (&filter->metadata, filter->options); break; default: break; @@ -1061,22 +1647,9 @@ gst_base_metadata_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: - filter->offset = 0; - filter->offset_orig = 0; - if (filter->adapter_parsing) { - gst_adapter_clear (filter->adapter_parsing); - } - if (filter->adapter_holding) { - gst_adapter_clear (filter->adapter_holding); - } - if (filter->common.state != MT_STATE_PARSED) { - /* cleanup parser */ - gst_metadata_common_dispose (&filter->common); - gst_metadata_common_init (&filter->common, filter->options); - } - break; - case GST_STATE_CHANGE_READY_TO_NULL: - gst_base_metadata_dispose_members (filter); + gst_base_metadata_reset_streaming (filter); + if (filter->state != MT_STATE_PARSED) + gst_base_metadata_reset_parsing (filter); break; default: break; @@ -1108,16 +1681,40 @@ gst_base_metadata_get_option_flag (const GstBaseMetadata * metadata) } void -gst_base_metadata_update_segment_with_new_buffer (GstBaseMetadata * metadata, +gst_base_metadata_update_segment_with_new_buffer (GstBaseMetadata * base, guint8 ** buf, guint32 * size, MetadataChunkType type) { - gst_metadata_common_update_segment_with_new_buffer (&metadata->common, buf, - size, type); + int i; + MetadataChunk *inject = base->metadata->inject_chunks.chunk; + const gsize inject_len = base->metadata->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; + } void gst_base_metadata_chunk_array_remove_zero_size (GstBaseMetadata * metadata) { - metadata_chunk_array_remove_zero_size (&metadata->common.metadata. - inject_chunks); + metadata_chunk_array_remove_zero_size (&metadata->metadata->inject_chunks); } |