1 /*****************************************************************************
2 * media.c: Libvlc API media descripor management
3 *****************************************************************************
4 * Copyright (C) 2007 VLC authors and VideoLAN
7 * Authors: Pierre d'Herbemont <pdherbemont@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
31 #include <vlc/libvlc.h>
32 #include <vlc/libvlc_media.h>
33 #include <vlc/libvlc_media_list.h> // For the subitems, here for convenience
34 #include <vlc/libvlc_events.h>
36 #include <vlc_common.h>
37 #include <vlc_input.h>
39 #include <vlc_playlist.h> /* For the preparser */
42 #include "../src/libvlc.h"
44 #include "libvlc_internal.h"
45 #include "media_internal.h"
46 #include "media_list_internal.h"
48 static const vlc_meta_type_t libvlc_to_vlc_meta[] =
50 [libvlc_meta_Title] = vlc_meta_Title,
51 [libvlc_meta_Artist] = vlc_meta_Artist,
52 [libvlc_meta_Genre] = vlc_meta_Genre,
53 [libvlc_meta_Copyright] = vlc_meta_Copyright,
54 [libvlc_meta_Album] = vlc_meta_Album,
55 [libvlc_meta_TrackNumber] = vlc_meta_TrackNumber,
56 [libvlc_meta_Description] = vlc_meta_Description,
57 [libvlc_meta_Rating] = vlc_meta_Rating,
58 [libvlc_meta_Date] = vlc_meta_Date,
59 [libvlc_meta_Setting] = vlc_meta_Setting,
60 [libvlc_meta_URL] = vlc_meta_URL,
61 [libvlc_meta_Language] = vlc_meta_Language,
62 [libvlc_meta_NowPlaying] = vlc_meta_NowPlaying,
63 [libvlc_meta_Publisher] = vlc_meta_Publisher,
64 [libvlc_meta_EncodedBy] = vlc_meta_EncodedBy,
65 [libvlc_meta_ArtworkURL] = vlc_meta_ArtworkURL,
66 [libvlc_meta_TrackID] = vlc_meta_TrackID,
67 [libvlc_meta_TrackTotal] = vlc_meta_TrackTotal,
68 [libvlc_meta_Director] = vlc_meta_Director,
69 [libvlc_meta_Season] = vlc_meta_Season,
70 [libvlc_meta_Episode] = vlc_meta_Episode,
71 [libvlc_meta_ShowName] = vlc_meta_ShowName,
72 [libvlc_meta_Actors] = vlc_meta_Actors,
73 [libvlc_meta_AlbumArtist] = vlc_meta_AlbumArtist,
74 [libvlc_meta_DiscNumber] = vlc_meta_DiscNumber
77 static const libvlc_meta_t vlc_to_libvlc_meta[] =
79 [vlc_meta_Title] = libvlc_meta_Title,
80 [vlc_meta_Artist] = libvlc_meta_Artist,
81 [vlc_meta_Genre] = libvlc_meta_Genre,
82 [vlc_meta_Copyright] = libvlc_meta_Copyright,
83 [vlc_meta_Album] = libvlc_meta_Album,
84 [vlc_meta_TrackNumber] = libvlc_meta_TrackNumber,
85 [vlc_meta_Description] = libvlc_meta_Description,
86 [vlc_meta_Rating] = libvlc_meta_Rating,
87 [vlc_meta_Date] = libvlc_meta_Date,
88 [vlc_meta_Setting] = libvlc_meta_Setting,
89 [vlc_meta_URL] = libvlc_meta_URL,
90 [vlc_meta_Language] = libvlc_meta_Language,
91 [vlc_meta_NowPlaying] = libvlc_meta_NowPlaying,
92 [vlc_meta_ESNowPlaying] = libvlc_meta_NowPlaying,
93 [vlc_meta_Publisher] = libvlc_meta_Publisher,
94 [vlc_meta_EncodedBy] = libvlc_meta_EncodedBy,
95 [vlc_meta_ArtworkURL] = libvlc_meta_ArtworkURL,
96 [vlc_meta_TrackID] = libvlc_meta_TrackID,
97 [vlc_meta_TrackTotal] = libvlc_meta_TrackTotal,
98 [vlc_meta_Director] = libvlc_meta_Director,
99 [vlc_meta_Season] = libvlc_meta_Season,
100 [vlc_meta_Episode] = libvlc_meta_Episode,
101 [vlc_meta_ShowName] = libvlc_meta_ShowName,
102 [vlc_meta_Actors] = libvlc_meta_Actors,
103 [vlc_meta_AlbumArtist] = libvlc_meta_AlbumArtist,
104 [vlc_meta_DiscNumber] = libvlc_meta_DiscNumber
107 static libvlc_media_list_t *media_get_subitems( libvlc_media_t * p_md,
110 libvlc_media_list_t *p_subitems = NULL;
112 vlc_mutex_lock( &p_md->subitems_lock );
113 if( p_md->p_subitems == NULL && b_create )
115 p_md->p_subitems = libvlc_media_list_new( p_md->p_libvlc_instance );
116 if( p_md->p_subitems != NULL )
118 p_md->p_subitems->b_read_only = true;
119 p_md->p_subitems->p_internal_md = p_md;
122 p_subitems = p_md->p_subitems;
123 vlc_mutex_unlock( &p_md->subitems_lock );
127 /**************************************************************************
128 * input_item_subitem_added (Private) (vlc event Callback)
129 **************************************************************************/
130 static void input_item_subitem_added( const vlc_event_t *p_event,
133 libvlc_media_t * p_md = user_data;
134 libvlc_media_t * p_md_child;
135 libvlc_media_list_t *p_subitems;
136 libvlc_event_t event;
138 p_md_child = libvlc_media_new_from_input_item(
139 p_md->p_libvlc_instance,
140 p_event->u.input_item_subitem_added.p_new_child );
142 /* Add this to our media list */
143 p_subitems = media_get_subitems( p_md, true );
144 if( p_subitems != NULL )
146 libvlc_media_list_lock( p_subitems );
147 libvlc_media_list_internal_add_media( p_subitems, p_md_child );
148 libvlc_media_list_unlock( p_subitems );
151 /* Construct the event */
152 event.type = libvlc_MediaSubItemAdded;
153 event.u.media_subitem_added.new_child = p_md_child;
156 libvlc_event_send( p_md->p_event_manager, &event );
157 libvlc_media_release( p_md_child );
160 /**************************************************************************
161 * input_item_subitemtree_added (Private) (vlc event Callback)
162 **************************************************************************/
163 static void input_item_subitemtree_added( const vlc_event_t * p_event,
166 VLC_UNUSED( p_event );
167 libvlc_media_t * p_md = user_data;
168 libvlc_event_t event;
170 /* Construct the event */
171 event.type = libvlc_MediaSubItemTreeAdded;
172 event.u.media_subitemtree_added.item = p_md;
175 libvlc_event_send( p_md->p_event_manager, &event );
178 /**************************************************************************
179 * input_item_meta_changed (Private) (vlc event Callback)
180 **************************************************************************/
181 static void input_item_meta_changed( const vlc_event_t *p_event,
184 libvlc_media_t * p_md = user_data;
185 libvlc_event_t event;
187 /* Construct the event */
188 event.type = libvlc_MediaMetaChanged;
189 event.u.media_meta_changed.meta_type =
190 vlc_to_libvlc_meta[p_event->u.input_item_meta_changed.meta_type];
193 libvlc_event_send( p_md->p_event_manager, &event );
196 /**************************************************************************
197 * input_item_duration_changed (Private) (vlc event Callback)
198 **************************************************************************/
199 static void input_item_duration_changed( const vlc_event_t *p_event,
202 libvlc_media_t * p_md = user_data;
203 libvlc_event_t event;
205 /* Construct the event */
206 event.type = libvlc_MediaDurationChanged;
207 event.u.media_duration_changed.new_duration =
208 from_mtime(p_event->u.input_item_duration_changed.new_duration);
211 libvlc_event_send( p_md->p_event_manager, &event );
214 /**************************************************************************
215 * input_item_preparsed_changed (Private) (vlc event Callback)
216 **************************************************************************/
217 static void input_item_preparsed_changed(const vlc_event_t *p_event,
220 libvlc_media_t *media = user_data;
221 libvlc_event_t event;
223 /* Eventually notify libvlc_media_parse() */
224 vlc_mutex_lock(&media->parsed_lock);
225 media->is_parsed = true;
226 vlc_cond_broadcast(&media->parsed_cond);
227 vlc_mutex_unlock(&media->parsed_lock);
230 /* Construct the event */
231 event.type = libvlc_MediaParsedChanged;
232 event.u.media_parsed_changed.new_status =
233 p_event->u.input_item_preparsed_changed.new_status;
236 libvlc_event_send(media->p_event_manager, &event);
239 /**************************************************************************
240 * input_item_preparse_ended (Private) (vlc event Callback)
241 **************************************************************************/
242 static void input_item_preparse_ended( const vlc_event_t * p_event,
245 VLC_UNUSED( p_event );
246 libvlc_media_t * p_md = user_data;
247 libvlc_media_list_t *p_subitems = media_get_subitems( p_md, false );
249 if( p_subitems != NULL )
251 /* notify the media list */
252 libvlc_media_list_lock( p_subitems );
253 libvlc_media_list_internal_end_reached( p_subitems );
254 libvlc_media_list_unlock( p_subitems );
258 /**************************************************************************
259 * Install event handler (Private)
260 **************************************************************************/
261 static void install_input_item_observer( libvlc_media_t *p_md )
263 vlc_event_attach( &p_md->p_input_item->event_manager,
264 vlc_InputItemSubItemAdded,
265 input_item_subitem_added,
267 vlc_event_attach( &p_md->p_input_item->event_manager,
268 vlc_InputItemMetaChanged,
269 input_item_meta_changed,
271 vlc_event_attach( &p_md->p_input_item->event_manager,
272 vlc_InputItemDurationChanged,
273 input_item_duration_changed,
275 vlc_event_attach( &p_md->p_input_item->event_manager,
276 vlc_InputItemPreparsedChanged,
277 input_item_preparsed_changed,
279 vlc_event_attach( &p_md->p_input_item->event_manager,
280 vlc_InputItemSubItemTreeAdded,
281 input_item_subitemtree_added,
283 vlc_event_attach( &p_md->p_input_item->event_manager,
284 vlc_InputItemPreparseEnded,
285 input_item_preparse_ended,
289 /**************************************************************************
290 * Uninstall event handler (Private)
291 **************************************************************************/
292 static void uninstall_input_item_observer( libvlc_media_t *p_md )
294 vlc_event_detach( &p_md->p_input_item->event_manager,
295 vlc_InputItemSubItemAdded,
296 input_item_subitem_added,
298 vlc_event_detach( &p_md->p_input_item->event_manager,
299 vlc_InputItemMetaChanged,
300 input_item_meta_changed,
302 vlc_event_detach( &p_md->p_input_item->event_manager,
303 vlc_InputItemDurationChanged,
304 input_item_duration_changed,
306 vlc_event_detach( &p_md->p_input_item->event_manager,
307 vlc_InputItemPreparsedChanged,
308 input_item_preparsed_changed,
310 vlc_event_detach( &p_md->p_input_item->event_manager,
311 vlc_InputItemSubItemTreeAdded,
312 input_item_subitemtree_added,
314 vlc_event_detach( &p_md->p_input_item->event_manager,
315 vlc_InputItemPreparseEnded,
316 input_item_preparse_ended,
320 /**************************************************************************
321 * Create a new media descriptor object from an input_item
323 * That's the generic constructor
324 **************************************************************************/
325 libvlc_media_t * libvlc_media_new_from_input_item(
326 libvlc_instance_t *p_instance,
327 input_item_t *p_input_item )
329 libvlc_media_t * p_md;
333 libvlc_printerr( "No input item given" );
337 p_md = calloc( 1, sizeof(libvlc_media_t) );
340 libvlc_printerr( "Not enough memory" );
344 p_md->p_libvlc_instance = p_instance;
345 p_md->p_input_item = p_input_item;
346 p_md->i_refcount = 1;
348 vlc_cond_init(&p_md->parsed_cond);
349 vlc_mutex_init(&p_md->parsed_lock);
350 vlc_mutex_init(&p_md->subitems_lock);
352 p_md->state = libvlc_NothingSpecial;
354 /* A media descriptor can be a playlist. When you open a playlist
355 * It can give a bunch of item to read. */
356 p_md->p_subitems = NULL;
358 p_md->p_event_manager = libvlc_event_manager_new( p_md, p_instance );
359 if( unlikely(p_md->p_event_manager == NULL) )
365 libvlc_event_manager_t *em = p_md->p_event_manager;
366 libvlc_event_manager_register_event_type(em, libvlc_MediaMetaChanged);
367 libvlc_event_manager_register_event_type(em, libvlc_MediaSubItemAdded);
368 libvlc_event_manager_register_event_type(em, libvlc_MediaFreed);
369 libvlc_event_manager_register_event_type(em, libvlc_MediaDurationChanged);
370 libvlc_event_manager_register_event_type(em, libvlc_MediaStateChanged);
371 libvlc_event_manager_register_event_type(em, libvlc_MediaParsedChanged);
372 libvlc_event_manager_register_event_type(em, libvlc_MediaSubItemTreeAdded);
374 vlc_gc_incref( p_md->p_input_item );
376 install_input_item_observer( p_md );
381 /**************************************************************************
382 * Create a new media descriptor object
383 **************************************************************************/
384 libvlc_media_t *libvlc_media_new_location( libvlc_instance_t *p_instance,
385 const char * psz_mrl )
387 input_item_t * p_input_item;
388 libvlc_media_t * p_md;
390 p_input_item = input_item_New( psz_mrl, NULL );
394 libvlc_printerr( "Not enough memory" );
398 p_md = libvlc_media_new_from_input_item( p_instance, p_input_item );
400 /* The p_input_item is retained in libvlc_media_new_from_input_item */
401 vlc_gc_decref( p_input_item );
406 libvlc_media_t *libvlc_media_new_path( libvlc_instance_t *p_instance,
409 char *mrl = vlc_path2uri( path, NULL );
410 if( unlikely(mrl == NULL) )
412 libvlc_printerr( "%s", vlc_strerror_c(errno) );
416 libvlc_media_t *m = libvlc_media_new_location( p_instance, mrl );
421 libvlc_media_t *libvlc_media_new_fd( libvlc_instance_t *p_instance, int fd )
424 snprintf( mrl, sizeof(mrl), "fd://%d", fd );
426 return libvlc_media_new_location( p_instance, mrl );
429 /**************************************************************************
430 * Create a new media descriptor object
431 **************************************************************************/
432 libvlc_media_t * libvlc_media_new_as_node( libvlc_instance_t *p_instance,
433 const char * psz_name )
435 input_item_t * p_input_item;
436 libvlc_media_t * p_md;
437 libvlc_media_list_t * p_subitems;
439 p_input_item = input_item_New( "vlc://nop", psz_name );
443 libvlc_printerr( "Not enough memory" );
447 p_md = libvlc_media_new_from_input_item( p_instance, p_input_item );
449 p_subitems = media_get_subitems( p_md, true );
450 if( p_subitems == NULL) {
451 libvlc_media_release( p_md );
458 /**************************************************************************
459 * Add an option to the media descriptor,
460 * that will be used to determine how the media_player will read the
461 * media. This allow to use VLC advanced reading/streaming
462 * options in a per-media basis
464 * The options are detailled in vlc --long-help, for instance "--sout-all"
465 **************************************************************************/
466 void libvlc_media_add_option( libvlc_media_t * p_md,
467 const char * psz_option )
469 libvlc_media_add_option_flag( p_md, psz_option,
470 VLC_INPUT_OPTION_UNIQUE|VLC_INPUT_OPTION_TRUSTED );
473 /**************************************************************************
474 * Same as libvlc_media_add_option but with configurable flags.
475 **************************************************************************/
476 void libvlc_media_add_option_flag( libvlc_media_t * p_md,
477 const char * ppsz_option,
480 input_item_AddOption( p_md->p_input_item, ppsz_option, i_flags );
483 /**************************************************************************
484 * Delete a media descriptor object
485 **************************************************************************/
486 void libvlc_media_release( libvlc_media_t *p_md )
493 if( p_md->i_refcount > 0 )
496 if( p_md->p_subitems )
497 libvlc_media_list_release( p_md->p_subitems );
499 uninstall_input_item_observer( p_md );
500 vlc_gc_decref( p_md->p_input_item );
502 vlc_cond_destroy( &p_md->parsed_cond );
503 vlc_mutex_destroy( &p_md->parsed_lock );
504 vlc_mutex_destroy( &p_md->subitems_lock );
506 /* Construct the event */
507 libvlc_event_t event;
508 event.type = libvlc_MediaFreed;
509 event.u.media_freed.md = p_md;
512 libvlc_event_send( p_md->p_event_manager, &event );
514 libvlc_event_manager_release( p_md->p_event_manager );
519 /**************************************************************************
520 * Retain a media descriptor object
521 **************************************************************************/
522 void libvlc_media_retain( libvlc_media_t *p_md )
528 /**************************************************************************
529 * Duplicate a media descriptor object
530 **************************************************************************/
532 libvlc_media_duplicate( libvlc_media_t *p_md_orig )
534 return libvlc_media_new_from_input_item(
535 p_md_orig->p_libvlc_instance, p_md_orig->p_input_item );
538 /**************************************************************************
539 * Get mrl from a media descriptor object
540 **************************************************************************/
542 libvlc_media_get_mrl( libvlc_media_t * p_md )
545 return input_item_GetURI( p_md->p_input_item );
548 /**************************************************************************
549 * Getter for meta information
550 **************************************************************************/
552 char *libvlc_media_get_meta( libvlc_media_t *p_md, libvlc_meta_t e_meta )
554 char *psz_meta = NULL;
556 if( e_meta == libvlc_meta_NowPlaying )
558 psz_meta = input_item_GetNowPlayingFb( p_md->p_input_item );
562 psz_meta = input_item_GetMeta( p_md->p_input_item,
563 libvlc_to_vlc_meta[e_meta] );
564 /* Should be integrated in core */
565 if( psz_meta == NULL && e_meta == libvlc_meta_Title
566 && p_md->p_input_item->psz_name != NULL )
567 psz_meta = strdup( p_md->p_input_item->psz_name );
572 /**************************************************************************
573 * Setter for meta information
574 **************************************************************************/
576 void libvlc_media_set_meta( libvlc_media_t *p_md, libvlc_meta_t e_meta, const char *psz_value )
579 input_item_SetMeta( p_md->p_input_item, libvlc_to_vlc_meta[e_meta], psz_value );
582 int libvlc_media_save_meta( libvlc_media_t *p_md )
585 vlc_object_t *p_obj = VLC_OBJECT(p_md->p_libvlc_instance->p_libvlc_int);
586 return input_item_WriteMeta( p_obj, p_md->p_input_item ) == VLC_SUCCESS;
589 /**************************************************************************
590 * Getter for state information
591 * Can be error, playing, buffering, NothingSpecial.
592 **************************************************************************/
595 libvlc_media_get_state( libvlc_media_t *p_md )
601 /**************************************************************************
602 * Setter for state information (LibVLC Internal)
603 **************************************************************************/
606 libvlc_media_set_state( libvlc_media_t *p_md,
607 libvlc_state_t state )
609 libvlc_event_t event;
613 /* Construct the event */
614 event.type = libvlc_MediaStateChanged;
615 event.u.media_state_changed.new_state = state;
618 libvlc_event_send( p_md->p_event_manager, &event );
621 /**************************************************************************
623 **************************************************************************/
624 libvlc_media_list_t *
625 libvlc_media_subitems( libvlc_media_t * p_md )
627 libvlc_media_list_t *p_subitems = media_get_subitems( p_md, true );
629 libvlc_media_list_retain( p_subitems );
633 /**************************************************************************
634 * Getter for statistics information
635 **************************************************************************/
636 int libvlc_media_get_stats( libvlc_media_t *p_md,
637 libvlc_media_stats_t *p_stats )
639 if( !p_md->p_input_item )
642 input_stats_t *p_itm_stats = p_md->p_input_item->p_stats;
643 vlc_mutex_lock( &p_itm_stats->lock );
644 p_stats->i_read_bytes = p_itm_stats->i_read_bytes;
645 p_stats->f_input_bitrate = p_itm_stats->f_input_bitrate;
647 p_stats->i_demux_read_bytes = p_itm_stats->i_demux_read_bytes;
648 p_stats->f_demux_bitrate = p_itm_stats->f_demux_bitrate;
649 p_stats->i_demux_corrupted = p_itm_stats->i_demux_corrupted;
650 p_stats->i_demux_discontinuity = p_itm_stats->i_demux_discontinuity;
652 p_stats->i_decoded_video = p_itm_stats->i_decoded_video;
653 p_stats->i_decoded_audio = p_itm_stats->i_decoded_audio;
655 p_stats->i_displayed_pictures = p_itm_stats->i_displayed_pictures;
656 p_stats->i_lost_pictures = p_itm_stats->i_lost_pictures;
658 p_stats->i_played_abuffers = p_itm_stats->i_played_abuffers;
659 p_stats->i_lost_abuffers = p_itm_stats->i_lost_abuffers;
661 p_stats->i_sent_packets = p_itm_stats->i_sent_packets;
662 p_stats->i_sent_bytes = p_itm_stats->i_sent_bytes;
663 p_stats->f_send_bitrate = p_itm_stats->f_send_bitrate;
664 vlc_mutex_unlock( &p_itm_stats->lock );
668 /**************************************************************************
670 **************************************************************************/
671 libvlc_event_manager_t *
672 libvlc_media_event_manager( libvlc_media_t * p_md )
676 return p_md->p_event_manager;
679 /**************************************************************************
680 * Get duration of media object (in ms)
681 **************************************************************************/
683 libvlc_media_get_duration( libvlc_media_t * p_md )
687 if( !p_md->p_input_item )
689 libvlc_printerr( "No input item" );
693 if (!input_item_IsPreparsed( p_md->p_input_item ))
696 return from_mtime(input_item_GetDuration( p_md->p_input_item ));
699 static int media_parse(libvlc_media_t *media, bool b_async,
700 libvlc_media_parse_flag_t parse_flag)
704 vlc_mutex_lock(&media->parsed_lock);
705 needed = !media->has_asked_preparse;
706 media->has_asked_preparse = true;
707 vlc_mutex_unlock(&media->parsed_lock);
711 libvlc_int_t *libvlc = media->p_libvlc_instance->p_libvlc_int;
712 input_item_t *item = media->p_input_item;
713 input_item_meta_request_option_t art_scope = META_REQUEST_OPTION_NONE;
714 input_item_meta_request_option_t parse_scope = META_REQUEST_OPTION_SCOPE_LOCAL;
717 if (parse_flag & libvlc_media_fetch_local)
718 art_scope |= META_REQUEST_OPTION_SCOPE_LOCAL;
719 if (parse_flag & libvlc_media_fetch_network)
720 art_scope |= META_REQUEST_OPTION_SCOPE_NETWORK;
721 if (art_scope != META_REQUEST_OPTION_NONE) {
722 ret = libvlc_ArtRequest(libvlc, item, art_scope);
723 if (ret != VLC_SUCCESS)
727 if (parse_flag & libvlc_media_parse_network)
728 parse_scope |= META_REQUEST_OPTION_SCOPE_NETWORK;
729 ret = libvlc_MetaRequest(libvlc, item, parse_scope);
730 if (ret != VLC_SUCCESS)
738 vlc_mutex_lock(&media->parsed_lock);
739 while (!media->is_parsed)
740 vlc_cond_wait(&media->parsed_cond, &media->parsed_lock);
741 vlc_mutex_unlock(&media->parsed_lock);
746 /**************************************************************************
747 * Parse the media and wait.
748 **************************************************************************/
750 libvlc_media_parse(libvlc_media_t *media)
752 media_parse( media, false, libvlc_media_fetch_local );
755 /**************************************************************************
756 * Parse the media but do not wait.
757 **************************************************************************/
759 libvlc_media_parse_async(libvlc_media_t *media)
761 media_parse( media, true, libvlc_media_fetch_local );
764 /**************************************************************************
765 * Parse the media asynchronously with options.
766 **************************************************************************/
768 libvlc_media_parse_with_options( libvlc_media_t *media,
769 libvlc_media_parse_flag_t parse_flag )
771 return media_parse( media, true, parse_flag ) == VLC_SUCCESS ? 0 : -1;
774 /**************************************************************************
775 * Get parsed status for media object.
776 **************************************************************************/
778 libvlc_media_is_parsed(libvlc_media_t *media)
782 vlc_mutex_lock(&media->parsed_lock);
783 parsed = media->is_parsed;
784 vlc_mutex_unlock(&media->parsed_lock);
788 /**************************************************************************
789 * Sets media descriptor's user_data. user_data is specialized data
790 * accessed by the host application, VLC.framework uses it as a pointer to
791 * an native object that references a libvlc_media_t pointer
792 **************************************************************************/
794 libvlc_media_set_user_data( libvlc_media_t * p_md, void * p_new_user_data )
797 p_md->p_user_data = p_new_user_data;
800 /**************************************************************************
801 * Get media descriptor's user_data. user_data is specialized data
802 * accessed by the host application, VLC.framework uses it as a pointer to
803 * an native object that references a libvlc_media_t pointer
804 **************************************************************************/
806 libvlc_media_get_user_data( libvlc_media_t * p_md )
809 return p_md->p_user_data;
812 /**************************************************************************
813 * Get media descriptor's elementary streams description
814 **************************************************************************/
816 libvlc_media_get_tracks_info( libvlc_media_t *p_md, libvlc_media_track_info_t ** pp_es )
820 input_item_t *p_input_item = p_md->p_input_item;
821 vlc_mutex_lock( &p_input_item->lock );
823 const int i_es = p_input_item->i_es;
824 *pp_es = (i_es > 0) ? malloc( i_es * sizeof(libvlc_media_track_info_t) ) : NULL;
826 if( !*pp_es ) /* no ES, or OOM */
828 vlc_mutex_unlock( &p_input_item->lock );
833 for( int i = 0; i < i_es; i++ )
835 libvlc_media_track_info_t *p_mes = *pp_es+i;
836 const es_format_t *p_es = p_input_item->es[i];
838 p_mes->i_codec = p_es->i_codec;
839 p_mes->i_id = p_es->i_id;
841 p_mes->i_profile = p_es->i_profile;
842 p_mes->i_level = p_es->i_level;
848 p_mes->i_type = libvlc_track_unknown;
851 p_mes->i_type = libvlc_track_video;
852 p_mes->u.video.i_height = p_es->video.i_height;
853 p_mes->u.video.i_width = p_es->video.i_width;
856 p_mes->i_type = libvlc_track_audio;
857 p_mes->u.audio.i_channels = p_es->audio.i_channels;
858 p_mes->u.audio.i_rate = p_es->audio.i_rate;
861 p_mes->i_type = libvlc_track_text;
866 vlc_mutex_unlock( &p_input_item->lock );
871 libvlc_media_tracks_get( libvlc_media_t *p_md, libvlc_media_track_t *** pp_es )
875 input_item_t *p_input_item = p_md->p_input_item;
876 vlc_mutex_lock( &p_input_item->lock );
878 const int i_es = p_input_item->i_es;
879 *pp_es = (i_es > 0) ? calloc( i_es, sizeof(**pp_es) ) : NULL;
881 if( !*pp_es ) /* no ES, or OOM */
883 vlc_mutex_unlock( &p_input_item->lock );
888 for( int i = 0; i < i_es; i++ )
890 libvlc_media_track_t *p_mes = calloc( 1, sizeof(*p_mes) );
893 p_mes->audio = malloc( __MAX(__MAX(sizeof(*p_mes->audio),
894 sizeof(*p_mes->video)),
895 sizeof(*p_mes->subtitle)) );
897 if ( !p_mes || !p_mes->audio )
899 libvlc_media_tracks_release( *pp_es, i_es );
902 vlc_mutex_unlock( &p_input_item->lock );
907 const es_format_t *p_es = p_input_item->es[i];
909 p_mes->i_codec = p_es->i_codec;
910 p_mes->i_original_fourcc = p_es->i_original_fourcc;
911 p_mes->i_id = p_es->i_id;
913 p_mes->i_profile = p_es->i_profile;
914 p_mes->i_level = p_es->i_level;
916 p_mes->i_bitrate = p_es->i_bitrate;
917 p_mes->psz_language = p_es->psz_language != NULL ? strdup(p_es->psz_language) : NULL;
918 p_mes->psz_description = p_es->psz_description != NULL ? strdup(p_es->psz_description) : NULL;
924 p_mes->i_type = libvlc_track_unknown;
927 p_mes->i_type = libvlc_track_video;
928 p_mes->video->i_height = p_es->video.i_height;
929 p_mes->video->i_width = p_es->video.i_width;
930 p_mes->video->i_sar_num = p_es->video.i_sar_num;
931 p_mes->video->i_sar_den = p_es->video.i_sar_den;
932 p_mes->video->i_frame_rate_num = p_es->video.i_frame_rate;
933 p_mes->video->i_frame_rate_den = p_es->video.i_frame_rate_base;
936 p_mes->i_type = libvlc_track_audio;
937 p_mes->audio->i_channels = p_es->audio.i_channels;
938 p_mes->audio->i_rate = p_es->audio.i_rate;
941 p_mes->i_type = libvlc_track_text;
942 p_mes->subtitle->psz_encoding = p_es->subs.psz_encoding != NULL ?
943 strdup(p_es->subs.psz_encoding) : NULL;
948 vlc_mutex_unlock( &p_input_item->lock );
952 /**************************************************************************
953 * Get codec description from media elementary stream
954 **************************************************************************/
956 libvlc_media_get_codec_description( libvlc_track_type_t i_type,
961 case libvlc_track_audio:
962 return vlc_fourcc_GetDescription( AUDIO_ES, i_codec );
963 case libvlc_track_video:
964 return vlc_fourcc_GetDescription( VIDEO_ES, i_codec );
965 case libvlc_track_text:
966 return vlc_fourcc_GetDescription( SPU_ES, i_codec );
967 case libvlc_track_unknown:
969 return vlc_fourcc_GetDescription( UNKNOWN_ES, i_codec );
973 /**************************************************************************
974 * Release media descriptor's elementary streams description array
975 **************************************************************************/
976 void libvlc_media_tracks_release( libvlc_media_track_t **p_tracks, unsigned i_count )
978 for( unsigned i = 0; i < i_count; ++i )
982 free( p_tracks[i]->psz_language );
983 free( p_tracks[i]->psz_description );
984 switch( p_tracks[i]->i_type )
986 case libvlc_track_audio:
988 case libvlc_track_video:
990 case libvlc_track_text:
991 free( p_tracks[i]->subtitle->psz_encoding );
993 case libvlc_track_unknown:
997 free( p_tracks[i]->audio );