diff -r 2a552f003c4e -r 8113a3dce6ce gst-plugins-nuvdemux/src/gstnuvdemux.c --- a/gst-plugins-nuvdemux/src/gstnuvdemux.c Fri Oct 27 23:42:34 2006 +0100 +++ b/gst-plugins-nuvdemux/src/gstnuvdemux.c Mon Nov 06 22:57:44 2006 +0000 @@ -60,6 +60,7 @@ #define GST_CAT_DEFAULT nuvdemux_debug +#define DEMUX_INDEX_SIZE_MAX (100000) #define GST_FLOW_ERROR_NO_DATA -101 GST_DEBUG_CATEGORY_EXTERN (GST_CAT_EVENT); @@ -89,8 +90,8 @@ GST_STATIC_CAPS_ANY); /* NUV Demux indexes init/dispose callers */ -static void gst_nuv_demux_index_init( nuv_demux_index **p_idx ); -static void gst_nuv_demux_index_clean( nuv_demux_index **p_idx ); +static nuv_demux_index* gst_nuv_demux_index_new (void); +static void gst_nuv_demux_index_destroy (nuv_demux_index *p_idx); /* NUV Demux indexes manipulation functions */ static gint64 gst_nuv_demux_index_find_offset( GstNuvDemux *nuv, gint64 i_offset ); @@ -106,12 +107,12 @@ static GstFlowReturn gst_nuv_demux_play (GstPad * pad); static gboolean gst_nuv_demux_sink_activate_pull (GstPad * sinkpad, gboolean active); +static gboolean gst_nuv_demux_sink_activate_push (GstPad * pad, + gboolean active); static gboolean gst_nuv_demux_sink_activate (GstPad * sinkpad); static GstFlowReturn gst_nuv_demux_read_bytes (GstNuvDemux * nuv, guint64 size, gboolean move, GstBuffer ** buffer); static void gst_nuv_demux_reset (GstNuvDemux * nuv); -static gboolean gst_nuv_demux_handle_sink_event (GstPad * sinkpad, - GstEvent * event); static void gst_nuv_demux_destoy_src_pad (GstNuvDemux * nuv); static void gst_nuv_demux_send_eos (GstNuvDemux * nuv); @@ -179,14 +180,15 @@ gst_pad_set_activatepull_function (nuv->sinkpad, gst_nuv_demux_sink_activate_pull); + gst_pad_set_activatepush_function (nuv->sinkpad, + gst_nuv_demux_sink_activate_push); + gst_pad_set_chain_function (nuv->sinkpad, GST_DEBUG_FUNCPTR (gst_nuv_demux_chain)); - gst_pad_set_event_function (nuv->sinkpad, gst_nuv_demux_handle_sink_event); - gst_element_add_pad (GST_ELEMENT (nuv), nuv->sinkpad); - gst_nuv_demux_index_init( &nuv->index_entries ); + nuv->index_entries = gst_nuv_demux_index_new (); nuv->adapter = NULL; nuv->mpeg_buffer = NULL; @@ -206,7 +208,7 @@ } if ( nuv->index_entries != NULL ) { - gst_nuv_demux_index_clean( &nuv->index_entries ); + gst_nuv_demux_index_destroy (nuv->index_entries); nuv->index_entries = NULL; } @@ -223,22 +225,20 @@ * Indexes (timecode offset conversion) functions *****************************************************************************/ -static void -gst_nuv_demux_index_init( nuv_demux_index **p_idx ) +static nuv_demux_index* +gst_nuv_demux_index_new (void) { - *p_idx = g_new0( nuv_demux_index, 1 ); - (*p_idx)->i_idx = 0; - (*p_idx)->i_idx_max = 0; + return g_new0 (nuv_demux_index, 1); } static void -gst_nuv_demux_index_clean( nuv_demux_index **p_idx ) +gst_nuv_demux_index_destroy (nuv_demux_index *p_idx) { - if ( *p_idx != NULL ) { - g_free( *p_idx ); - *p_idx = NULL; + if (p_idx != NULL) { + g_free (p_idx->idx); + p_idx->idx = NULL; + g_free (p_idx); } - } static void @@ -250,13 +250,13 @@ // return; /* Be sure to append new entry (we don't insert point) */ - if( p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time ) + if (p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time) return; /* */ - if( p_idx->i_idx >= p_idx->i_idx_max ) + if (p_idx->i_idx >= p_idx->i_idx_max) { - if( p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX ) + if (p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX) { /* Avoid too big index */ const gint64 i_length = p_idx->idx[p_idx->i_idx-1].i_time - @@ -265,20 +265,20 @@ gint i, j; /* We try to reduce the resolution of the index by a factor 2 */ - for( i = 1, j = 1; i < p_idx->i_idx; i++ ) + for (i = 1, j = 1; i < p_idx->i_idx; i++) { - if( p_idx->idx[i].i_time < j * i_length / i_count ) + if (p_idx->idx[i].i_time < j * i_length / i_count) continue; p_idx->idx[j++] = p_idx->idx[i]; } p_idx->i_idx = j; - if( p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4 ) + if (p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4) { /* We haven't created enough space * (This method won't create a good index but work for sure) */ - for( i = 0; i < p_idx->i_idx/2; i++ ) + for (i = 0; i < p_idx->i_idx/2; i++) p_idx->idx[i] = p_idx->idx[2*i]; p_idx->i_idx /= 2; } @@ -286,8 +286,8 @@ else { p_idx->i_idx_max += 1000; - //p_idx->idx = g_realloc( p_idx->idx, - //p_idx->i_idx_max*sizeof(nuv_demux_index_entry)); + p_idx->idx = g_realloc (p_idx->idx, + p_idx->i_idx_max*sizeof(nuv_demux_index_entry)); } } @@ -388,29 +388,6 @@ return p_idx->idx[i_max].i_offset; } -/***************************************************************************** - * Utils functions - *****************************************************************************/ - -static gboolean -gst_nuv_demux_handle_sink_event (GstPad * sinkpad, GstEvent * event) -{ - gboolean res = FALSE; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - res = TRUE; - break; - default: - return gst_pad_event_default (sinkpad, event); - break; - } - - gst_event_unref (event); - return res; -} - - /* HeaderLoad: */ static GstFlowReturn @@ -610,10 +587,11 @@ gst_pad_set_active (nuv->src_video_pad, TRUE); gst_pad_set_caps (nuv->src_video_pad, video_caps); + gst_pad_set_active (nuv->src_video_pad, TRUE); + gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_video_pad); + gst_pad_set_event_function (nuv->src_video_pad, gst_nuv_demux_handle_src_event); - gst_pad_set_active (nuv->src_video_pad, TRUE); - gst_element_add_pad (GST_ELEMENT (nuv), nuv->src_video_pad); gst_caps_unref (video_caps); } @@ -681,11 +659,11 @@ /* search for a valid timecode in the indexes list (find the nearest valid timecode) */ if ( h->i_timecode < 0 ) { /* convert this actual timecode to a valid index in the timecode's table */ - gint64 pos = gst_nuv_demux_index_convert_time( nuv, h->i_timecode ); + gint64 pos = gst_nuv_demux_index_convert_time (nuv, h->i_timecode); /* find the nearest empty frame slot */ - gint64 near_off = gst_nuv_demux_index_find_offset( nuv, pos ); - near_off = 0; + gint64 near_off = gst_nuv_demux_index_find_offset (nuv, pos); + /* just get the timecode from the timecode's table */ GST_BUFFER_TIMESTAMP (buf) = nuv->index_entries->idx[near_off].i_time * GST_MSECOND; } else { @@ -704,6 +682,10 @@ GST_BUFFER_OFFSET (buf) = nuv->video_offset; gst_buffer_set_caps (buf, GST_PAD_CAPS (nuv->src_video_pad)); ret = gst_pad_push (nuv->src_video_pad, buf); + if (ret != GST_FLOW_OK) { + GST_WARNING_OBJECT (nuv, "error pushing on srcpad %s, is linked? = %d", + gst_pad_get_name (nuv->src_video_pad), gst_pad_is_linked (nuv->src_video_pad)); + } nuv->video_offset++; break; } @@ -715,24 +697,33 @@ GST_BUFFER_OFFSET (buf) = nuv->audio_offset; gst_buffer_set_caps (buf, GST_PAD_CAPS (nuv->src_audio_pad)); ret = gst_pad_push (nuv->src_audio_pad, buf); + if (ret != GST_FLOW_OK) { + GST_WARNING_OBJECT (nuv, "Error pushing on srcpad %s, is linked? = %d", + gst_pad_get_name (nuv->src_audio_pad), gst_pad_is_linked (nuv->src_audio_pad)); + } nuv->audio_offset++; break; } case 'S': { + /* switch (h->i_compression) { case 'V': + GST_DEBUG_OBJECT (nuv, "Video New Segment"); + nuv->video_offset = 0; gst_pad_push_event (nuv->src_video_pad, gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, - h->i_timecode)); + 0)); break; case 'A': + GST_DEBUG_OBJECT (nuv, "Audio New Segment"); gst_pad_push_event (nuv->src_audio_pad, gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0)); break; default: break; } + */ } default: if (buf != NULL) @@ -741,7 +732,7 @@ break; } - GST_DEBUG_OBJECT (nuv, "data sended"); + GST_DEBUG_OBJECT (nuv, "data sent"); done: nuv->state = GST_NUV_DEMUX_FRAME_HEADER; @@ -938,6 +929,8 @@ return GST_FLOW_OK; pause: + g_debug ("PAUSE"); + GST_LOG_OBJECT (nuv, "pausing task, reason %s", gst_flow_get_name (res)); gst_pad_pause_task (nuv->sinkpad); if (GST_FLOW_IS_FATAL (res)) { @@ -989,7 +982,11 @@ return GST_FLOW_ERROR_NO_DATA; if (move) { - *buffer = gst_adapter_take_buffer (nuv->adapter, size); + guint8 *data = NULL; + + data = (guint8 *) gst_adapter_take (nuv->adapter, size); + *buffer = gst_buffer_new (); + gst_buffer_set_data (*buffer, data, size); } else { guint8 *data = NULL; @@ -1038,6 +1035,22 @@ return TRUE; } +static gboolean +gst_nuv_demux_sink_activate_push (GstPad * pad, gboolean active) +{ + GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad)); + + if (active) { + GST_DEBUG_OBJECT (nuv, "activating push/chain function"); + } else { + GST_DEBUG_OBJECT (nuv, "deactivating push/chain function"); + } + + gst_object_unref (nuv); + + return TRUE; +} + static GstFlowReturn gst_nuv_demux_chain (GstPad * pad, GstBuffer * buf) { @@ -1047,6 +1060,8 @@ GST_DEBUG_OBJECT (nuv, "PUSH adapter %d", gst_adapter_available (nuv->adapter)); + gst_object_unref (nuv); + return gst_nuv_demux_play (pad); } @@ -1101,7 +1116,7 @@ gst_nuv_demux_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - + switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: break; @@ -1115,7 +1130,7 @@ switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: - //gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element)); + gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element)); gst_nuv_demux_reset (GST_NUV_DEMUX (element)); break; default: