[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