[vlc-devel] [Patch] Correctly fill out input_item's es info, and slim down input_item_es_t.
Laurent Aimar
fenrir at via.ecp.fr
Tue Feb 23 21:02:11 CET 2010
Hi,
On Mon, Feb 22, 2010, Pierre d'Herbemont wrote:
> Hey,
> Please review the attached patch.
> I consider it important because it properly fix libvlc_media_get_es(). We
> are currently advising our poor user to create a new media_player with
> --sout=#description which makes us look overcomplicated. Mostly because
> you still have to attach an event and such to know when we are done, and
> also because a full playback is launched, not saving CPU and memory.
> Our alternative to this patch is to read the input_item's info dictionary.
> And parse the string in it. Hence the modification stay in libvlc umbrella
> and not in the core.
> However I consider this patch as low risk:
> - It is following how we fill the input_item's info which is an already
> existing string dictionary.
> - Its impact in term of performance is low. We are not using a full
> es_format_t, but just a stripped down version of fixed size, which is what
> we expose in libvlc_media.
> - It's chirugical and circumvented.
> - It's fixing a real issue in libvlc.
Well, it's adding a feature not fixing an issue (I don't say that it's not a
wanted one).
> If it's not accepted I'll fix libvlc_media_get_es() in 1.1 by parsing
> input_item's info field, which are correctly filled after preparsing for
> most demuxer. I am ok with this, but wanted to get the patch archived on
> the ML at least.
Except the following remarks, I am ok with the way it is implemented.
> diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h
> index d4858c9..1e10acd 100644
> --- a/include/vlc_input_item.h
> +++ b/include/vlc_input_item.h
> @@ -51,6 +51,44 @@ 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_es_t {
Usually useless to name the struct part.
> + vlc_fourcc_t i_codec;
> + int i_id;
> + int i_cat; /* @see es_format_category_e */
> +
> + /* Codec specific */
> + int i_profile;
> + int i_level;
> +
> + /* Audio specific */
> + unsigned i_channels;
> + unsigned i_rate;
> +
> + /* Video specific */
> + unsigned i_height;
> + unsigned i_width;
A union between video and audio type will save memory and allows to know
which fields cannot be used together, maybe somehting like:
union
{
struct
{
unsigned i_width;
unsigned i_height;
} video;
struct
{
unsigned i_channels;
unsigned i_rate;
} audio;
} u;
> +} input_item_es_t;
> +
> +static inline input_item_es_t *input_item_es_new_from_format(const es_format_t *fmt)
input_item_es_NewFromFormat to be consistant.
> +{
> + input_item_es_t *ret = (input_item_es_t *)malloc(sizeof(input_item_es_t));
malloc(*ret) is safer.
> + 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;
> +
> + ret->i_channels = fmt->audio.i_channels;
> + ret->i_rate = fmt->audio.i_rate;
> +
> + ret->i_height = fmt->video.i_height;
> + ret->i_width = fmt->video.i_width;
> + return ret;
> +}
I think the function should be moved to src/input/item.c as it is not speed critical.
> struct input_item_t
> {
> VLC_GC_MEMBERS
> diff --git a/src/input/es_out.c b/src/input/es_out.c
> index 3062d8e..c2fb21d 100644
> --- a/src/input/es_out.c
> +++ b/src/input/es_out.c
> @@ -2223,7 +2223,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
> }
> return VLC_SUCCESS;
> }
> -
> +
Cosmetic.
> case ES_OUT_SET_ES_DEFAULT:
> {
> es_out_id_t *es = va_arg( args, es_out_id_t * );
> @@ -2811,6 +2811,31 @@ 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 input item */
> + input_item_t *item = p_input->p->p_item;
I would prefer input_GetItem() as I plan to remove as much as p_input->p accesses as possible.
> + vlc_mutex_lock( &item->lock );
> + bool found = false;
> +
> + input_item_es_t *input_item_fmt = input_item_es_new_from_format(fmt);
> +
> + for( int i = 0; i < item->i_es; i++ )
> + {
> + if (item->es[i]->i_id == es->i_id)
> + {
> + /* We've found the right ES, replace it */
> + free(item->es[i]);
> + item->es[i] = input_item_fmt;
> + found = true;
> + break;
> + }
> + }
> + if( !found )
> + {
> + /* ES not found, create a new one. */
> + TAB_APPEND(item->i_es, item->es, input_item_fmt);
> + }
> + vlc_mutex_unlock( &item->lock );
> +
Creating an helper (input_item_UpdateEs or something like that) in item.c is
cleaner than putting the code in es_out.
Also, current item->es is not of the right type as it is a es_format_t (I haven't
saw any change to it). Changing the type of item->es will make #describe unusable,
so either we need to add new fields to input_item_t or breaks the VLM VoD part.
Btw, you also need to clean up the array when destructing the input_item_t.
Regards,
--
fenrir
More information about the vlc-devel
mailing list