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