gst-plugins-nuvdemux/src/gstnuvdemux.c
branchtrunk
changeset 57 c83c59b22fe1
parent 56 24be83eaef89
child 60 98fa2109e716
     1.1 --- a/gst-plugins-nuvdemux/src/gstnuvdemux.c	Thu Oct 26 18:55:14 2006 +0100
     1.2 +++ b/gst-plugins-nuvdemux/src/gstnuvdemux.c	Fri Oct 27 00:11:21 2006 +0100
     1.3 @@ -52,6 +52,8 @@
     1.4  #include <gst/gstplugin.h>
     1.5  #include <string.h>
     1.6  
     1.7 +#define GETTEXT_PACKAGE	"gst-plugins-nuvdemux-0.10.3"
     1.8 +
     1.9  #include "gst/gst-i18n-plugin.h"
    1.10  #include "gstnuvdemux.h"
    1.11  
    1.12 @@ -88,8 +90,8 @@
    1.13      GST_STATIC_CAPS_ANY);
    1.14  
    1.15  /* NUV Demux indexes init/dispose callers */
    1.16 -static void gst_nuv_demux_index_init( nuv_demux_index *p_idx );
    1.17 -static void gst_nuv_demux_index_clean( nuv_demux_index *p_idx );
    1.18 +static void gst_nuv_demux_index_init( nuv_demux_index **p_idx );
    1.19 +static void gst_nuv_demux_index_clean( nuv_demux_index **p_idx );
    1.20  
    1.21  /* NUV Demux indexes manipulation functions */
    1.22  static gint64 gst_nuv_demux_index_find_offset( GstNuvDemux *nuv, gint64 i_offset );
    1.23 @@ -137,18 +139,6 @@
    1.24  #define READ_DOUBLE_FROM_LE(d) *((gdouble* ) (d))
    1.25  #endif /* G_BYTE_ORDER != G_BIG_ENDIAN */
    1.26  
    1.27 -static gint32 
    1.28 -gst_nuv_demux_getdwle (void const * _p)
    1.29 -{
    1.30 -    guint8 * p = (guint8 *)_p;
    1.31 -	g_print( "[%s] shifting bits: {%d, %d, %d, %d}\n", __FUNCTION__, 
    1.32 -			  ((guint32)p[3] << 24), ((guint32)p[2] << 16),
    1.33 -              ((guint32)p[1] << 8), p[0] );
    1.34 -    return ( ((guint32)p[3] << 24) | ((guint32)p[2] << 16)
    1.35 -              | ((guint32)p[1] << 8) | p[0] );
    1.36 -    //return ( (gint)p[3] | (gint)p[2] | (gint)p[1] | p[0] );
    1.37 -}
    1.38 -
    1.39  static void
    1.40  gst_nuv_demux_base_init (gpointer klass)
    1.41  {
    1.42 @@ -197,7 +187,7 @@
    1.43  
    1.44    gst_element_add_pad (GST_ELEMENT (nuv), nuv->sinkpad);
    1.45    
    1.46 -  gst_nuv_demux_index_init( nuv->index_entries );
    1.47 +  gst_nuv_demux_index_init( &nuv->index_entries );
    1.48  
    1.49    nuv->adapter = NULL;
    1.50    nuv->mpeg_buffer = NULL;
    1.51 @@ -217,7 +207,7 @@
    1.52    }
    1.53    
    1.54    if ( nuv->index_entries != NULL ) {
    1.55 -  	gst_nuv_demux_index_clean( nuv->index_entries );
    1.56 +  	gst_nuv_demux_index_clean( &nuv->index_entries );
    1.57    	nuv->index_entries = NULL;
    1.58    }
    1.59  
    1.60 @@ -235,168 +225,168 @@
    1.61   *****************************************************************************/
    1.62  
    1.63  static void 
    1.64 -gst_nuv_demux_index_init( nuv_demux_index *p_idx )
    1.65 +gst_nuv_demux_index_init( nuv_demux_index **p_idx )
    1.66  {
    1.67 -		p_idx = g_new0( nuv_demux_index, 1 );
    1.68 -    p_idx->i_idx = 0;
    1.69 -    p_idx->i_idx_max = 0;
    1.70 -    p_idx->idx = g_new0( nuv_demux_index_entry, DEMUX_INDEX_SIZE_MAX );
    1.71 +	*p_idx = g_new0( nuv_demux_index, 1 );
    1.72 +	(*p_idx)->i_idx = 0;
    1.73 +	(*p_idx)->i_idx_max = 0;
    1.74  }
    1.75  
    1.76  static void 
    1.77 -gst_nuv_demux_index_clean( nuv_demux_index *p_idx )
    1.78 +gst_nuv_demux_index_clean( nuv_demux_index **p_idx )
    1.79  {
    1.80 -    if( p_idx->idx )
    1.81 -    {
    1.82 -        g_free( p_idx->idx );
    1.83 -    }
    1.84 +	if ( *p_idx != NULL ) {
    1.85 +		g_free( *p_idx );
    1.86 +		*p_idx = NULL;
    1.87 +	}
    1.88 +
    1.89  }
    1.90  
    1.91  static void 
    1.92  gst_nuv_demux_index_append( GstNuvDemux *nuv, gint64 i_time, gint64 i_offset )
    1.93  {
    1.94  	nuv_demux_index *p_idx = nuv->index_entries;
    1.95 -	
    1.96 -	if ( p_idx == NULL || p_idx->idx == NULL )
    1.97 +
    1.98 +	//if ( p_idx == NULL )
    1.99 +	//	return;
   1.100 +
   1.101 +	/* Be sure to append new entry (we don't insert point) */
   1.102 +	if( p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time )
   1.103  		return;
   1.104  
   1.105 -    /* Be sure to append new entry (we don't insert point) */
   1.106 -    if(  p_idx != NULL && p_idx->i_idx > 0 && p_idx->idx[p_idx->i_idx-1].i_time >= i_time )
   1.107 -        return;
   1.108 +	/* */
   1.109 +	if( p_idx->i_idx >= p_idx->i_idx_max )
   1.110 +	{
   1.111 +		if( p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX )
   1.112 +		{
   1.113 +			/* Avoid too big index */
   1.114 +			const gint64 i_length = p_idx->idx[p_idx->i_idx-1].i_time -
   1.115 +				p_idx->idx[0].i_time;
   1.116 +			const gint i_count = DEMUX_INDEX_SIZE_MAX/2;
   1.117 +			gint i, j;
   1.118  
   1.119 -    /* */
   1.120 -    if( p_idx->i_idx >= p_idx->i_idx_max )
   1.121 -    {
   1.122 -        if( p_idx->i_idx >= DEMUX_INDEX_SIZE_MAX )
   1.123 -        {
   1.124 -            /* Avoid too big index */
   1.125 -            const gint64 i_length = p_idx->idx[p_idx->i_idx-1].i_time -
   1.126 -                                                        p_idx->idx[0].i_time;
   1.127 -            const gint i_count = DEMUX_INDEX_SIZE_MAX/2;
   1.128 -            gint i, j;
   1.129 +			/* We try to reduce the resolution of the index by a factor 2 */
   1.130 +			for( i = 1, j = 1; i < p_idx->i_idx; i++ )
   1.131 +			{
   1.132 +				if( p_idx->idx[i].i_time < j * i_length / i_count )
   1.133 +					continue;
   1.134  
   1.135 -            /* We try to reduce the resolution of the index by a factor 2 */
   1.136 -            for( i = 1, j = 1; i < p_idx->i_idx; i++ )
   1.137 -            {
   1.138 -                if( p_idx->idx[i].i_time < j * i_length / i_count )
   1.139 -                    continue;
   1.140 +				p_idx->idx[j++] = p_idx->idx[i];
   1.141 +			}
   1.142 +			p_idx->i_idx = j;
   1.143  
   1.144 -                p_idx->idx[j++] = p_idx->idx[i];
   1.145 -            }
   1.146 -            p_idx->i_idx = j;
   1.147 +			if( p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4 )
   1.148 +			{
   1.149 +				/* We haven't created enough space
   1.150 +				 * (This method won't create a good index but work for sure) */
   1.151 +				for( i = 0; i < p_idx->i_idx/2; i++ )
   1.152 +					p_idx->idx[i] = p_idx->idx[2*i];
   1.153 +				p_idx->i_idx /= 2;
   1.154 +			}
   1.155 +		}
   1.156 +		else
   1.157 +		{
   1.158 +			p_idx->i_idx_max += 1000;
   1.159 +			//p_idx->idx = g_realloc( p_idx->idx,
   1.160 +					//p_idx->i_idx_max*sizeof(nuv_demux_index_entry));
   1.161 +		}
   1.162 +	}
   1.163  
   1.164 -            if( p_idx->i_idx > 3 * DEMUX_INDEX_SIZE_MAX / 4 )
   1.165 -            {
   1.166 -                /* We haven't created enough space
   1.167 -                 * (This method won't create a good index but work for sure) */
   1.168 -                for( i = 0; i < p_idx->i_idx/2; i++ )
   1.169 -                    p_idx->idx[i] = p_idx->idx[2*i];
   1.170 -                p_idx->i_idx /= 2;
   1.171 -            }
   1.172 -        }
   1.173 -        else
   1.174 -        {
   1.175 -            p_idx->i_idx_max += 1000;
   1.176 -            p_idx->idx = g_realloc( p_idx->idx,
   1.177 -                                  p_idx->i_idx_max*sizeof(nuv_demux_index_entry));
   1.178 -        }
   1.179 -    }
   1.180 +	/* */
   1.181 +	p_idx->idx[p_idx->i_idx].i_time = i_time;
   1.182 +	p_idx->idx[p_idx->i_idx].i_offset = i_offset;
   1.183  
   1.184 -    /* */
   1.185 -    p_idx->idx[p_idx->i_idx].i_time = i_time;
   1.186 -    p_idx->idx[p_idx->i_idx].i_offset = i_offset;
   1.187 -
   1.188 -    p_idx->i_idx++;
   1.189 +	p_idx->i_idx++;
   1.190  }
   1.191  
   1.192  static gint64 
   1.193  gst_nuv_demux_index_convert_time( GstNuvDemux *nuv, gint64 i_time )
   1.194  {
   1.195  	nuv_demux_index *p_idx = nuv->index_entries;
   1.196 -	
   1.197 -	g_return_val_if_fail( p_idx != NULL, i_time );
   1.198 -	
   1.199 -    gint i_min = 0;
   1.200 -    gint i_max = p_idx->i_idx-1;
   1.201  
   1.202 -    /* Empty index */
   1.203 -    if( p_idx->i_idx <= 0 )
   1.204 -        return -1;
   1.205 +	g_return_val_if_fail( p_idx != NULL , i_time );
   1.206  
   1.207 -    /* Special border case */
   1.208 -    if( i_time <= p_idx->idx[0].i_time )
   1.209 -        return p_idx->idx[0].i_offset;
   1.210 -    if( i_time >= p_idx->idx[i_max].i_time )
   1.211 -        return p_idx->idx[i_max].i_offset;
   1.212 +	gint i_min = 0;
   1.213 +	gint i_max = p_idx->i_idx-1;
   1.214  
   1.215 -    /* Dicho */
   1.216 -    for( ;; )
   1.217 -    {
   1.218 -        gint i_med;
   1.219 +	/* Empty index */
   1.220 +	if( p_idx->i_idx <= 0 )
   1.221 +		return -1;
   1.222  
   1.223 -        if( i_max - i_min <= 1 )
   1.224 -            break;
   1.225 +	/* Special border case */
   1.226 +	if( i_time <= p_idx->idx[0].i_time )
   1.227 +		return p_idx->idx[0].i_offset;
   1.228 +	if( i_time >= p_idx->idx[i_max].i_time )
   1.229 +		return p_idx->idx[i_max].i_offset;
   1.230  
   1.231 -        i_med = (i_min+i_max)/2;
   1.232 -        if( p_idx->idx[i_med].i_time < i_time )
   1.233 -            i_min = i_med;
   1.234 -        else if( p_idx->idx[i_med].i_time > i_time )
   1.235 -            i_max = i_med;
   1.236 -        else
   1.237 -            return p_idx->idx[i_med].i_offset;
   1.238 -    }
   1.239 +	/* Dicho */
   1.240 +	for( ;; )
   1.241 +	{
   1.242 +		gint i_med;
   1.243  
   1.244 -    /* return nearest in time */
   1.245 -    if( i_time - p_idx->idx[i_min].i_time < p_idx->idx[i_max].i_time - i_time )
   1.246 -        return p_idx->idx[i_min].i_offset;
   1.247 -    else
   1.248 -        return p_idx->idx[i_max].i_offset;
   1.249 +		if( i_max - i_min <= 1 )
   1.250 +			break;
   1.251 +
   1.252 +		i_med = (i_min+i_max)/2;
   1.253 +		if( p_idx->idx[i_med].i_time < i_time )
   1.254 +			i_min = i_med;
   1.255 +		else if( p_idx->idx[i_med].i_time > i_time )
   1.256 +			i_max = i_med;
   1.257 +		else
   1.258 +			return p_idx->idx[i_med].i_offset;
   1.259 +	}
   1.260 +
   1.261 +	/* return nearest in time */
   1.262 +	if( i_time - p_idx->idx[i_min].i_time < p_idx->idx[i_max].i_time - i_time )
   1.263 +		return p_idx->idx[i_min].i_offset;
   1.264 +	else
   1.265 +		return p_idx->idx[i_max].i_offset;
   1.266  }
   1.267  
   1.268  static gint64
   1.269  gst_nuv_demux_index_find_offset( GstNuvDemux *nuv, gint64 i_offset )
   1.270  {
   1.271  	nuv_demux_index *p_idx = nuv->index_entries;
   1.272 -	
   1.273 -	g_return_val_if_fail( p_idx != NULL, i_offset );
   1.274 -	
   1.275 -    gint i_min = 0;
   1.276 -    gint i_max = p_idx->i_idx-1;
   1.277  
   1.278 -    /* Empty index */
   1.279 -    if( p_idx->i_idx <= 0 )
   1.280 -        return -1;
   1.281 +	g_return_val_if_fail( p_idx != NULL && p_idx->idx != NULL, i_offset );
   1.282  
   1.283 -    /* Special border case */
   1.284 -    if( i_offset <= p_idx->idx[0].i_offset )
   1.285 -        return p_idx->idx[0].i_offset;
   1.286 -    if( i_offset == p_idx->idx[i_max].i_offset )
   1.287 -        return p_idx->idx[i_max].i_offset;
   1.288 -    if( i_offset > p_idx->idx[i_max].i_offset )
   1.289 -        return -1;
   1.290 +	gint i_min = 0;
   1.291 +	gint i_max = p_idx->i_idx-1;
   1.292  
   1.293 -    /* Dicho */
   1.294 -    for( ;; )
   1.295 -    {
   1.296 -        gint i_med;
   1.297 +	/* Empty index */
   1.298 +	if( p_idx->i_idx <= 0 )
   1.299 +		return -1;
   1.300  
   1.301 -        if ( i_max - i_min <= 1 )
   1.302 -            break;
   1.303 +	/* Special border case */
   1.304 +	if( i_offset <= p_idx->idx[0].i_offset )
   1.305 +		return p_idx->idx[0].i_offset;
   1.306 +	if( i_offset == p_idx->idx[i_max].i_offset )
   1.307 +		return p_idx->idx[i_max].i_offset;
   1.308 +	if( i_offset > p_idx->idx[i_max].i_offset )
   1.309 +		return -1;
   1.310  
   1.311 -        i_med = (i_min+i_max)/2;
   1.312 -        if( p_idx->idx[i_med].i_offset < i_offset )
   1.313 -            i_min = i_med;
   1.314 -        else if( p_idx->idx[i_med].i_offset > i_offset )
   1.315 -            i_max = i_med;
   1.316 -        else
   1.317 -            return p_idx->idx[i_med].i_offset;
   1.318 -    }
   1.319 +	/* Dicho */
   1.320 +	for( ;; )
   1.321 +	{
   1.322 +		gint i_med;
   1.323  
   1.324 -    /* return nearest */
   1.325 -    if( i_offset - p_idx->idx[i_min].i_offset < p_idx->idx[i_max].i_offset - i_offset )
   1.326 -        return p_idx->idx[i_min].i_offset;
   1.327 -    else
   1.328 -        return p_idx->idx[i_max].i_offset;
   1.329 +		if ( i_max - i_min <= 1 )
   1.330 +			break;
   1.331 +
   1.332 +		i_med = (i_min+i_max)/2;
   1.333 +		if( p_idx->idx[i_med].i_offset < i_offset )
   1.334 +			i_min = i_med;
   1.335 +		else if( p_idx->idx[i_med].i_offset > i_offset )
   1.336 +			i_max = i_med;
   1.337 +		else
   1.338 +			return p_idx->idx[i_med].i_offset;
   1.339 +	}
   1.340 +
   1.341 +	/* return nearest */
   1.342 +	if( i_offset - p_idx->idx[i_min].i_offset < p_idx->idx[i_max].i_offset - i_offset )
   1.343 +		return p_idx->idx[i_min].i_offset;
   1.344 +	else
   1.345 +		return p_idx->idx[i_max].i_offset;
   1.346  }
   1.347  
   1.348  /*****************************************************************************
   1.349 @@ -524,7 +514,9 @@
   1.350    h->i_keyframe = data[2];
   1.351    h->i_filters = data[3];
   1.352  
   1.353 -  h->i_timecode = gst_nuv_demux_getdwle( &data[4] ); //GST_READ_UINT32_LE (&data[4]);
   1.354 +  h->i_timecode = GST_READ_UINT32_LE (&data[4]);
   1.355 +
   1.356 +
   1.357    h->i_length = GST_READ_UINT32_LE (&data[8]);
   1.358    GST_DEBUG_OBJECT (nuv, "frame hdr: t=%c c=%c k=%d f=0x%x timecode=%d l=%d",
   1.359        h->i_type,
   1.360 @@ -677,26 +669,26 @@
   1.361    if (h->i_type == 'R')
   1.362      goto done;
   1.363      
   1.364 -	/* append the frame's header timecode field, and the actual offset */
   1.365 +   /* append the frame's header timecode field, and the actual offset */
   1.366    gst_nuv_demux_index_append( nuv, h->i_timecode, nuv->offset );
   1.367 -  
   1.368 + 
   1.369    if (h->i_length > 0) {
   1.370 -    ret = gst_nuv_demux_read_bytes (nuv, h->i_length, TRUE, &buf);
   1.371 -    if (ret != GST_FLOW_OK)
   1.372 -      return ret;
   1.373 -      
   1.374 -    /* search for a valid timecode in the indexes list (find the nearest valid timecode) */
   1.375 +	  ret = gst_nuv_demux_read_bytes (nuv, h->i_length, TRUE, &buf);
   1.376 +	  if (ret != GST_FLOW_OK)
   1.377 +		  return ret;
   1.378 +
   1.379 +	  /* search for a valid timecode in the indexes list (find the nearest valid timecode) */
   1.380  	  if ( h->i_timecode < 0 ) {
   1.381 -	  	/* convert this actual timecode to a valid index in the timecode's table */
   1.382 +		  /* convert this actual timecode to a valid index in the timecode's table */
   1.383  		  gint64 pos = gst_nuv_demux_index_convert_time( nuv, h->i_timecode );
   1.384 -		  
   1.385 +
   1.386  		  /* find the nearest empty frame slot */		  
   1.387  		  gint64 near_off = gst_nuv_demux_index_find_offset( nuv, pos );
   1.388 -		  
   1.389 +
   1.390  		  /* just get the timecode from the timecode's table */		  
   1.391  		  GST_BUFFER_TIMESTAMP (buf) = nuv->index_entries->idx[near_off].i_time * GST_MSECOND;
   1.392  	  } else {  
   1.393 -	  	GST_BUFFER_TIMESTAMP (buf) = h->i_timecode * GST_MSECOND;
   1.394 +		  GST_BUFFER_TIMESTAMP (buf) = h->i_timecode * GST_MSECOND;
   1.395  	  }
   1.396    }
   1.397