diff options
author | LRN <lrn1986@gmail.com> | 2012-08-16 10:41:59 +0000 |
---|---|---|
committer | LRN <lrn1986@gmail.com> | 2012-08-16 10:41:59 +0000 |
commit | 3f542fba4232cd50d198a658e72ac46961ebd374 (patch) | |
tree | 0917340a539024acbf3faf08c807fcf40124a0cb | |
parent | ddbe32198104530774a770fad4a271e9436f13ef (diff) | |
download | libextractor-3f542fba4232cd50d198a658e72ac46961ebd374.tar.gz libextractor-3f542fba4232cd50d198a658e72ac46961ebd374.zip |
Fix buffer underrunning
Apparently, pull-mode requires us to satisfy appsrc's every whim,
i.e. if it asks more data than we can give it in one go (due to shm
size limit), then we have to buffer it up before giving it away.
Now discoverer works correctly in random mode, so reverting previous
commit as well.
-rw-r--r-- | src/plugins/gstreamer_extractor.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/src/plugins/gstreamer_extractor.c b/src/plugins/gstreamer_extractor.c index 73231bf..328064b 100644 --- a/src/plugins/gstreamer_extractor.c +++ b/src/plugins/gstreamer_extractor.c | |||
@@ -711,8 +711,10 @@ _source_setup (GstDiscoverer * dc, GstElement * source, PrivStruct * ps) | |||
711 | if (ps->length > 0) | 711 | if (ps->length > 0) |
712 | { | 712 | { |
713 | g_object_set (ps->source, "size", (gint64) ps->length, NULL); | 713 | g_object_set (ps->source, "size", (gint64) ps->length, NULL); |
714 | gst_util_set_object_arg (G_OBJECT (ps->source), "stream-type", "random-access"); | ||
714 | } | 715 | } |
715 | gst_util_set_object_arg (G_OBJECT (ps->source), "stream-type", "seekable"); | 716 | else |
717 | gst_util_set_object_arg (G_OBJECT (ps->source), "stream-type", "seekable"); | ||
716 | 718 | ||
717 | /* configure the appsrc, we will push a buffer to appsrc when it needs more | 719 | /* configure the appsrc, we will push a buffer to appsrc when it needs more |
718 | * data */ | 720 | * data */ |
@@ -726,6 +728,11 @@ feed_data (GstElement * appsrc, guint size, PrivStruct * ps) | |||
726 | GstFlowReturn ret; | 728 | GstFlowReturn ret; |
727 | long data_len; | 729 | long data_len; |
728 | uint8_t *le_data; | 730 | uint8_t *le_data; |
731 | guint accumulated; | ||
732 | GstMemory *mem; | ||
733 | GstMapInfo mi; | ||
734 | |||
735 | GST_DEBUG ("Request %u bytes", size); | ||
729 | 736 | ||
730 | if (ps->length > 0 && ps->offset >= ps->length) { | 737 | if (ps->length > 0 && ps->offset >= ps->length) { |
731 | /* we are at the EOS, send end-of-stream */ | 738 | /* we are at the EOS, send end-of-stream */ |
@@ -736,37 +743,47 @@ feed_data (GstElement * appsrc, guint size, PrivStruct * ps) | |||
736 | if (ps->length > 0 && ps->offset + size > ps->length) | 743 | if (ps->length > 0 && ps->offset + size > ps->length) |
737 | size = ps->length - ps->offset; | 744 | size = ps->length - ps->offset; |
738 | 745 | ||
739 | data_len = ps->ec->read (ps->ec->cls, (void **) &le_data, size); | 746 | mem = gst_allocator_alloc (NULL, size, NULL); |
740 | if (data_len > 0) | 747 | if (!gst_memory_map (mem, &mi, GST_MAP_WRITE)) |
741 | { | 748 | { |
742 | GstMemory *mem; | 749 | gst_memory_unref (mem); |
743 | GstMapInfo mi; | 750 | GST_DEBUG ("Failed to map the memory"); |
744 | mem = gst_allocator_alloc (NULL, data_len, NULL); | 751 | ret = gst_app_src_end_of_stream (GST_APP_SRC (ps->source)); |
745 | if (gst_memory_map (mem, &mi, GST_MAP_WRITE)) | 752 | return; |
746 | { | 753 | } |
747 | GstBuffer *buffer; | 754 | |
748 | memcpy (mi.data, le_data, data_len); | 755 | accumulated = 0; |
749 | gst_memory_unmap (mem, &mi); | 756 | data_len = 1; |
750 | buffer = gst_buffer_new (); | 757 | while (accumulated < size && data_len > 0) |
751 | gst_buffer_append_memory (buffer, mem); | 758 | { |
752 | 759 | data_len = ps->ec->read (ps->ec->cls, (void **) &le_data, size - accumulated); | |
753 | /* we need to set an offset for random access */ | 760 | if (data_len > 0) |
754 | GST_BUFFER_OFFSET (buffer) = ps->offset; | ||
755 | GST_BUFFER_OFFSET_END (buffer) = ps->offset + data_len; | ||
756 | |||
757 | GST_DEBUG ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u", buffer, | ||
758 | ps->offset, data_len); | ||
759 | ret = gst_app_src_push_buffer (GST_APP_SRC (ps->source), buffer); | ||
760 | ps->offset += data_len; | ||
761 | } | ||
762 | else | ||
763 | { | 761 | { |
764 | gst_memory_unref (mem); | 762 | memcpy (&mi.data[accumulated], le_data, data_len); |
765 | ret = gst_app_src_end_of_stream (GST_APP_SRC (ps->source)); | 763 | accumulated += data_len; |
766 | } | 764 | } |
767 | } | 765 | } |
766 | gst_memory_unmap (mem, &mi); | ||
767 | if (data_len > 0) | ||
768 | { | ||
769 | GstBuffer *buffer; | ||
770 | buffer = gst_buffer_new (); | ||
771 | gst_buffer_append_memory (buffer, mem); | ||
772 | |||
773 | /* we need to set an offset for random access */ | ||
774 | GST_BUFFER_OFFSET (buffer) = ps->offset; | ||
775 | GST_BUFFER_OFFSET_END (buffer) = ps->offset + size; | ||
776 | |||
777 | GST_DEBUG ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u", buffer, | ||
778 | ps->offset, size); | ||
779 | ret = gst_app_src_push_buffer (GST_APP_SRC (ps->source), buffer); | ||
780 | ps->offset += size; | ||
781 | } | ||
768 | else | 782 | else |
783 | { | ||
784 | gst_memory_unref (mem); | ||
769 | ret = gst_app_src_end_of_stream (GST_APP_SRC (ps->source)); | 785 | ret = gst_app_src_end_of_stream (GST_APP_SRC (ps->source)); |
786 | } | ||
770 | 787 | ||
771 | return; | 788 | return; |
772 | } | 789 | } |