1.1 --- a/gst-plugins-nuvdemux/src/gstnuvdemux.c Fri Oct 27 23:42:34 2006 +0100
1.2 +++ b/gst-plugins-nuvdemux/src/gstnuvdemux.c Mon Nov 06 23:12:21 2006 +0000
1.3 @@ -60,6 +60,7 @@
1.4 #define GST_CAT_DEFAULT nuvdemux_debug
1.5
1.6
1.7 +#define DEMUX_INDEX_SIZE_MAX (100000)
1.8 #define GST_FLOW_ERROR_NO_DATA -101
1.9
1.10 GST_DEBUG_CATEGORY_EXTERN (GST_CAT_EVENT);
1.11 @@ -89,8 +90,8 @@
1.12 GST_STATIC_CAPS_ANY);
1.13
1.14 /* NUV Demux indexes init/dispose callers */
1.15 -static void gst_nuv_demux_index_init( nuv_demux_index **p_idx );
1.16 -static void gst_nuv_demux_index_clean( nuv_demux_index **p_idx );
1.17 +static nuv_demux_index* gst_nuv_demux_index_new (void);
1.18 +static void gst_nuv_demux_index_destroy (nuv_demux_index *p_idx);
1.19
1.20 /* NUV Demux indexes manipulation functions */
1.21 static gint64 gst_nuv_demux_index_find_offset( GstNuvDemux *nuv, gint64 i_offset );
1.22 @@ -106,12 +107,12 @@
1.23 static GstFlowReturn gst_nuv_demux_play (GstPad * pad);
1.24 static gboolean gst_nuv_demux_sink_activate_pull (GstPad * sinkpad,
1.25 gboolean active);
1.26 +static gboolean gst_nuv_demux_sink_activate_push (GstPad * pad,
1.27 + gboolean active);
1.28 static gboolean gst_nuv_demux_sink_activate (GstPad * sinkpad);
1.29 static GstFlowReturn gst_nuv_demux_read_bytes (GstNuvDemux * nuv, guint64 size,
1.30 gboolean move, GstBuffer ** buffer);
1.31 static void gst_nuv_demux_reset (GstNuvDemux * nuv);
1.32 -static gboolean gst_nuv_demux_handle_sink_event (GstPad * sinkpad,
1.33 - GstEvent * event);
1.34 static void gst_nuv_demux_destoy_src_pad (GstNuvDemux * nuv);
1.35 static void gst_nuv_demux_send_eos (GstNuvDemux * nuv);
1.36
1.37 @@ -179,14 +180,15 @@
1.38 gst_pad_set_activatepull_function (nuv->sinkpad,
1.39 gst_nuv_demux_sink_activate_pull);
1.40
1.41 + gst_pad_set_activatepush_function (nuv->sinkpad,
1.42 + gst_nuv_demux_sink_activate_push);
1.43 +
1.44 gst_pad_set_chain_function (nuv->sinkpad,
1.45 GST_DEBUG_FUNCPTR (gst_nuv_demux_chain));
1.46
1.47 - gst_pad_set_event_function (nuv->sinkpad, gst_nuv_demux_handle_sink_event);
1.48 -
1.49 gst_element_add_pad (GST_ELEMENT (nuv), nuv->sinkpad);
1.50
1.51 - gst_nuv_demux_index_init( &nuv->index_entries );
1.52 + nuv->index_entries = gst_nuv_demux_index_new ();
1.53
1.54 nuv->adapter = NULL;
1.55 nuv->mpeg_buffer = NULL;
1.56 @@ -206,7 +208,7 @@
1.57 }
1.58
1.59 if ( nuv->index_entries != NULL ) {
1.60 - gst_nuv_demux_index_clean( &nuv->index_entries );
1.61 + gst_nuv_demux_index_destroy (nuv->index_entries);
1.62 nuv->index_entries = NULL;
1.63 }
1.64
1.65 @@ -223,22 +225,20 @@
1.66 * Indexes (timecode offset conversion) functions
1.67 *****************************************************************************/
1.68
1.69 -static void
1.70 -gst_nuv_demux_index_init( nuv_demux_index **p_idx )
1.71 +static nuv_demux_index*
1.72 +gst_nuv_demux_index_new (void)
1.73 {
1.74 - *p_idx = g_new0( nuv_demux_index, 1 );
1.75 - (*p_idx)->i_idx = 0;
1.76 - (*p_idx)->i_idx_max = 0;
1.77 + return g_new0 (nuv_demux_index, 1);
1.78 }
1.79
1.80 static void
1.81 -gst_nuv_demux_index_clean( nuv_demux_index **p_idx )
1.82 +gst_nuv_demux_index_destroy (nuv_demux_index *p_idx)
1.83 {
1.84 - if ( *p_idx != NULL ) {
1.85 - g_free( *p_idx );
1.86 - *p_idx = NULL;
1.87 + if (p_idx != NULL) {
1.88 + g_free (p_idx->idx);
1.89 + p_idx->idx = NULL;
1.90 + g_free (p_idx);
1.91 }
1.92 -
1.93 }
1.94
1.95 static void
1.96 @@ -250,13 +250,13 @@
1.97 // return;
1.98
1.99 /* Be sure to append new entry (we don't insert point) */
1.100 - if( p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time )
1.101 + if (p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time)
1.102 return;
1.103
1.104 /* */
1.105 - if( p_idx->i_idx >= p_idx->i_idx_max )
1.106 + if (p_idx->i_idx >= p_idx->i_idx_max)
1.107 {
1.108 - if( p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX )
1.109 + if (p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX)
1.110 {
1.111 /* Avoid too big index */
1.112 const gint64 i_length = p_idx->idx[p_idx->i_idx-1].i_time -
1.113 @@ -265,20 +265,20 @@
1.114 gint i, j;
1.115
1.116 /* We try to reduce the resolution of the index by a factor 2 */
1.117 - for( i = 1, j = 1; i < p_idx->i_idx; i++ )
1.118 + for (i = 1, j = 1; i < p_idx->i_idx; i++)
1.119 {
1.120 - if( p_idx->idx[i].i_time < j * i_length / i_count )
1.121 + if (p_idx->idx[i].i_time < j * i_length / i_count)
1.122 continue;
1.123
1.124 p_idx->idx[j++] = p_idx->idx[i];
1.125 }
1.126 p_idx->i_idx = j;
1.127
1.128 - if( p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4 )
1.129 + if (p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4)
1.130 {
1.131 /* We haven't created enough space
1.132 * (This method won't create a good index but work for sure) */
1.133 - for( i = 0; i < p_idx->i_idx/2; i++ )
1.134 + for (i = 0; i < p_idx->i_idx/2; i++)
1.135 p_idx->idx[i] = p_idx->idx[2*i];
1.136 p_idx->i_idx /= 2;
1.137 }
1.138 @@ -286,8 +286,8 @@
1.139 else
1.140 {
1.141 p_idx->i_idx_max += 1000;
1.142 - //p_idx->idx = g_realloc( p_idx->idx,
1.143 - //p_idx->i_idx_max*sizeof(nuv_demux_index_entry));
1.144 + p_idx->idx = g_realloc (p_idx->idx,
1.145 + p_idx->i_idx_max*sizeof(nuv_demux_index_entry));
1.146 }
1.147 }
1.148
1.149 @@ -388,29 +388,6 @@
1.150 return p_idx->idx[i_max].i_offset;
1.151 }
1.152
1.153 -/*****************************************************************************
1.154 - * Utils functions
1.155 - *****************************************************************************/
1.156 -
1.157 -static gboolean
1.158 -gst_nuv_demux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
1.159 -{
1.160 - gboolean res = FALSE;
1.161 -
1.162 - switch (GST_EVENT_TYPE (event)) {
1.163 - case GST_EVENT_NEWSEGMENT:
1.164 - res = TRUE;
1.165 - break;
1.166 - default:
1.167 - return gst_pad_event_default (sinkpad, event);
1.168 - break;
1.169 - }
1.170 -
1.171 - gst_event_unref (event);
1.172 - return res;
1.173 -}
1.174 -
1.175 -
1.176 /* HeaderLoad:
1.177 */
1.178 static GstFlowReturn
1.179 @@ -610,10 +587,11 @@
1.180 gst_pad_set_active (nuv->src_video_pad, TRUE);
1.181 gst_pad_set_caps (nuv->src_video_pad, video_caps);
1.182
1.183 + gst_pad_set_active (nuv->src_video_pad, TRUE);
1.184 + gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_video_pad);
1.185 +
1.186 gst_pad_set_event_function (nuv->src_video_pad,
1.187 gst_nuv_demux_handle_src_event);
1.188 - gst_pad_set_active (nuv->src_video_pad, TRUE);
1.189 - gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_video_pad);
1.190
1.191 gst_caps_unref (video_caps);
1.192 }
1.193 @@ -681,11 +659,11 @@
1.194 /* search for a valid timecode in the indexes list (find the nearest valid timecode) */
1.195 if ( h->i_timecode < 0 ) {
1.196 /* convert this actual timecode to a valid index in the timecode's table */
1.197 - gint64 pos = gst_nuv_demux_index_convert_time( nuv, h->i_timecode );
1.198 + gint64 pos = gst_nuv_demux_index_convert_time (nuv, h->i_timecode);
1.199
1.200 /* find the nearest empty frame slot */
1.201 - gint64 near_off = gst_nuv_demux_index_find_offset( nuv, pos );
1.202 - near_off = 0;
1.203 + gint64 near_off = gst_nuv_demux_index_find_offset (nuv, pos);
1.204 +
1.205 /* just get the timecode from the timecode's table */
1.206 GST_BUFFER_TIMESTAMP (buf) = nuv->index_entries->idx[near_off].i_time * GST_MSECOND;
1.207 } else {
1.208 @@ -704,6 +682,10 @@
1.209 GST_BUFFER_OFFSET (buf) = nuv->video_offset;
1.210 gst_buffer_set_caps (buf, GST_PAD_CAPS (nuv->src_video_pad));
1.211 ret = gst_pad_push (nuv->src_video_pad, buf);
1.212 + if (ret != GST_FLOW_OK) {
1.213 + GST_WARNING_OBJECT (nuv, "error pushing on srcpad %s, is linked? = %d",
1.214 + gst_pad_get_name (nuv->src_video_pad), gst_pad_is_linked (nuv->src_video_pad));
1.215 + }
1.216 nuv->video_offset++;
1.217 break;
1.218 }
1.219 @@ -715,24 +697,33 @@
1.220 GST_BUFFER_OFFSET (buf) = nuv->audio_offset;
1.221 gst_buffer_set_caps (buf, GST_PAD_CAPS (nuv->src_audio_pad));
1.222 ret = gst_pad_push (nuv->src_audio_pad, buf);
1.223 + if (ret != GST_FLOW_OK) {
1.224 + GST_WARNING_OBJECT (nuv, "Error pushing on srcpad %s, is linked? = %d",
1.225 + gst_pad_get_name (nuv->src_audio_pad), gst_pad_is_linked (nuv->src_audio_pad));
1.226 + }
1.227 nuv->audio_offset++;
1.228 break;
1.229 }
1.230 case 'S':
1.231 {
1.232 + /*
1.233 switch (h->i_compression) {
1.234 case 'V':
1.235 + GST_DEBUG_OBJECT (nuv, "Video New Segment");
1.236 + nuv->video_offset = 0;
1.237 gst_pad_push_event (nuv->src_video_pad,
1.238 gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1,
1.239 - h->i_timecode));
1.240 + 0));
1.241 break;
1.242 case 'A':
1.243 + GST_DEBUG_OBJECT (nuv, "Audio New Segment");
1.244 gst_pad_push_event (nuv->src_audio_pad,
1.245 gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
1.246 break;
1.247 default:
1.248 break;
1.249 }
1.250 + */
1.251 }
1.252 default:
1.253 if (buf != NULL)
1.254 @@ -741,7 +732,7 @@
1.255 break;
1.256 }
1.257
1.258 - GST_DEBUG_OBJECT (nuv, "data sended");
1.259 + GST_DEBUG_OBJECT (nuv, "data sent");
1.260
1.261 done:
1.262 nuv->state = GST_NUV_DEMUX_FRAME_HEADER;
1.263 @@ -938,6 +929,8 @@
1.264 return GST_FLOW_OK;
1.265
1.266 pause:
1.267 + g_debug ("PAUSE");
1.268 +
1.269 GST_LOG_OBJECT (nuv, "pausing task, reason %s", gst_flow_get_name (res));
1.270 gst_pad_pause_task (nuv->sinkpad);
1.271 if (GST_FLOW_IS_FATAL (res)) {
1.272 @@ -989,7 +982,11 @@
1.273 return GST_FLOW_ERROR_NO_DATA;
1.274
1.275 if (move) {
1.276 - *buffer = gst_adapter_take_buffer (nuv->adapter, size);
1.277 + guint8 *data = NULL;
1.278 +
1.279 + data = (guint8 *) gst_adapter_take (nuv->adapter, size);
1.280 + *buffer = gst_buffer_new ();
1.281 + gst_buffer_set_data (*buffer, data, size);
1.282 } else {
1.283 guint8 *data = NULL;
1.284
1.285 @@ -1038,6 +1035,22 @@
1.286 return TRUE;
1.287 }
1.288
1.289 +static gboolean
1.290 +gst_nuv_demux_sink_activate_push (GstPad * pad, gboolean active)
1.291 +{
1.292 + GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
1.293 +
1.294 + if (active) {
1.295 + GST_DEBUG_OBJECT (nuv, "activating push/chain function");
1.296 + } else {
1.297 + GST_DEBUG_OBJECT (nuv, "deactivating push/chain function");
1.298 + }
1.299 +
1.300 + gst_object_unref (nuv);
1.301 +
1.302 + return TRUE;
1.303 +}
1.304 +
1.305 static GstFlowReturn
1.306 gst_nuv_demux_chain (GstPad * pad, GstBuffer * buf)
1.307 {
1.308 @@ -1047,6 +1060,8 @@
1.309
1.310 GST_DEBUG_OBJECT (nuv, "PUSH adapter %d", gst_adapter_available (nuv->adapter));
1.311
1.312 + gst_object_unref (nuv);
1.313 +
1.314 return gst_nuv_demux_play (pad);
1.315 }
1.316
1.317 @@ -1101,7 +1116,7 @@
1.318 gst_nuv_demux_change_state (GstElement * element, GstStateChange transition)
1.319 {
1.320 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
1.321 -
1.322 +
1.323 switch (transition) {
1.324 case GST_STATE_CHANGE_READY_TO_PAUSED:
1.325 break;
1.326 @@ -1115,7 +1130,7 @@
1.327
1.328 switch (transition) {
1.329 case GST_STATE_CHANGE_PAUSED_TO_READY:
1.330 - //gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element));
1.331 + gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element));
1.332 gst_nuv_demux_reset (GST_NUV_DEMUX (element));
1.333 break;
1.334 default: