aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLRN <lrn1986@gmail.com>2013-12-22 20:53:25 +0000
committerLRN <lrn1986@gmail.com>2013-12-22 20:53:25 +0000
commit1135cd9f4382443970ba31ce20fbfd319742159d (patch)
treed65551a1e1b37b21e915810fcb5666508b0c2ac0
parentc22f738445aef0242dd22f243d75c5226d8e872f (diff)
downloadlibextractor-1135cd9f4382443970ba31ce20fbfd319742159d.tar.gz
libextractor-1135cd9f4382443970ba31ce20fbfd319742159d.zip
Change gstreamer plugin timeout logic
-rw-r--r--src/plugins/gstreamer_extractor.c67
1 files changed, 26 insertions, 41 deletions
diff --git a/src/plugins/gstreamer_extractor.c b/src/plugins/gstreamer_extractor.c
index 2deb228..876f0c6 100644
--- a/src/plugins/gstreamer_extractor.c
+++ b/src/plugins/gstreamer_extractor.c
@@ -35,19 +35,12 @@ GST_DEBUG_CATEGORY_STATIC (gstreamer_extractor);
35#define GST_CAT_DEFAULT gstreamer_extractor 35#define GST_CAT_DEFAULT gstreamer_extractor
36 36
37/** 37/**
38 * How often should we check for data timeout.
39 * In milliseconds.
40 */
41#define DATA_TIMEOUT_FREQUENCY 750 /* 750ms, hang up for 1.5s at most */
42
43/**
44 * Once discoverer has gone for that long without asking for data or 38 * Once discoverer has gone for that long without asking for data or
45 * asking to seek, or giving us discovered info, assume it hanged up 39 * asking to seek, or giving us discovered info, assume it hanged up
46 * and kill it. 40 * and kill it.
47 * In microseconds. 41 * In milliseconds.
48 * Keep this value a bit less than DATA_TIMEOUT_FREQUENCY
49 */ 42 */
50#define DATA_TIMEOUT 1350000LL /* 1.35s */ 43#define DATA_TIMEOUT 750 /* 750ms */
51 44
52pthread_mutex_t pipe_mutex; 45pthread_mutex_t pipe_mutex;
53 46
@@ -804,13 +797,6 @@ enum CurrentStreamType
804struct PrivStruct 797struct PrivStruct
805{ 798{
806 /** 799 /**
807 * Tracks the time from the last IO request so that we can decide
808 * to terminate processing if GStreamer just takes far too long.
809 * Values are based on 'g_get_monotonic_time()', in milliseconds.
810 */
811 gint64 last_data_request_time;
812
813 /**
814 * Current read-offset in the 'ec' context (based on our read/seek calls). 800 * Current read-offset in the 'ec' context (based on our read/seek calls).
815 */ 801 */
816 guint64 offset; 802 guint64 offset;
@@ -857,7 +843,7 @@ struct PrivStruct
857 size_t toc_pos; 843 size_t toc_pos;
858 844
859 /** 845 /**
860 * 846 * Identifier of the timeout event source
861 */ 847 */
862 guint timeout_id; 848 guint timeout_id;
863 849
@@ -909,6 +895,16 @@ static GQuark *subtitle_quarks;
909static GQuark duration_quark; 895static GQuark duration_quark;
910 896
911 897
898static gboolean
899_data_timeout (struct PrivStruct *ps)
900{
901 GST_ERROR ("GstDiscoverer I/O timed out");
902 ps->timeout_id = 0;
903 g_main_loop_quit (ps->loop);
904 return FALSE;
905}
906
907
912/** 908/**
913 * Implementation of GstElement's "need-data" callback. Reads data from 909 * Implementation of GstElement's "need-data" callback. Reads data from
914 * the extraction context and passes it to GStreamer. 910 * the extraction context and passes it to GStreamer.
@@ -931,8 +927,9 @@ feed_data (GstElement * appsrc,
931 927
932 GST_DEBUG ("Request %u bytes", size); 928 GST_DEBUG ("Request %u bytes", size);
933 929
934 /* Update it now, in case we bail out due to error */ 930 if (ps->timeout_id > 0)
935 ps->last_data_request_time = g_get_monotonic_time (); 931 g_source_remove (ps->timeout_id);
932 ps->timeout_id = g_timeout_add (DATA_TIMEOUT, (GSourceFunc) _data_timeout, ps);
936 933
937 if ( (ps->length > 0) && (ps->offset >= ps->length) ) 934 if ( (ps->length > 0) && (ps->offset >= ps->length) )
938 { 935 {
@@ -988,8 +985,9 @@ feed_data (GstElement * appsrc,
988 ps->offset = UINT64_MAX; /* set to invalid value */ 985 ps->offset = UINT64_MAX; /* set to invalid value */
989 } 986 }
990 987
991 /* Update it again to account for time we spent fulfilling the request */ 988 if (ps->timeout_id > 0)
992 ps->last_data_request_time = g_get_monotonic_time (); 989 g_source_remove (ps->timeout_id);
990 ps->timeout_id = g_timeout_add (DATA_TIMEOUT, (GSourceFunc) _data_timeout, ps);
993} 991}
994 992
995 993
@@ -1011,7 +1009,9 @@ seek_data (GstElement * appsrc,
1011 pthread_mutex_lock (&pipe_mutex); 1009 pthread_mutex_lock (&pipe_mutex);
1012 ps->offset = ps->ec->seek (ps->ec->cls, position, SEEK_SET); 1010 ps->offset = ps->ec->seek (ps->ec->cls, position, SEEK_SET);
1013 pthread_mutex_unlock (&pipe_mutex); 1011 pthread_mutex_unlock (&pipe_mutex);
1014 ps->last_data_request_time = g_get_monotonic_time (); 1012 if (ps->timeout_id > 0)
1013 g_source_remove (ps->timeout_id);
1014 ps->timeout_id = g_timeout_add (DATA_TIMEOUT, (GSourceFunc) _data_timeout, ps);
1015 return ps->offset == position; 1015 return ps->offset == position;
1016} 1016}
1017 1017
@@ -1935,7 +1935,9 @@ _new_discovered_uri (GstDiscoverer * dc,
1935 struct PrivStruct *ps) 1935 struct PrivStruct *ps)
1936{ 1936{
1937 send_discovered_info (info, ps); 1937 send_discovered_info (info, ps);
1938 ps->last_data_request_time = g_get_monotonic_time (); 1938 if (ps->timeout_id > 0)
1939 g_source_remove (ps->timeout_id);
1940 ps->timeout_id = g_timeout_add (DATA_TIMEOUT, (GSourceFunc) _data_timeout, ps);
1939} 1941}
1940 1942
1941 1943
@@ -1949,22 +1951,6 @@ _discoverer_finished (GstDiscoverer * dc, struct PrivStruct *ps)
1949} 1951}
1950 1952
1951 1953
1952static gboolean
1953_data_timeout (struct PrivStruct *ps)
1954{
1955 gint64 now = g_get_monotonic_time ();
1956 if (now - ps->last_data_request_time > DATA_TIMEOUT)
1957 {
1958 GST_ERROR ("GstDiscoverer I/O timed out (last heard from discoverer on %lld, now is %lld, difference is %lld > %lld",
1959 ps->last_data_request_time, now, now - ps->last_data_request_time, DATA_TIMEOUT);
1960 ps->timeout_id = 0;
1961 g_main_loop_quit (ps->loop);
1962 return FALSE;
1963 }
1964 return TRUE;
1965}
1966
1967
1968/** 1954/**
1969 * This callback is called when discoverer has constructed a source object to 1955 * This callback is called when discoverer has constructed a source object to
1970 * read from. Since we provided the appsrc:// uri to discoverer, this will be 1956 * read from. Since we provided the appsrc:// uri to discoverer, this will be
@@ -2000,8 +1986,7 @@ _source_setup (GstDiscoverer * dc,
2000 * data */ 1986 * data */
2001 g_signal_connect (ps->source, "need-data", G_CALLBACK (feed_data), ps); 1987 g_signal_connect (ps->source, "need-data", G_CALLBACK (feed_data), ps);
2002 g_signal_connect (ps->source, "seek-data", G_CALLBACK (seek_data), ps); 1988 g_signal_connect (ps->source, "seek-data", G_CALLBACK (seek_data), ps);
2003 ps->timeout_id = g_timeout_add (DATA_TIMEOUT_FREQUENCY, (GSourceFunc) _data_timeout, ps); 1989 ps->timeout_id = g_timeout_add (DATA_TIMEOUT, (GSourceFunc) _data_timeout, ps);
2004 ps->last_data_request_time = g_get_monotonic_time ();
2005} 1990}
2006 1991
2007 1992