Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / debian / patches / 0029-uridecodebin-use-bitrate-to-configure-streaming-buff.patch
1 From 4a8a2fcb49d44cc41e924db3a94bfc8998224744 Mon Sep 17 00:00:00 2001
2 From: Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
3 Date: Tue, 26 Apr 2011 13:37:51 +0200
4 Subject: [PATCH] uridecodebin: use bitrate to configure streaming
5  buffer-duration default case
6
7 In particular, in audio only cases whose (estimated) metadata provides bitrate
8 information, the buffer-size based on such bitrate (and buffer-duration)
9 will be much more reasonable than queue2 default buffer-size.
10 ---
11  gst/playback/gsturidecodebin.c |  125 +++++++++++++++++++++++++++++++++++++++-
12  1 files changed, 123 insertions(+), 2 deletions(-)
13
14 diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c
15 index 361b164..6469d90 100644
16 --- a/gst/playback/gsturidecodebin.c
17 +++ b/gst/playback/gsturidecodebin.c
18 @@ -58,6 +58,12 @@ typedef struct _GstURIDecodeBinClass GstURIDecodeBinClass;
19  #define GST_URI_DECODE_BIN_LOCK(dec) (g_mutex_lock(GST_URI_DECODE_BIN_GET_LOCK(dec)))
20  #define GST_URI_DECODE_BIN_UNLOCK(dec) (g_mutex_unlock(GST_URI_DECODE_BIN_GET_LOCK(dec)))
21  
22 +typedef struct _GstURIDecodeBinStream
23 +{
24 +  gulong probe_id;
25 +  guint bitrate;
26 +} GstURIDecodeBinStream;
27 +
28  /**
29   * GstURIDecodeBin
30   *
31 @@ -92,6 +98,7 @@ struct _GstURIDecodeBin
32    guint have_type_id;           /* have-type signal id from typefind */
33    GSList *decodebins;
34    GSList *pending_decodebins;
35 +  GHashTable *streams;
36    gint numpads;
37  
38    /* for dynamic sources */
39 @@ -938,7 +945,99 @@ source_no_more_pads (GstElement * element, GstURIDecodeBin * bin)
40    no_more_pads_full (element, FALSE, bin);
41  }
42  
43 -/* Called by the signal handlers when a decodebin has 
44 +static void
45 +configure_stream_buffering (GstURIDecodeBin * decoder)
46 +{
47 +  GstElement *queue = NULL;
48 +  GHashTableIter iter;
49 +  gpointer key, value;
50 +  gint bitrate = 0;
51 +
52 +  /* automatic configuration enabled ? */
53 +  if (decoder->buffer_size != -1)
54 +    return;
55 +
56 +  GST_URI_DECODE_BIN_LOCK (decoder);
57 +  if (decoder->queue)
58 +    queue = gst_object_ref (decoder->queue);
59 +
60 +  g_hash_table_iter_init (&iter, decoder->streams);
61 +  while (g_hash_table_iter_next (&iter, &key, &value)) {
62 +    GstURIDecodeBinStream *stream = value;
63 +
64 +    if (stream->bitrate && bitrate >= 0)
65 +      bitrate += stream->bitrate;
66 +    else
67 +      bitrate = -1;
68 +  }
69 +  GST_URI_DECODE_BIN_UNLOCK (decoder);
70 +
71 +  GST_DEBUG_OBJECT (decoder, "overall bitrate %d", bitrate);
72 +  if (!queue)
73 +    return;
74 +
75 +  if (bitrate > 0) {
76 +    guint64 time;
77 +    guint bytes;
78 +
79 +    /* all streams have a bitrate;
80 +     * configure queue size based on queue duration using combined bitrate */
81 +    g_object_get (queue, "max-size-time", &time, NULL);
82 +    GST_DEBUG_OBJECT (decoder, "queue buffering time %" GST_TIME_FORMAT,
83 +        GST_TIME_ARGS (time));
84 +    if (time > 0) {
85 +      bytes = gst_util_uint64_scale (time, bitrate, 8 * GST_SECOND);
86 +      GST_DEBUG_OBJECT (decoder, "corresponds to buffer size %d", bytes);
87 +      g_object_set (queue, "max-size-bytes", bytes, NULL);
88 +    }
89 +  }
90 +
91 +  gst_object_unref (queue);
92 +}
93 +
94 +static gboolean
95 +decoded_pad_event_probe (GstPad * pad, GstEvent * event,
96 +    GstURIDecodeBin * decoder)
97 +{
98 +  GST_LOG_OBJECT (pad, "%s, decoder %p", GST_EVENT_TYPE_NAME (event), decoder);
99 +
100 +  /* look for a bitrate tag */
101 +  switch (GST_EVENT_TYPE (event)) {
102 +    case GST_EVENT_TAG:
103 +    {
104 +      GstTagList *list;
105 +      guint bitrate = 0;
106 +      GstURIDecodeBinStream *stream;
107 +
108 +      gst_event_parse_tag (event, &list);
109 +      if (!gst_tag_list_get_uint_index (list, GST_TAG_NOMINAL_BITRATE, 0,
110 +              &bitrate)) {
111 +        gst_tag_list_get_uint_index (list, GST_TAG_BITRATE, 0, &bitrate);
112 +      }
113 +      GST_DEBUG_OBJECT (pad, "found bitrate %u", bitrate);
114 +      if (bitrate) {
115 +        GST_URI_DECODE_BIN_LOCK (decoder);
116 +        stream = g_hash_table_lookup (decoder->streams, pad);
117 +        GST_URI_DECODE_BIN_UNLOCK (decoder);
118 +        if (stream) {
119 +          stream->bitrate = bitrate;
120 +          /* no longer need this probe now */
121 +          gst_pad_remove_event_probe (pad, stream->probe_id);
122 +          /* configure buffer if possible */
123 +          configure_stream_buffering (decoder);
124 +        }
125 +      }
126 +      break;
127 +    }
128 +    default:
129 +      break;
130 +  }
131 +
132 +  /* never drop */
133 +  return TRUE;
134 +}
135 +
136 +/* Called by the signal handlers when a decodebin has
137   * found a new raw pad.  
138   */
139  static void
140 @@ -948,6 +1047,7 @@ new_decoded_pad_cb (GstElement * element, GstPad * pad, gboolean last,
141    GstPad *newpad;
142    GstPadTemplate *pad_tmpl;
143    gchar *padname;
144 +  GstURIDecodeBinStream *stream;
145  
146    GST_DEBUG_OBJECT (element, "new decoded pad, name: <%s>. Last: %d",
147        GST_PAD_NAME (pad), last);
148 @@ -965,11 +1065,19 @@ new_decoded_pad_cb (GstElement * element, GstPad * pad, gboolean last,
149    /* store ref to the ghostpad so we can remove it */
150    g_object_set_data (G_OBJECT (pad), "uridecodebin.ghostpad", newpad);
151  
152 +  /* add event probe to monitor tags */
153 +  stream = g_slice_alloc0 (sizeof (GstURIDecodeBinStream));
154 +  stream->probe_id =
155 +      gst_pad_add_event_probe (pad, G_CALLBACK (decoded_pad_event_probe),
156 +      decoder);
157 +  GST_URI_DECODE_BIN_LOCK (decoder);
158 +  g_hash_table_insert (decoder->streams, pad, stream);
159 +  GST_URI_DECODE_BIN_UNLOCK (decoder);
160 +
161    gst_pad_set_active (newpad, TRUE);
162    gst_element_add_pad (GST_ELEMENT_CAST (decoder), newpad);
163  }
164  
165 -
166  static gboolean
167  source_pad_event_probe (GstPad * pad, GstEvent * event,
168      GstURIDecodeBin * decoder)
169 @@ -1782,6 +1890,12 @@ could_not_link:
170    }
171  }
172  
173 +static void
174 +free_stream (gpointer value)
175 +{
176 +  g_slice_free (GstURIDecodeBinStream, value);
177 +}
178 +
179  /* remove source and all related elements */
180  static void
181  remove_source (GstURIDecodeBin * bin)
182 @@ -1815,6 +1929,10 @@ remove_source (GstURIDecodeBin * bin)
183      gst_bin_remove (GST_BIN_CAST (bin), bin->typefind);
184      bin->typefind = NULL;
185    }
186 +  if (bin->streams) {
187 +    g_hash_table_destroy (bin->streams);
188 +    bin->streams = NULL;
189 +  }
190    /* Don't loose the SOURCE flag */
191    GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_IS_SOURCE);
192  }
193 @@ -1909,6 +2027,9 @@ setup_source (GstURIDecodeBin * decoder)
194    /* remove the old decoders now, if any */
195    remove_decoders (decoder, FALSE);
196  
197 +  /* stream admin setup */
198 +  decoder->streams = g_hash_table_new_full (NULL, NULL, NULL, free_stream);
199 +
200    /* see if the source element emits raw audio/video all by itself,
201     * if so, we can create streams for the pads and be done with it.
202     * Also check that is has source pads, if not, we assume it will