]> git.sesse.net Git - vlc/blobdiff - lib/media.c
libvlc_media_new_path: set more meaningful error message (fixes #10792)
[vlc] / lib / media.c
index 600e10a01e919efeff4b0feefe043893bc34de0e..af70b4a7e2de322215e5376d3ad9e0e2e355d330 100644 (file)
@@ -26,6 +26,7 @@
 #endif
 
 #include <assert.h>
+#include <errno.h>
 
 #include <vlc/libvlc.h>
 #include <vlc/libvlc_media.h>
@@ -61,7 +62,13 @@ static const vlc_meta_type_t libvlc_to_vlc_meta[] =
     [libvlc_meta_Publisher]    = vlc_meta_Publisher,
     [libvlc_meta_EncodedBy]    = vlc_meta_EncodedBy,
     [libvlc_meta_ArtworkURL]   = vlc_meta_ArtworkURL,
-    [libvlc_meta_TrackID]      = vlc_meta_TrackID
+    [libvlc_meta_TrackID]      = vlc_meta_TrackID,
+    [libvlc_meta_TrackTotal]   = vlc_meta_TrackTotal,
+    [libvlc_meta_Director]     = vlc_meta_Director,
+    [libvlc_meta_Season]       = vlc_meta_Season,
+    [libvlc_meta_Episode]      = vlc_meta_Episode,
+    [libvlc_meta_ShowName]     = vlc_meta_ShowName,
+    [libvlc_meta_Actors]       = vlc_meta_Actors
 };
 
 static const libvlc_meta_t vlc_to_libvlc_meta[] =
@@ -82,7 +89,13 @@ static const libvlc_meta_t vlc_to_libvlc_meta[] =
     [vlc_meta_Publisher]    = libvlc_meta_Publisher,
     [vlc_meta_EncodedBy]    = libvlc_meta_EncodedBy,
     [vlc_meta_ArtworkURL]   = libvlc_meta_ArtworkURL,
-    [vlc_meta_TrackID]      = libvlc_meta_TrackID
+    [vlc_meta_TrackID]      = libvlc_meta_TrackID,
+    [vlc_meta_TrackTotal]   = libvlc_meta_TrackTotal,
+    [vlc_meta_Director]     = libvlc_meta_Director,
+    [vlc_meta_Season]       = libvlc_meta_Season,
+    [vlc_meta_Episode]      = libvlc_meta_Episode,
+    [vlc_meta_ShowName]     = libvlc_meta_ShowName,
+    [vlc_meta_Actors]       = libvlc_meta_Actors
 };
 
 /**************************************************************************
@@ -119,6 +132,24 @@ static void input_item_subitem_added( const vlc_event_t *p_event,
     libvlc_media_release( p_md_child );
 }
 
+/**************************************************************************
+ * input_item_subitemtree_added (Private) (vlc event Callback)
+ **************************************************************************/
+static void input_item_subitemtree_added( const vlc_event_t * p_event,
+                                          void * user_data )
+{
+    VLC_UNUSED( p_event );
+    libvlc_media_t * p_md = user_data;
+    libvlc_event_t event;
+
+    /* Construct the event */
+    event.type = libvlc_MediaSubItemTreeAdded;
+    event.u.media_subitemtree_added.item = p_md;
+
+    /* Send the event */
+    libvlc_event_send( p_md->p_event_manager, &event );
+}
+
 /**************************************************************************
  * input_item_meta_changed (Private) (vlc event Callback)
  **************************************************************************/
@@ -201,6 +232,10 @@ static void install_input_item_observer( libvlc_media_t *p_md )
                       vlc_InputItemPreparsedChanged,
                       input_item_preparsed_changed,
                       p_md );
+    vlc_event_attach( &p_md->p_input_item->event_manager,
+                      vlc_InputItemSubItemTreeAdded,
+                      input_item_subitemtree_added,
+                      p_md );
 }
 
 /**************************************************************************
@@ -224,6 +259,10 @@ static void uninstall_input_item_observer( libvlc_media_t *p_md )
                       vlc_InputItemPreparsedChanged,
                       input_item_preparsed_changed,
                       p_md );
+    vlc_event_detach( &p_md->p_input_item->event_manager,
+                      vlc_InputItemSubItemTreeAdded,
+                      input_item_subitemtree_added,
+                      p_md );
 }
 
 /**************************************************************************
@@ -277,6 +316,7 @@ libvlc_media_t * libvlc_media_new_from_input_item(
     libvlc_event_manager_register_event_type(em, libvlc_MediaDurationChanged);
     libvlc_event_manager_register_event_type(em, libvlc_MediaStateChanged);
     libvlc_event_manager_register_event_type(em, libvlc_MediaParsedChanged);
+    libvlc_event_manager_register_event_type(em, libvlc_MediaSubItemTreeAdded);
 
     vlc_gc_incref( p_md->p_input_item );
 
@@ -313,10 +353,10 @@ libvlc_media_t *libvlc_media_new_location( libvlc_instance_t *p_instance,
 libvlc_media_t *libvlc_media_new_path( libvlc_instance_t *p_instance,
                                        const char *path )
 {
-    char *mrl = vlc_path2uri( path, "file" );
+    char *mrl = vlc_path2uri( path, NULL );
     if( unlikely(mrl == NULL) )
     {
-        libvlc_printerr( "Not enough memory" );
+        libvlc_printerr( "%s", vlc_strerror_c(errno) );
         return NULL;
     }
 
@@ -590,13 +630,12 @@ libvlc_media_get_duration( libvlc_media_t * p_md )
 
 static int media_parse(libvlc_media_t *media)
 {
-    /* TODO: fetcher and parser independent of playlist */
-#warning FIXME: remove pl_Get
-    playlist_t *playlist = pl_Get(media->p_libvlc_instance->p_libvlc_int);
+    libvlc_int_t *libvlc = media->p_libvlc_instance->p_libvlc_int;
+    input_item_t *item = media->p_input_item;
 
     /* TODO: Fetch art on need basis. But how not to break compatibility? */
-    playlist_AskForArtEnqueue(playlist, media->p_input_item );
-    return playlist_PreparseEnqueue(playlist, media->p_input_item);
+    libvlc_ArtRequest(libvlc, item);
+    return libvlc_MetaRequest(libvlc, item);
 }
 
 /**************************************************************************
@@ -734,3 +773,116 @@ 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;
 }
+
+unsigned
+libvlc_media_tracks_get( libvlc_media_t *p_md, libvlc_media_track_t *** pp_es )
+{
+    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) ? calloc( i_es, sizeof(**pp_es) ) : NULL;
+
+    if( !*pp_es ) /* no ES, or OOM */
+    {
+        vlc_mutex_unlock( &p_input_item->lock );
+        return 0;
+    }
+
+    /* Fill array */
+    for( int i = 0; i < i_es; i++ )
+    {
+        libvlc_media_track_t *p_mes = calloc( 1, sizeof(*p_mes) );
+        if ( p_mes )
+        {
+            p_mes->audio = malloc( __MAX(__MAX(sizeof(*p_mes->audio),
+                                               sizeof(*p_mes->video)),
+                                               sizeof(*p_mes->subtitle)) );
+        }
+        if ( !p_mes || !p_mes->audio )
+        {
+            libvlc_media_tracks_release( *pp_es, i_es );
+            *pp_es = NULL;
+            free( p_mes );
+            vlc_mutex_unlock( &p_input_item->lock );
+            return 0;
+        }
+        (*pp_es)[i] = p_mes;
+
+        const es_format_t *p_es = p_input_item->es[i];
+
+        p_mes->i_codec = p_es->i_codec;
+        p_mes->i_original_fourcc = p_es->i_original_fourcc;
+        p_mes->i_id = p_es->i_id;
+
+        p_mes->i_profile = p_es->i_profile;
+        p_mes->i_level = p_es->i_level;
+
+        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;
+
+        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->video->i_height = p_es->video.i_height;
+            p_mes->video->i_width = p_es->video.i_width;
+            p_mes->video->i_sar_num = p_es->video.i_sar_num;
+            p_mes->video->i_sar_den = p_es->video.i_sar_den;
+            p_mes->video->i_frame_rate_num = p_es->video.i_frame_rate;
+            p_mes->video->i_frame_rate_den = p_es->video.i_frame_rate_base;
+            break;
+        case AUDIO_ES:
+            p_mes->i_type = libvlc_track_audio;
+            p_mes->audio->i_channels = p_es->audio.i_channels;
+            p_mes->audio->i_rate = p_es->audio.i_rate;
+            break;
+        case SPU_ES:
+            p_mes->i_type = libvlc_track_text;
+            p_mes->subtitle->psz_encoding = p_es->subs.psz_encoding != NULL ?
+                                            strdup(p_es->subs.psz_encoding) : NULL;
+            break;
+        }
+    }
+
+    vlc_mutex_unlock( &p_input_item->lock );
+    return i_es;
+}
+
+
+/**************************************************************************
+ * Release media descriptor's elementary streams description array
+ **************************************************************************/
+void libvlc_media_tracks_release( libvlc_media_track_t **p_tracks, unsigned i_count )
+{
+    for( unsigned i = 0; i < i_count; ++i )
+    {
+        if ( !p_tracks[i] )
+            continue;
+        free( p_tracks[i]->psz_language );
+        free( p_tracks[i]->psz_description );
+        switch( p_tracks[i]->i_type )
+        {
+        case libvlc_track_audio:
+            break;
+        case libvlc_track_video:
+            break;
+        case libvlc_track_text:
+            free( p_tracks[i]->subtitle->psz_encoding );
+            break;
+        case libvlc_track_unknown:
+        default:
+            break;
+        }
+        free( p_tracks[i]->audio );
+        free( p_tracks[i] );
+    }
+    free( p_tracks );
+}