diff options
Diffstat (limited to 'gst/matroska/matroska-read-common.c')
-rw-r--r-- | gst/matroska/matroska-read-common.c | 147 |
1 files changed, 92 insertions, 55 deletions
diff --git a/gst/matroska/matroska-read-common.c b/gst/matroska/matroska-read-common.c index 5fd178fe3..0714c7054 100644 --- a/gst/matroska/matroska-read-common.c +++ b/gst/matroska/matroska-read-common.c @@ -58,7 +58,7 @@ GST_DEBUG_CATEGORY (matroskareadcommon_debug); static gboolean gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc, - guint8 ** data_out, guint * size_out, + gpointer * data_out, gsize * size_out, GstMatroskaTrackCompressionAlgorithm algo) { guint8 *new_data = NULL; @@ -237,8 +237,8 @@ gst_matroska_decode_content_encodings (GArray * encodings) for (i = 0; i < encodings->len; i++) { GstMatroskaTrackEncoding *enc = &g_array_index (encodings, GstMatroskaTrackEncoding, i); - guint8 *data = NULL; - guint size; + gpointer data = NULL; + gsize size; if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING) == 0) @@ -270,11 +270,11 @@ gst_matroska_decode_content_encodings (GArray * encodings) } gboolean -gst_matroska_decode_data (GArray * encodings, guint8 ** data_out, - guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free) +gst_matroska_decode_data (GArray * encodings, gpointer * data_out, + gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free) { - guint8 *data; - guint size; + gpointer data; + gsize size; gboolean ret = TRUE; gint i; @@ -288,8 +288,8 @@ gst_matroska_decode_data (GArray * encodings, guint8 ** data_out, for (i = 0; i < encodings->len; i++) { GstMatroskaTrackEncoding *enc = &g_array_index (encodings, GstMatroskaTrackEncoding, i); - guint8 *new_data = NULL; - guint new_size = 0; + gpointer new_data = NULL; + gsize new_size = 0; if ((enc->scope & scope) == 0) continue; @@ -430,21 +430,31 @@ gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common, gst_tag_list_insert (common->global_tags, taglist, GST_TAG_MERGE_APPEND); gst_tag_list_free (taglist); } else { + GstEvent *tag_event = gst_event_new_tag (taglist); + gint i; + /* hm, already sent, no need to cache and wait anymore */ GST_DEBUG_OBJECT (common, "Sending late global tags %" GST_PTR_FORMAT, taglist); - gst_element_found_tags (el, taglist); + + for (i = 0; i < common->src->len; i++) { + GstMatroskaTrackContext *stream; + + stream = g_ptr_array_index (common->src, i); + gst_pad_push_event (stream->pad, gst_event_ref (tag_event)); + } + + gst_event_unref (tag_event); } } gint64 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common) { - GstFormat fmt = GST_FORMAT_BYTES; gint64 end = -1; - if (!gst_pad_query_peer_duration (common->sinkpad, &fmt, &end) || - fmt != GST_FORMAT_BYTES || end < 0) + if (!gst_pad_peer_query_duration (common->sinkpad, GST_FORMAT_BYTES, + &end) || end < 0) GST_DEBUG_OBJECT (common, "no upstream length"); return end; @@ -569,7 +579,9 @@ gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common, if (filename && mimetype && data && datalen > 0) { GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE; GstBuffer *tagbuffer = NULL; - GstCaps *caps; + GstSample *tagsample = NULL; + GstStructure *info = NULL; + GstCaps *caps = NULL; gchar *filename_lc = g_utf8_strdown (filename, -1); GST_DEBUG_OBJECT (common, "Creating tag for attachment with " @@ -595,44 +607,49 @@ gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common, /* First try to create an image tag buffer from this */ if (image_type != GST_TAG_IMAGE_TYPE_NONE) { - tagbuffer = - gst_tag_image_data_to_image_buffer (data, datalen, image_type); + tagsample = + gst_tag_image_data_to_image_sample (data, datalen, image_type); - if (!tagbuffer) + if (!tagsample) image_type = GST_TAG_IMAGE_TYPE_NONE; + else { + data = NULL; + tagbuffer = gst_buffer_ref (gst_sample_get_buffer (tagsample)); + caps = gst_caps_ref (gst_sample_get_caps (tagsample)); + info = gst_structure_copy (gst_sample_get_info (tagsample)); + gst_sample_unref (tagsample); + } } /* if this failed create an attachment buffer */ if (!tagbuffer) { - tagbuffer = gst_buffer_new_and_alloc (datalen); - - memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen); - GST_BUFFER_SIZE (tagbuffer) = datalen; + tagbuffer = gst_buffer_new_wrapped (g_memdup (data, datalen), datalen); caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL); if (caps == NULL) - caps = gst_caps_new_simple (mimetype, NULL); - gst_buffer_set_caps (tagbuffer, caps); - gst_caps_unref (caps); + caps = gst_caps_new_empty_simple (mimetype); } - /* Set filename and description on the caps */ - caps = GST_BUFFER_CAPS (tagbuffer); - gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL); + /* Set filename and description in the info */ + if (info == NULL) + info = gst_structure_new_empty ("GstTagImageInfo"); + + gst_structure_set (info, "filename", G_TYPE_STRING, filename, NULL); if (description) - gst_caps_set_simple (caps, "description", G_TYPE_STRING, description, - NULL); + gst_structure_set (info, "description", G_TYPE_STRING, description, NULL); + + tagsample = gst_sample_new (tagbuffer, caps, NULL, info); GST_DEBUG_OBJECT (common, - "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps); + "Created attachment sample: %" GST_PTR_FORMAT, tagsample); /* and append to the tag list */ if (image_type != GST_TAG_IMAGE_TYPE_NONE) - gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer, + gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagsample, NULL); else gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT, - tagbuffer, NULL); + tagsample, NULL); } g_free (filename); @@ -658,7 +675,7 @@ gst_matroska_read_common_parse_attachments (GstMatroskaReadCommon * common, return ret; } - taglist = gst_tag_list_new (); + taglist = gst_tag_list_new_empty (); while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) { if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) @@ -1280,9 +1297,7 @@ gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common, break; GST_DEBUG_OBJECT (common, "Title: %s", GST_STR_NULL (text)); - taglist = gst_tag_list_new (); - gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text, - NULL); + taglist = gst_tag_list_new (GST_TAG_TITLE, text, NULL); gst_matroska_read_common_found_global_tag (common, el, taglist); g_free (text); break; @@ -1313,7 +1328,7 @@ gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common, dur_u = gst_gdouble_to_guint64 (dur_f * gst_guint64_to_gdouble (common->time_scale)); if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64) - gst_segment_set_duration (&common->segment, GST_FORMAT_TIME, dur_u); + common->segment.duration = dur_u; } DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret); @@ -1518,7 +1533,7 @@ gst_matroska_read_common_parse_metadata (GstMatroskaReadCommon * common, return ret; } - taglist = gst_tag_list_new (); + taglist = gst_tag_list_new_empty (); while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) { if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) @@ -1551,7 +1566,8 @@ static GstFlowReturn gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint peek, const guint8 ** data) { - *data = gst_adapter_peek (common->adapter, peek); + /* Caller needs to gst_adapter_unmap. */ + *data = gst_adapter_map (common->adapter, peek); if (*data == NULL) return GST_FLOW_UNEXPECTED; @@ -1571,19 +1587,26 @@ gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64 * We do it mainly to avoid pulling buffers of 1 byte all the time */ if (common->cached_buffer) { guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer); - guint cache_size = GST_BUFFER_SIZE (common->cached_buffer); + gsize cache_size = gst_buffer_get_size (common->cached_buffer); if (cache_offset <= common->offset && (common->offset + size) <= (cache_offset + cache_size)) { if (p_buf) - *p_buf = gst_buffer_create_sub (common->cached_buffer, - common->offset - cache_offset, size); - if (bytes) - *bytes = GST_BUFFER_DATA (common->cached_buffer) + common->offset - - cache_offset; + *p_buf = gst_buffer_copy_region (common->cached_buffer, + GST_BUFFER_COPY_ALL, common->offset - cache_offset, size); + if (bytes) { + if (!common->cached_data) + common->cached_data = gst_buffer_map (common->cached_buffer, + NULL, NULL, GST_MAP_READ); + *bytes = common->cached_data + common->offset - cache_offset; + } return GST_FLOW_OK; } /* not enough data in the cache, free cache and get a new one */ + if (common->cached_data) { + gst_buffer_unmap (common->cached_buffer, common->cached_data, -1); + common->cached_data = NULL; + } gst_buffer_unref (common->cached_buffer); common->cached_buffer = NULL; } @@ -1596,11 +1619,15 @@ gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64 return ret; } - if (GST_BUFFER_SIZE (common->cached_buffer) >= size) { + if (gst_buffer_get_size (common->cached_buffer) >= size) { if (p_buf) - *p_buf = gst_buffer_create_sub (common->cached_buffer, 0, size); - if (bytes) - *bytes = GST_BUFFER_DATA (common->cached_buffer); + *p_buf = gst_buffer_copy_region (common->cached_buffer, + GST_BUFFER_COPY_ALL, 0, size); + if (bytes) { + common->cached_data = gst_buffer_map (common->cached_buffer, + NULL, NULL, GST_MAP_READ); + *bytes = common->cached_data; + } return GST_FLOW_OK; } @@ -1621,10 +1648,10 @@ gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64 return ret; } - if (GST_BUFFER_SIZE (common->cached_buffer) < size) { + if (gst_buffer_get_size (common->cached_buffer) < size) { GST_WARNING_OBJECT (common, "Dropping short buffer at offset %" G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", common->offset, - size, GST_BUFFER_SIZE (common->cached_buffer)); + size, gst_buffer_get_size (common->cached_buffer)); gst_buffer_unref (common->cached_buffer); common->cached_buffer = NULL; @@ -1636,9 +1663,13 @@ gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64 } if (p_buf) - *p_buf = gst_buffer_create_sub (common->cached_buffer, 0, size); - if (bytes) - *bytes = GST_BUFFER_DATA (common->cached_buffer); + *p_buf = gst_buffer_copy_region (common->cached_buffer, + GST_BUFFER_COPY_ALL, 0, size); + if (bytes) { + common->cached_data = gst_buffer_map (common->cached_buffer, + NULL, NULL, GST_MAP_READ); + *bytes = common->cached_data; + } return GST_FLOW_OK; } @@ -1664,9 +1695,15 @@ GstFlowReturn gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common, GstElement * el, guint32 * _id, guint64 * _length, guint * _needed) { - return gst_ebml_peek_id_length (_id, _length, _needed, + GstFlowReturn ret; + + ret = gst_ebml_peek_id_length (_id, _length, _needed, (GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common, el, common->offset); + + gst_adapter_unmap (common->adapter); + + return ret; } static GstFlowReturn |