aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLRN <lrn1986@gmail.com>2012-08-16 10:41:59 +0000
committerLRN <lrn1986@gmail.com>2012-08-16 10:41:59 +0000
commit3f542fba4232cd50d198a658e72ac46961ebd374 (patch)
tree0917340a539024acbf3faf08c807fcf40124a0cb
parentddbe32198104530774a770fad4a271e9436f13ef (diff)
downloadlibextractor-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.c69
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}