diff options
-rw-r--r-- | src/plugins/gstreamer_extractor.c | 67 |
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 | ||
52 | pthread_mutex_t pipe_mutex; | 45 | pthread_mutex_t pipe_mutex; |
53 | 46 | ||
@@ -804,13 +797,6 @@ enum CurrentStreamType | |||
804 | struct PrivStruct | 797 | struct 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; | |||
909 | static GQuark duration_quark; | 895 | static GQuark duration_quark; |
910 | 896 | ||
911 | 897 | ||
898 | static 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 | ||
1952 | static 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 | ||