[vlc-devel] [PATCH/RFC] libvlc: add language and frame rate to

Rémi Denis-Courmont remi at remlab.net
Mon Feb 4 20:27:07 CET 2013


Le lundi 4 février 2013 21:18:36, Jean-Baptiste Kempf a écrit :
> Le 09/10/2012 16:34, Rafaël Carré a écrit :
> > ---
> > Suggestions on how to implement this?
> 
> I am trying :D

diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h
index 7e61039..19d12a4 100644
--- a/include/vlc/libvlc_media.h
+++ b/include/vlc/libvlc_media.h
@@ -170,6 +170,45 @@ typedef struct libvlc_media_track_info_t
 } libvlc_media_track_info_t;
 
 
+typedef struct libvlc_media_track_info_2_t
+{
+    /* Codec fourcc */
+    uint32_t    i_codec;
+    int         i_id;
+    libvlc_track_type_t i_type;
+
+    /* Codec specific */
+    int         i_profile;
+    int         i_level;

Maybe add original codec too?

+
+    union {
+        struct {
+            /* Audio specific */
+            unsigned    i_channels;
+            unsigned    i_rate;
+        } audio;
+        struct {
+            /* Video specific */
+            unsigned    i_height;
+            unsigned    i_width;
+            unsigned    i_sar_num;
+            unsigned    i_sar_den;
+            float       f_frame_rate;
+        } video;
+        struct {
+            char *psz_encoding;
+        } subtitle;
+    } u;

Is this needed? I think recent C allows anonymous unions.

+
+    unsigned int i_bitrate;
+    char *psz_language;
+    char *psz_description;
+
+    void *reserved;
+
+} libvlc_media_track_info_2_t;

Hmm, I think the convention is not to have underscore before 2. Bit maybe just 
libvlc_media_track_t...

+
+
 /**
  * Create a media with a certain given media resource location,
  * for instance a valid URL.
@@ -512,6 +551,21 @@ LIBVLC_API void *libvlc_media_get_user_data( 
libvlc_media_t *p_md );
 LIBVLC_API
 int libvlc_media_get_tracks_info( libvlc_media_t *p_md,
                                   libvlc_media_track_info_t **tracks );
+LIBVLC_API
+int libvlc_media_get_tracks_info_2( libvlc_media_t *p_md,
+                                  libvlc_media_track_info_2_t **tracks );

Please NOOO. This reproduces the exact same extensibility problem.

+
+
+/**
+ * Release media descriptor's elementary streams description array
+ *
+ * \param p_tracks tracks info array to release
+ * \param i_count number of elements in the array
+ */
+LIBVLC_API
+void libvlc_media_tracks_info_release( libvlc_media_track_info_2_t *p_tracks,
+                                       int i_count );
+
 
 /** @}*/
 
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 42dad5c..2d2b688 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -72,6 +72,7 @@ libvlc_media_get_state
 libvlc_media_get_stats
 libvlc_media_get_user_data
 libvlc_media_get_tracks_info
+libvlc_media_get_tracks_info_2
 libvlc_media_is_parsed
 libvlc_media_library_load
 libvlc_media_library_media_list
@@ -168,6 +169,7 @@ libvlc_media_set_meta
 libvlc_media_set_state
 libvlc_media_set_user_data
 libvlc_media_subitems
+libvlc_media_tracks_info_release
 libvlc_new
 libvlc_playlist_play
 libvlc_release
diff --git a/lib/media.c b/lib/media.c
index 600e10a..aa0e24e 100644
--- a/lib/media.c
+++ b/lib/media.c
@@ -680,8 +680,57 @@ 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 )
+static void
+libvlc_media_fill_tracks_info( libvlc_media_track_info_2_t *p_mes,
+                               const es_format_t *p_es,
+                               int version )
+{
+    p_mes->i_codec   = p_es->i_codec;
+    p_mes->i_id      = p_es->i_id;
+    p_mes->i_profile = p_es->i_profile;
+    p_mes->i_level   = p_es->i_level;
+
+    switch(p_es->i_cat)
+    {
+    case UNKNOWN_ES:
+    default:
+        p_mes->i_type = libvlc_track_unknown;
+        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;
+        if (version == 2) {
+            p_mes->u.video.i_sar_num = p_es->video.i_sar_num;
+            p_mes->u.video.i_sar_num = p_es->video.i_sar_num;
+            p_mes->u.video.f_frame_rate = (float)p_es->video.i_frame_rate /
+                                          (float)p_es-
>video.i_frame_rate_base;
+        }
+        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;
+        break;
+    case SPU_ES:
+        p_mes->i_type = libvlc_track_text;
+        if (version == 2) {
+            p_mes->u.subtitle.psz_encoding = p_es->subs.psz_encoding != NULL 
?
+                                             strdup(p_es->subs.psz_encoding) 
: NULL;
+        }
+        break;
+    }
+
+    if (version == 2) {
+        p_mes->i_bitrate = p_es->i_bitrate;
+        p_mes->psz_language = p_es->psz_language != NULL ? strdup(p_es-
>psz_language) : NULL;
+        p_mes->psz_description = p_es->psz_description != NULL ? strdup(p_es-
>psz_description) : NULL;
+    }
+}
+
+
+static int
+libvlc_media_get_tracks_info_internal( libvlc_media_t *p_md, void *vpp_es, 
int version)
 {
     assert( p_md );
 
@@ -689,9 +738,15 @@ libvlc_media_get_tracks_info( libvlc_media_t *p_md, 
libvlc_media_track_info_t **
     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;
 
-    if( !*pp_es ) /* no ES, or OOM */
+    size_t size;
+    if (version == 2)
+        size = sizeof(libvlc_media_track_info_2_t);
+    else
+        size = sizeof(libvlc_media_track_info_t);
+    vpp_es = (i_es > 0) ? malloc( i_es * size ) : NULL;
+
+    if( !vpp_es ) /* no ES, or OOM */
     {
         vlc_mutex_unlock( &p_input_item->lock );
         return 0;
@@ -700,37 +755,50 @@ libvlc_media_get_tracks_info( libvlc_media_t *p_md, 
libvlc_media_track_info_t **
     /* Fill array */
     for( int i = 0; i < i_es; i++ )
     {
-        libvlc_media_track_info_t *p_mes = *pp_es+i;
         const es_format_t *p_es = p_input_item->es[i];
-
-        p_mes->i_codec = p_es->i_codec;
-        p_mes->i_id = p_es->i_id;
-
-        p_mes->i_profile = p_es->i_profile;
-        p_mes->i_level = p_es->i_level;
-
-        switch(p_es->i_cat)
+        if (version == 2)
+        {
+            libvlc_media_track_info_2_t **pp_es = vpp_es;
+            libvlc_media_track_info_2_t *p_mes = *pp_es+i;
+            libvlc_media_fill_tracks_info( p_mes, p_es, true );
+        }
+        else
         {
-        case UNKNOWN_ES:
-        default:
-            p_mes->i_type = libvlc_track_unknown;
-            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;
-            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;
-            break;
-        case SPU_ES:
-            p_mes->i_type = libvlc_track_text;
-            break;
+            libvlc_media_track_info_t **pp_es = vpp_es;
+            libvlc_media_track_info_t *p_mes = *pp_es+i;
+            libvlc_media_fill_tracks_info( (libvlc_media_track_info_2_t 
*)p_mes, p_es, false );

Not sure this cast respects the rules of C type aliasing.

         }
     }
 
     vlc_mutex_unlock( &p_input_item->lock );
     return i_es;
 }
+
+int
+libvlc_media_get_tracks_info( libvlc_media_t *p_md, libvlc_media_track_info_t 
** pp_es )
+{
+    return libvlc_media_get_tracks_info_internal( p_md, pp_es, 1);
+}
+
+int
+libvlc_media_get_tracks_info_2( libvlc_media_t *p_md, 
libvlc_media_track_info_2_t ** pp_es )
+{
+    return libvlc_media_get_tracks_info_internal( p_md, pp_es, 2);
+}
+
+
+/**************************************************************************
+ * Release media descriptor's elementary streams description array
+ **************************************************************************/
+void libvlc_media_tracks_info_release( libvlc_media_track_info_2_t *p_tracks, 
int i_count )
+{
+    if (!p_tracks)
+        return;
+    for (int i = 0; i < i_count; ++i) {
+        free( p_tracks[i].psz_language );
+        free( p_tracks[i].psz_description );
+        if (p_tracks[i].i_type == libvlc_track_text)
+            free (p_tracks[i].u.subtitle.psz_encoding);
+    }
+    free( p_tracks );
+}
-- 
1.8.1.2



-- 
Rémi Denis-Courmont
http://www.remlab.net/



More information about the vlc-devel mailing list