diff -r 24be83eaef89 -r 3f9efc6c27bd gst-plugins-nuvdemux/src/gstnuvdemux.c --- a/gst-plugins-nuvdemux/src/gstnuvdemux.c Thu Oct 26 18:55:14 2006 +0100 +++ b/gst-plugins-nuvdemux/src/gstnuvdemux.c Fri Oct 27 00:13:07 2006 +0100 @@ -52,6 +52,8 @@ #include #include +#define GETTEXT_PACKAGE "gst-plugins-nuvdemux-0.10.3" + #include "gst/gst-i18n-plugin.h" #include "gstnuvdemux.h" @@ -88,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 void gst_nuv_demux_index_init( nuv_demux_index **p_idx ); +static void gst_nuv_demux_index_clean( nuv_demux_index **p_idx ); /* NUV Demux indexes manipulation functions */ static gint64 gst_nuv_demux_index_find_offset( GstNuvDemux *nuv, gint64 i_offset ); @@ -137,18 +139,6 @@ #define READ_DOUBLE_FROM_LE(d) *((gdouble* ) (d)) #endif /* G_BYTE_ORDER != G_BIG_ENDIAN */ -static gint32 -gst_nuv_demux_getdwle (void const * _p) -{ - guint8 * p = (guint8 *)_p; - g_print( "[%s] shifting bits: {%d, %d, %d, %d}\n", __FUNCTION__, - ((guint32)p[3] << 24), ((guint32)p[2] << 16), - ((guint32)p[1] << 8), p[0] ); - return ( ((guint32)p[3] << 24) | ((guint32)p[2] << 16) - | ((guint32)p[1] << 8) | p[0] ); - //return ( (gint)p[3] | (gint)p[2] | (gint)p[1] | p[0] ); -} - static void gst_nuv_demux_base_init (gpointer klass) { @@ -197,7 +187,7 @@ gst_element_add_pad (GST_ELEMENT (nuv), nuv->sinkpad); - gst_nuv_demux_index_init( nuv->index_entries ); + gst_nuv_demux_index_init( &nuv->index_entries ); nuv->adapter = NULL; nuv->mpeg_buffer = NULL; @@ -217,7 +207,7 @@ } if ( nuv->index_entries != NULL ) { - gst_nuv_demux_index_clean( nuv->index_entries ); + gst_nuv_demux_index_clean( &nuv->index_entries ); nuv->index_entries = NULL; } @@ -235,168 +225,168 @@ *****************************************************************************/ static void -gst_nuv_demux_index_init( nuv_demux_index *p_idx ) +gst_nuv_demux_index_init( nuv_demux_index **p_idx ) { - p_idx = g_new0( nuv_demux_index, 1 ); - p_idx->i_idx = 0; - p_idx->i_idx_max = 0; - p_idx->idx = g_new0( nuv_demux_index_entry, DEMUX_INDEX_SIZE_MAX ); + *p_idx = g_new0( nuv_demux_index, 1 ); + (*p_idx)->i_idx = 0; + (*p_idx)->i_idx_max = 0; } static void -gst_nuv_demux_index_clean( nuv_demux_index *p_idx ) +gst_nuv_demux_index_clean( nuv_demux_index **p_idx ) { - if( p_idx->idx ) - { - g_free( p_idx->idx ); - } + if ( *p_idx != NULL ) { + g_free( *p_idx ); + *p_idx = NULL; + } + } static void gst_nuv_demux_index_append( GstNuvDemux *nuv, gint64 i_time, gint64 i_offset ) { nuv_demux_index *p_idx = nuv->index_entries; - - if ( p_idx == NULL || p_idx->idx == NULL ) + + //if ( p_idx == NULL ) + // 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 ) 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 ) - return; + /* */ + if( p_idx->i_idx >= p_idx->i_idx_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 - + p_idx->idx[0].i_time; + const gint i_count = DEMUX_INDEX_SIZE_MAX/2; + gint i, j; - /* */ - if( p_idx->i_idx >= p_idx->i_idx_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 - - p_idx->idx[0].i_time; - const gint i_count = DEMUX_INDEX_SIZE_MAX/2; - 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++ ) + { + if( p_idx->idx[i].i_time < j * i_length / i_count ) + continue; - /* We try to reduce the resolution of the index by a factor 2 */ - for( i = 1, j = 1; i < p_idx->i_idx; i++ ) - { - 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; - p_idx->idx[j++] = p_idx->idx[i]; - } - p_idx->i_idx = j; + 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++ ) + p_idx->idx[i] = p_idx->idx[2*i]; + p_idx->i_idx /= 2; + } + } + 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)); + } + } - 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++ ) - p_idx->idx[i] = p_idx->idx[2*i]; - p_idx->i_idx /= 2; - } - } - 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[p_idx->i_idx].i_time = i_time; + p_idx->idx[p_idx->i_idx].i_offset = i_offset; - /* */ - p_idx->idx[p_idx->i_idx].i_time = i_time; - p_idx->idx[p_idx->i_idx].i_offset = i_offset; - - p_idx->i_idx++; + p_idx->i_idx++; } static gint64 gst_nuv_demux_index_convert_time( GstNuvDemux *nuv, gint64 i_time ) { nuv_demux_index *p_idx = nuv->index_entries; - - g_return_val_if_fail( p_idx != NULL, i_time ); - - gint i_min = 0; - gint i_max = p_idx->i_idx-1; - /* Empty index */ - if( p_idx->i_idx <= 0 ) - return -1; + g_return_val_if_fail( p_idx != NULL , i_time ); - /* Special border case */ - if( i_time <= p_idx->idx[0].i_time ) - return p_idx->idx[0].i_offset; - if( i_time >= p_idx->idx[i_max].i_time ) - return p_idx->idx[i_max].i_offset; + gint i_min = 0; + gint i_max = p_idx->i_idx-1; - /* Dicho */ - for( ;; ) - { - gint i_med; + /* Empty index */ + if( p_idx->i_idx <= 0 ) + return -1; - if( i_max - i_min <= 1 ) - break; + /* Special border case */ + if( i_time <= p_idx->idx[0].i_time ) + return p_idx->idx[0].i_offset; + if( i_time >= p_idx->idx[i_max].i_time ) + return p_idx->idx[i_max].i_offset; - i_med = (i_min+i_max)/2; - if( p_idx->idx[i_med].i_time < i_time ) - i_min = i_med; - else if( p_idx->idx[i_med].i_time > i_time ) - i_max = i_med; - else - return p_idx->idx[i_med].i_offset; - } + /* Dicho */ + for( ;; ) + { + gint i_med; - /* return nearest in time */ - if( i_time - p_idx->idx[i_min].i_time < p_idx->idx[i_max].i_time - i_time ) - return p_idx->idx[i_min].i_offset; - else - return p_idx->idx[i_max].i_offset; + if( i_max - i_min <= 1 ) + break; + + i_med = (i_min+i_max)/2; + if( p_idx->idx[i_med].i_time < i_time ) + i_min = i_med; + else if( p_idx->idx[i_med].i_time > i_time ) + i_max = i_med; + else + return p_idx->idx[i_med].i_offset; + } + + /* return nearest in time */ + if( i_time - p_idx->idx[i_min].i_time < p_idx->idx[i_max].i_time - i_time ) + return p_idx->idx[i_min].i_offset; + else + return p_idx->idx[i_max].i_offset; } static gint64 gst_nuv_demux_index_find_offset( GstNuvDemux *nuv, gint64 i_offset ) { nuv_demux_index *p_idx = nuv->index_entries; - - g_return_val_if_fail( p_idx != NULL, i_offset ); - - gint i_min = 0; - gint i_max = p_idx->i_idx-1; - /* Empty index */ - if( p_idx->i_idx <= 0 ) - return -1; + g_return_val_if_fail( p_idx != NULL && p_idx->idx != NULL, i_offset ); - /* Special border case */ - if( i_offset <= p_idx->idx[0].i_offset ) - return p_idx->idx[0].i_offset; - if( i_offset == p_idx->idx[i_max].i_offset ) - return p_idx->idx[i_max].i_offset; - if( i_offset > p_idx->idx[i_max].i_offset ) - return -1; + gint i_min = 0; + gint i_max = p_idx->i_idx-1; - /* Dicho */ - for( ;; ) - { - gint i_med; + /* Empty index */ + if( p_idx->i_idx <= 0 ) + return -1; - if ( i_max - i_min <= 1 ) - break; + /* Special border case */ + if( i_offset <= p_idx->idx[0].i_offset ) + return p_idx->idx[0].i_offset; + if( i_offset == p_idx->idx[i_max].i_offset ) + return p_idx->idx[i_max].i_offset; + if( i_offset > p_idx->idx[i_max].i_offset ) + return -1; - i_med = (i_min+i_max)/2; - if( p_idx->idx[i_med].i_offset < i_offset ) - i_min = i_med; - else if( p_idx->idx[i_med].i_offset > i_offset ) - i_max = i_med; - else - return p_idx->idx[i_med].i_offset; - } + /* Dicho */ + for( ;; ) + { + gint i_med; - /* return nearest */ - if( i_offset - p_idx->idx[i_min].i_offset < p_idx->idx[i_max].i_offset - i_offset ) - return p_idx->idx[i_min].i_offset; - else - return p_idx->idx[i_max].i_offset; + if ( i_max - i_min <= 1 ) + break; + + i_med = (i_min+i_max)/2; + if( p_idx->idx[i_med].i_offset < i_offset ) + i_min = i_med; + else if( p_idx->idx[i_med].i_offset > i_offset ) + i_max = i_med; + else + return p_idx->idx[i_med].i_offset; + } + + /* return nearest */ + if( i_offset - p_idx->idx[i_min].i_offset < p_idx->idx[i_max].i_offset - i_offset ) + return p_idx->idx[i_min].i_offset; + else + return p_idx->idx[i_max].i_offset; } /***************************************************************************** @@ -524,7 +514,9 @@ h->i_keyframe = data[2]; h->i_filters = data[3]; - h->i_timecode = gst_nuv_demux_getdwle( &data[4] ); //GST_READ_UINT32_LE (&data[4]); + h->i_timecode = GST_READ_UINT32_LE (&data[4]); + + h->i_length = GST_READ_UINT32_LE (&data[8]); GST_DEBUG_OBJECT (nuv, "frame hdr: t=%c c=%c k=%d f=0x%x timecode=%d l=%d", h->i_type, @@ -677,26 +669,26 @@ if (h->i_type == 'R') goto done; - /* append the frame's header timecode field, and the actual offset */ + /* append the frame's header timecode field, and the actual offset */ gst_nuv_demux_index_append( nuv, h->i_timecode, nuv->offset ); - + if (h->i_length > 0) { - ret = gst_nuv_demux_read_bytes (nuv, h->i_length, TRUE, &buf); - if (ret != GST_FLOW_OK) - return ret; - - /* search for a valid timecode in the indexes list (find the nearest valid timecode) */ + ret = gst_nuv_demux_read_bytes (nuv, h->i_length, TRUE, &buf); + if (ret != GST_FLOW_OK) + return ret; + + /* 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 */ + /* 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 ); - + /* find the nearest empty frame slot */ 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 { - GST_BUFFER_TIMESTAMP (buf) = h->i_timecode * GST_MSECOND; + GST_BUFFER_TIMESTAMP (buf) = h->i_timecode * GST_MSECOND; } }