[vlc-commits] commit: input: Fill in the input_item es. (Pierre d'Herbemont )

git at videolan.org git at videolan.org
Wed Jul 14 20:41:53 CEST 2010


vlc/vlc-1.1 | branch: master | Pierre d'Herbemont <pdherbemont at free.fr> | Mon Feb 22 17:20:27 2010 +0100| [91d9a74630aa4ff9baaca6830887fd39c1141277] | committer: Pierre d'Herbemont 

input: Fill in the input_item es.

Instead of using es_format_t we use a custom structure to limit the memory footprint.
This allow libvlc_media_get_es() to properly work after libvlc_media_parse().

> http://git.videolan.org/gitweb.cgi/vlc/vlc-1.1.git/?a=commit;h=91d9a74630aa4ff9baaca6830887fd39c1141277
---

 include/vlc/libvlc_media.h |   21 ++++---------
 include/vlc_input_item.h   |   32 +++++++++++++++++++++
 src/control/media.c        |   34 +++++++++++-----------
 src/input/es_out.c         |    6 +++-
 src/input/item.c           |   67 ++++++++++++++++++++++++++++++++++++++++++++
 src/input/item.h           |    1 +
 6 files changed, 129 insertions(+), 32 deletions(-)

diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h
index 52de810..56bb3d2 100644
--- a/include/vlc/libvlc_media.h
+++ b/include/vlc/libvlc_media.h
@@ -453,20 +453,13 @@ VLC_PUBLIC_API void *
 /**
  * Get media descriptor's elementary streams description
  *
- * Note, you need to play the media _one_ time with --sout="#description"
- * Not doing this will result in an empty array, and doing it more than once
- * will duplicate the entries in the array each time. Something like this:
- *
- * @begincode
- * libvlc_media_player_t *player = libvlc_media_player_new_from_media(media);
- * libvlc_media_add_option_flag(media, "sout=\"#description\"");
- * libvlc_media_player_play(player);
- * // ... wait until playing
- * libvlc_media_player_release(player);
- * @endcode
- *
- * This is very likely to change in next release, and be done at the parsing
- * phase.
+ * This is especially useful for getting codec information
+ * bitrate, size...
+ *
+ * Note, you need to parse the media first.
+ *
+ * \see libvlc_media_parse
+ * \see libvlc_media_track_info_t
  *
  * \param media media descriptor object
  * \param tracks address to store an allocated array of Elementary Streams
diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h
index ca11d09..99efe89 100644
--- a/include/vlc_input_item.h
+++ b/include/vlc_input_item.h
@@ -51,6 +51,35 @@ struct info_category_t
     struct info_t **pp_infos;     /**< Pointer to an array of infos */
 };
 
+/* Stripped down version of es_format_t because es_format_t can become very
+ * large in term of memory. This is mostly libvlc_media_es_t */
+typedef struct input_item_track_t
+{
+    vlc_fourcc_t i_codec;
+    int          i_id;
+    int          i_cat; /* @see es_format_category_e */
+
+    /* Codec specific */
+    int         i_profile;
+    int         i_level;
+
+    union
+    {
+        struct
+        {
+            /* Video specific */
+            unsigned    i_height;
+            unsigned    i_width;
+        } video;
+        struct
+        {
+            /* Audio specific */
+            unsigned    i_channels;
+            unsigned    i_rate;
+        } audio;
+    } u;
+} input_item_track_t;
+
 struct input_item_t
 {
     VLC_GC_MEMBERS
@@ -73,6 +102,9 @@ struct input_item_t
     int         i_es;                /**< Number of es format descriptions */
     es_format_t **es;                /**< Es formats */
 
+    int i_tracks;                    /**< Number of track info descriptions */
+    input_item_track_t **tracks;     /**< Tracks Info */
+
     input_stats_t *p_stats;          /**< Statistics */
     int           i_nb_played;       /**< Number of times played */
 
diff --git a/src/control/media.c b/src/control/media.c
index 3fad99e..f3cb444 100644
--- a/src/control/media.c
+++ b/src/control/media.c
@@ -681,35 +681,35 @@ libvlc_media_get_user_data( libvlc_media_t * p_md )
  * Get media descriptor's elementary streams description
  **************************************************************************/
 int
-libvlc_media_get_tracks_info( libvlc_media_t *p_md, libvlc_media_track_info_t ** pp_es )
+libvlc_media_get_tracks_info( libvlc_media_t *p_md, libvlc_media_track_info_t ** pp_tracks )
 {
     assert( p_md );
 
     input_item_t *p_input_item = p_md->p_input_item;
     vlc_mutex_lock( &p_input_item->lock );
 
-    const int i_es = p_input_item->i_es;
-    *pp_es = (i_es > 0) ? malloc( i_es * sizeof(libvlc_media_track_info_t) ) : NULL;
+    const int i_tracks = p_input_item->i_tracks;
+    *pp_tracks = (i_tracks > 0) ? malloc( i_tracks * sizeof(libvlc_media_track_info_t) ) : NULL;
 
-    if( !pp_es ) /* no ES, or OOM */
+    if( !pp_tracks ) /* no ES, or OOM */
     {
         vlc_mutex_unlock( &p_input_item->lock );
         return 0;
     }
 
     /* Fill array */
-    for( int i = 0; i < i_es; i++ )
+    for( int i = 0; i < i_tracks; i++ )
     {
-        libvlc_media_track_info_t *p_mes = *pp_es+i;
-        const es_format_t *p_es = p_input_item->es[i];
+        libvlc_media_track_info_t *p_mes = *pp_tracks+i;
+        const es_format_t *p_tracks = p_input_item->tracks[i];
 
-        p_mes->i_codec = p_es->i_codec;
-        p_mes->i_id = p_es->i_id;
+        p_mes->i_codec = p_track->i_codec;
+        p_mes->i_id = p_track->i_id;
 
-        p_mes->i_profile = p_es->i_profile;
-        p_mes->i_level = p_es->i_level;
+        p_mes->i_profile = p_track->i_profile;
+        p_mes->i_level = p_track->i_level;
 
-        switch(p_es->i_cat)
+        switch(p_track->i_cat)
         {
         case UNKNOWN_ES:
         default:
@@ -717,13 +717,13 @@ libvlc_media_get_tracks_info( libvlc_media_t *p_md, libvlc_media_track_info_t **
             break;
         case VIDEO_ES:
             p_mes->i_type = libvlc_track_video;
-            p_mes->u.video.i_height = p_es->video.i_height;
-            p_mes->u.video.i_width = p_es->video.i_width;
+            p_mes->u.video.i_height = p_track->video.i_height;
+            p_mes->u.video.i_width = p_track->video.i_width;
             break;
         case AUDIO_ES:
             p_mes->i_type = libvlc_track_audio;
-            p_mes->u.audio.i_channels = p_es->audio.i_channels;
-            p_mes->u.audio.i_rate = p_es->audio.i_rate;
+            p_mes->u.audio.i_channels = p_track->audio.i_channels;
+            p_mes->u.audio.i_rate = p_track->audio.i_rate;
             break;
         case SPU_ES:
             p_mes->i_type = libvlc_track_text;
@@ -732,5 +732,5 @@ libvlc_media_get_tracks_info( libvlc_media_t *p_md, libvlc_media_track_info_t **
     }
 
     vlc_mutex_unlock( &p_input_item->lock );
-    return i_es;
+    return i_tracks;
 }
diff --git a/src/input/es_out.c b/src/input/es_out.c
index a45f021..38bbfa2 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -45,6 +45,7 @@
 #include "es_out.h"
 #include "event.h"
 #include "info.h"
+#include "item.h"
 
 #include "../stream_output/stream_output.h"
 
@@ -2255,7 +2256,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
             }
             return VLC_SUCCESS;
         }
- 
+
         case ES_OUT_SET_ES_DEFAULT:
         {
             es_out_id_t *es = va_arg( args, es_out_id_t * );
@@ -2855,6 +2856,9 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t *
     const es_format_t *p_fmt_es = &es->fmt;
     lldiv_t         div;
 
+    /* Update the item tracks field */
+    input_item_UpdateTrack(input_GetItem(p_input), fmt);
+
     /* Create category */
     char psz_cat[128];
     snprintf( psz_cat, sizeof(psz_cat),_("Stream %d"), es->i_meta_id );
diff --git a/src/input/item.c b/src/input/item.c
index df4e159..12d5ff2 100644
--- a/src/input/item.c
+++ b/src/input/item.c
@@ -36,6 +36,7 @@
 #include "info.h"
 
 static int GuessType( const input_item_t *p_item );
+static void input_item_track_Delete(input_item_track_t *track);
 
 /** Stuff moved out of vlc_input.h -- FIXME: should probably not be inline
  * anyway. */
@@ -46,6 +47,7 @@ static inline void input_item_Init( vlc_object_t *p_o, input_item_t *p_i )
     p_i->psz_name = NULL;
     p_i->psz_uri = NULL;
     TAB_INIT( p_i->i_es, p_i->es );
+    TAB_INIT( p_i->i_tracks, p_i->tracks );
     TAB_INIT( p_i->i_options, p_i->ppsz_options );
     p_i->optflagv = NULL, p_i->optflagc = 0;
     TAB_INIT( p_i->i_categories, p_i->pp_categories );
@@ -99,6 +101,10 @@ static inline void input_item_Clean( input_item_t *p_i )
     }
     TAB_CLEAN( p_i->i_es, p_i->es );
 
+    for( i = 0; i < p_i->i_tracks; i++ )
+        input_item_track_Delete( p_i->tracks[i] );
+    TAB_CLEAN( p_i->tracks, p_i->tracks );
+
     for( i = 0; i < p_i->i_epg; i++ )
         vlc_epg_Delete( p_i->pp_epg[i] );
     TAB_CLEAN( p_i->i_epg, p_i->pp_epg );
@@ -1047,3 +1053,64 @@ void input_item_node_PostAndDelete( input_item_node_t *p_root )
 
   input_item_node_Delete( p_root );
 }
+
+/*
+ * Item tracks_info
+ */
+static input_item_track_t *input_item_track_NewFromESFormat(const es_format_t *fmt)
+{
+    input_item_track_t *ret = malloc(sizeof(*ret));
+    ret->i_codec = fmt->i_codec;
+    ret->i_id = fmt->i_id;
+    ret->i_cat = fmt->i_cat;
+
+    ret->i_profile = fmt->i_profile;
+    ret->i_level = fmt->i_level;
+
+    switch(fmt->i_cat)
+    {
+    case VIDEO_ES:
+        ret->u.video.i_height = fmt->video.i_height;
+        ret->u.video.i_width = fmt->video.i_width;
+        break;
+    case AUDIO_ES:
+        ret->u.audio.i_channels = fmt->audio.i_channels;
+        ret->u.audio.i_rate = fmt->audio.i_rate;
+        break;
+    default:
+        break;
+    }
+    return ret;
+}
+
+static void input_item_track_Delete(input_item_track_t *track)
+{
+    free(track);
+}
+
+/* Called by es_out when a new Elementary Stream is added or updated. */
+void input_item_UpdateTrack(input_item_t *item, const es_format_t *fmt)
+{
+    input_item_track_t *track = input_item_track_NewFromESFormat( fmt );
+    if( !track )
+        return;
+
+    vlc_mutex_lock( &item->lock );
+
+    for( int i = 0; i < item->i_tracks; i++ )
+    {
+        if( item->tracks[i]->i_id == track->i_id )
+        {
+            /* We've found the right ES, replace it */
+            input_item_track_Delete( item->tracks[i] );
+            item->tracks[i] = track;
+            vlc_mutex_unlock( &item->lock );
+            return;
+        }
+    }
+
+    /* ES not found, create a new one. */
+    TAB_APPEND(item->i_tracks, item->tracks, track);
+
+    vlc_mutex_unlock( &item->lock );
+}
diff --git a/src/input/item.h b/src/input/item.h
index 971620a..e09a765 100644
--- a/src/input/item.h
+++ b/src/input/item.h
@@ -31,5 +31,6 @@
 #include "input_interface.h"
 
 void input_item_SetErrorWhenReading( input_item_t *p_i, bool b_error );
+void input_item_UpdateTrack( input_item_t *item, const es_format_t *fmt );
 
 #endif



More information about the vlc-commits mailing list