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 libvlc_media_t
*libvlc_media_new_callbacks(libvlc_instance_t
*p_instance
,
430 libvlc_media_open_cb open_cb
,
431 libvlc_media_read_cb read_cb
,
432 libvlc_media_seek_cb seek_cb
,
433 libvlc_media_close_cb close_cb
,
436 libvlc_media_t
*m
= libvlc_media_new_location(p_instance
, "imem://");
437 if (unlikely(m
== NULL
))
440 assert(read_cb
!= NULL
);
441 input_item_AddOpaque(m
->p_input_item
, "imem-data", opaque
);
442 input_item_AddOpaque(m
->p_input_item
, "imem-open", open_cb
);
443 input_item_AddOpaque(m
->p_input_item
, "imem-read", read_cb
);
444 input_item_AddOpaque(m
->p_input_item
, "imem-seek", seek_cb
);
445 input_item_AddOpaque(m
->p_input_item
, "imem-close", close_cb
);
449 /**************************************************************************
450 * Create a new media descriptor object
451 **************************************************************************/
452 libvlc_media_t
* libvlc_media_new_as_node( libvlc_instance_t
*p_instance
,
453 const char * psz_name
)
455 input_item_t
* p_input_item
;
456 libvlc_media_t
* p_md
;
457 libvlc_media_list_t
* p_subitems
;
459 p_input_item
= input_item_New( "vlc://nop", psz_name
);
463 libvlc_printerr( "Not enough memory" );
467 p_md
= libvlc_media_new_from_input_item( p_instance
, p_input_item
);
469 p_subitems
= media_get_subitems( p_md
, true );
470 if( p_subitems
== NULL
) {
471 libvlc_media_release( p_md
);
478 /**************************************************************************
479 * Add an option to the media descriptor,
480 * that will be used to determine how the media_player will read the
481 * media. This allow to use VLC advanced reading/streaming
482 * options in a per-media basis
484 * The options are detailled in vlc --long-help, for instance "--sout-all"
485 **************************************************************************/
486 void libvlc_media_add_option( libvlc_media_t
* p_md
,
487 const char * psz_option
)
489 libvlc_media_add_option_flag( p_md
, psz_option
,
490 VLC_INPUT_OPTION_UNIQUE
|VLC_INPUT_OPTION_TRUSTED
);
493 /**************************************************************************
494 * Same as libvlc_media_add_option but with configurable flags.
495 **************************************************************************/
496 void libvlc_media_add_option_flag( libvlc_media_t
* p_md
,
497 const char * ppsz_option
,
500 input_item_AddOption( p_md
->p_input_item
, ppsz_option
, i_flags
);
503 /**************************************************************************
504 * Delete a media descriptor object
505 **************************************************************************/
506 void libvlc_media_release( libvlc_media_t
*p_md
)
513 if( p_md
->i_refcount
> 0 )
516 if( p_md
->p_subitems
)
517 libvlc_media_list_release( p_md
->p_subitems
);
519 uninstall_input_item_observer( p_md
);
520 vlc_gc_decref( p_md
->p_input_item
);
522 vlc_cond_destroy( &p_md
->parsed_cond
);
523 vlc_mutex_destroy( &p_md
->parsed_lock
);
524 vlc_mutex_destroy( &p_md
->subitems_lock
);
526 /* Construct the event */
527 libvlc_event_t event
;
528 event
.type
= libvlc_MediaFreed
;
529 event
.u
.media_freed
.md
= p_md
;
532 libvlc_event_send( p_md
->p_event_manager
, &event
);
534 libvlc_event_manager_release( p_md
->p_event_manager
);
539 /**************************************************************************
540 * Retain a media descriptor object
541 **************************************************************************/
542 void libvlc_media_retain( libvlc_media_t
*p_md
)
548 /**************************************************************************
549 * Duplicate a media descriptor object
550 **************************************************************************/
552 libvlc_media_duplicate( libvlc_media_t
*p_md_orig
)
554 return libvlc_media_new_from_input_item(
555 p_md_orig
->p_libvlc_instance
, p_md_orig
->p_input_item
);
558 /**************************************************************************
559 * Get mrl from a media descriptor object
560 **************************************************************************/
562 libvlc_media_get_mrl( libvlc_media_t
* p_md
)
565 return input_item_GetURI( p_md
->p_input_item
);
568 /**************************************************************************
569 * Getter for meta information
570 **************************************************************************/
572 char *libvlc_media_get_meta( libvlc_media_t
*p_md
, libvlc_meta_t e_meta
)
574 char *psz_meta
= NULL
;
576 if( e_meta
== libvlc_meta_NowPlaying
)
578 psz_meta
= input_item_GetNowPlayingFb( p_md
->p_input_item
);
582 psz_meta
= input_item_GetMeta( p_md
->p_input_item
,
583 libvlc_to_vlc_meta
[e_meta
] );
584 /* Should be integrated in core */
585 if( psz_meta
== NULL
&& e_meta
== libvlc_meta_Title
586 && p_md
->p_input_item
->psz_name
!= NULL
)
587 psz_meta
= strdup( p_md
->p_input_item
->psz_name
);
592 /**************************************************************************
593 * Setter for meta information
594 **************************************************************************/
596 void libvlc_media_set_meta( libvlc_media_t
*p_md
, libvlc_meta_t e_meta
, const char *psz_value
)
599 input_item_SetMeta( p_md
->p_input_item
, libvlc_to_vlc_meta
[e_meta
], psz_value
);
602 int libvlc_media_save_meta( libvlc_media_t
*p_md
)
605 vlc_object_t
*p_obj
= VLC_OBJECT(p_md
->p_libvlc_instance
->p_libvlc_int
);
606 return input_item_WriteMeta( p_obj
, p_md
->p_input_item
) == VLC_SUCCESS
;
609 /**************************************************************************
610 * Getter for state information
611 * Can be error, playing, buffering, NothingSpecial.
612 **************************************************************************/
615 libvlc_media_get_state( libvlc_media_t
*p_md
)
621 /**************************************************************************
622 * Setter for state information (LibVLC Internal)
623 **************************************************************************/
626 libvlc_media_set_state( libvlc_media_t
*p_md
,
627 libvlc_state_t state
)
629 libvlc_event_t event
;
633 /* Construct the event */
634 event
.type
= libvlc_MediaStateChanged
;
635 event
.u
.media_state_changed
.new_state
= state
;
638 libvlc_event_send( p_md
->p_event_manager
, &event
);
641 /**************************************************************************
643 **************************************************************************/
644 libvlc_media_list_t
*
645 libvlc_media_subitems( libvlc_media_t
* p_md
)
647 libvlc_media_list_t
*p_subitems
= media_get_subitems( p_md
, true );
649 libvlc_media_list_retain( p_subitems
);
653 /**************************************************************************
654 * Getter for statistics information
655 **************************************************************************/
656 int libvlc_media_get_stats( libvlc_media_t
*p_md
,
657 libvlc_media_stats_t
*p_stats
)
659 if( !p_md
->p_input_item
)
662 input_stats_t
*p_itm_stats
= p_md
->p_input_item
->p_stats
;
663 vlc_mutex_lock( &p_itm_stats
->lock
);
664 p_stats
->i_read_bytes
= p_itm_stats
->i_read_bytes
;
665 p_stats
->f_input_bitrate
= p_itm_stats
->f_input_bitrate
;
667 p_stats
->i_demux_read_bytes
= p_itm_stats
->i_demux_read_bytes
;
668 p_stats
->f_demux_bitrate
= p_itm_stats
->f_demux_bitrate
;
669 p_stats
->i_demux_corrupted
= p_itm_stats
->i_demux_corrupted
;
670 p_stats
->i_demux_discontinuity
= p_itm_stats
->i_demux_discontinuity
;
672 p_stats
->i_decoded_video
= p_itm_stats
->i_decoded_video
;
673 p_stats
->i_decoded_audio
= p_itm_stats
->i_decoded_audio
;
675 p_stats
->i_displayed_pictures
= p_itm_stats
->i_displayed_pictures
;
676 p_stats
->i_lost_pictures
= p_itm_stats
->i_lost_pictures
;
678 p_stats
->i_played_abuffers
= p_itm_stats
->i_played_abuffers
;
679 p_stats
->i_lost_abuffers
= p_itm_stats
->i_lost_abuffers
;
681 p_stats
->i_sent_packets
= p_itm_stats
->i_sent_packets
;
682 p_stats
->i_sent_bytes
= p_itm_stats
->i_sent_bytes
;
683 p_stats
->f_send_bitrate
= p_itm_stats
->f_send_bitrate
;
684 vlc_mutex_unlock( &p_itm_stats
->lock
);
688 /**************************************************************************
690 **************************************************************************/
691 libvlc_event_manager_t
*
692 libvlc_media_event_manager( libvlc_media_t
* p_md
)
696 return p_md
->p_event_manager
;
699 /**************************************************************************
700 * Get duration of media object (in ms)
701 **************************************************************************/
703 libvlc_media_get_duration( libvlc_media_t
* p_md
)
707 if( !p_md
->p_input_item
)
709 libvlc_printerr( "No input item" );
713 if (!input_item_IsPreparsed( p_md
->p_input_item
))
716 return from_mtime(input_item_GetDuration( p_md
->p_input_item
));
719 static int media_parse(libvlc_media_t
*media
, bool b_async
,
720 libvlc_media_parse_flag_t parse_flag
)
724 vlc_mutex_lock(&media
->parsed_lock
);
725 needed
= !media
->has_asked_preparse
;
726 media
->has_asked_preparse
= true;
727 vlc_mutex_unlock(&media
->parsed_lock
);
731 libvlc_int_t
*libvlc
= media
->p_libvlc_instance
->p_libvlc_int
;
732 input_item_t
*item
= media
->p_input_item
;
733 input_item_meta_request_option_t art_scope
= META_REQUEST_OPTION_NONE
;
734 input_item_meta_request_option_t parse_scope
= META_REQUEST_OPTION_SCOPE_LOCAL
;
737 if (parse_flag
& libvlc_media_fetch_local
)
738 art_scope
|= META_REQUEST_OPTION_SCOPE_LOCAL
;
739 if (parse_flag
& libvlc_media_fetch_network
)
740 art_scope
|= META_REQUEST_OPTION_SCOPE_NETWORK
;
741 if (art_scope
!= META_REQUEST_OPTION_NONE
) {
742 ret
= libvlc_ArtRequest(libvlc
, item
, art_scope
);
743 if (ret
!= VLC_SUCCESS
)
747 if (parse_flag
& libvlc_media_parse_network
)
748 parse_scope
|= META_REQUEST_OPTION_SCOPE_NETWORK
;
749 ret
= libvlc_MetaRequest(libvlc
, item
, parse_scope
);
750 if (ret
!= VLC_SUCCESS
)
758 vlc_mutex_lock(&media
->parsed_lock
);
759 while (!media
->is_parsed
)
760 vlc_cond_wait(&media
->parsed_cond
, &media
->parsed_lock
);
761 vlc_mutex_unlock(&media
->parsed_lock
);
766 /**************************************************************************
767 * Parse the media and wait.
768 **************************************************************************/
770 libvlc_media_parse(libvlc_media_t
*media
)
772 media_parse( media
, false, libvlc_media_fetch_local
);
775 /**************************************************************************
776 * Parse the media but do not wait.
777 **************************************************************************/
779 libvlc_media_parse_async(libvlc_media_t
*media
)
781 media_parse( media
, true, libvlc_media_fetch_local
);
784 /**************************************************************************
785 * Parse the media asynchronously with options.
786 **************************************************************************/
788 libvlc_media_parse_with_options( libvlc_media_t
*media
,
789 libvlc_media_parse_flag_t parse_flag
)
791 return media_parse( media
, true, parse_flag
) == VLC_SUCCESS
? 0 : -1;
794 /**************************************************************************
795 * Get parsed status for media object.
796 **************************************************************************/
798 libvlc_media_is_parsed(libvlc_media_t
*media
)
802 vlc_mutex_lock(&media
->parsed_lock
);
803 parsed
= media
->is_parsed
;
804 vlc_mutex_unlock(&media
->parsed_lock
);
808 /**************************************************************************
809 * Sets media descriptor's user_data. user_data is specialized data
810 * accessed by the host application, VLC.framework uses it as a pointer to
811 * an native object that references a libvlc_media_t pointer
812 **************************************************************************/
814 libvlc_media_set_user_data( libvlc_media_t
* p_md
, void * p_new_user_data
)
817 p_md
->p_user_data
= p_new_user_data
;
820 /**************************************************************************
821 * Get media descriptor's user_data. user_data is specialized data
822 * accessed by the host application, VLC.framework uses it as a pointer to
823 * an native object that references a libvlc_media_t pointer
824 **************************************************************************/
826 libvlc_media_get_user_data( libvlc_media_t
* p_md
)
829 return p_md
->p_user_data
;
832 /**************************************************************************
833 * Get media descriptor's elementary streams description
834 **************************************************************************/
836 libvlc_media_get_tracks_info( libvlc_media_t
*p_md
, libvlc_media_track_info_t
** pp_es
)
840 input_item_t
*p_input_item
= p_md
->p_input_item
;
841 vlc_mutex_lock( &p_input_item
->lock
);
843 const int i_es
= p_input_item
->i_es
;
844 *pp_es
= (i_es
> 0) ? malloc( i_es
* sizeof(libvlc_media_track_info_t
) ) : NULL
;
846 if( !*pp_es
) /* no ES, or OOM */
848 vlc_mutex_unlock( &p_input_item
->lock
);
853 for( int i
= 0; i
< i_es
; i
++ )
855 libvlc_media_track_info_t
*p_mes
= *pp_es
+i
;
856 const es_format_t
*p_es
= p_input_item
->es
[i
];
858 p_mes
->i_codec
= p_es
->i_codec
;
859 p_mes
->i_id
= p_es
->i_id
;
861 p_mes
->i_profile
= p_es
->i_profile
;
862 p_mes
->i_level
= p_es
->i_level
;
868 p_mes
->i_type
= libvlc_track_unknown
;
871 p_mes
->i_type
= libvlc_track_video
;
872 p_mes
->u
.video
.i_height
= p_es
->video
.i_height
;
873 p_mes
->u
.video
.i_width
= p_es
->video
.i_width
;
876 p_mes
->i_type
= libvlc_track_audio
;
877 p_mes
->u
.audio
.i_channels
= p_es
->audio
.i_channels
;
878 p_mes
->u
.audio
.i_rate
= p_es
->audio
.i_rate
;
881 p_mes
->i_type
= libvlc_track_text
;
886 vlc_mutex_unlock( &p_input_item
->lock
);
891 libvlc_media_tracks_get( libvlc_media_t
*p_md
, libvlc_media_track_t
*** pp_es
)
895 input_item_t
*p_input_item
= p_md
->p_input_item
;
896 vlc_mutex_lock( &p_input_item
->lock
);
898 const int i_es
= p_input_item
->i_es
;
899 *pp_es
= (i_es
> 0) ? calloc( i_es
, sizeof(**pp_es
) ) : NULL
;
901 if( !*pp_es
) /* no ES, or OOM */
903 vlc_mutex_unlock( &p_input_item
->lock
);
908 for( int i
= 0; i
< i_es
; i
++ )
910 libvlc_media_track_t
*p_mes
= calloc( 1, sizeof(*p_mes
) );
913 p_mes
->audio
= malloc( __MAX(__MAX(sizeof(*p_mes
->audio
),
914 sizeof(*p_mes
->video
)),
915 sizeof(*p_mes
->subtitle
)) );
917 if ( !p_mes
|| !p_mes
->audio
)
919 libvlc_media_tracks_release( *pp_es
, i_es
);
922 vlc_mutex_unlock( &p_input_item
->lock
);
927 const es_format_t
*p_es
= p_input_item
->es
[i
];
929 p_mes
->i_codec
= p_es
->i_codec
;
930 p_mes
->i_original_fourcc
= p_es
->i_original_fourcc
;
931 p_mes
->i_id
= p_es
->i_id
;
933 p_mes
->i_profile
= p_es
->i_profile
;
934 p_mes
->i_level
= p_es
->i_level
;
936 p_mes
->i_bitrate
= p_es
->i_bitrate
;
937 p_mes
->psz_language
= p_es
->psz_language
!= NULL
? strdup(p_es
->psz_language
) : NULL
;
938 p_mes
->psz_description
= p_es
->psz_description
!= NULL
? strdup(p_es
->psz_description
) : NULL
;
944 p_mes
->i_type
= libvlc_track_unknown
;
947 p_mes
->i_type
= libvlc_track_video
;
948 p_mes
->video
->i_height
= p_es
->video
.i_height
;
949 p_mes
->video
->i_width
= p_es
->video
.i_width
;
950 p_mes
->video
->i_sar_num
= p_es
->video
.i_sar_num
;
951 p_mes
->video
->i_sar_den
= p_es
->video
.i_sar_den
;
952 p_mes
->video
->i_frame_rate_num
= p_es
->video
.i_frame_rate
;
953 p_mes
->video
->i_frame_rate_den
= p_es
->video
.i_frame_rate_base
;
956 p_mes
->i_type
= libvlc_track_audio
;
957 p_mes
->audio
->i_channels
= p_es
->audio
.i_channels
;
958 p_mes
->audio
->i_rate
= p_es
->audio
.i_rate
;
961 p_mes
->i_type
= libvlc_track_text
;
962 p_mes
->subtitle
->psz_encoding
= p_es
->subs
.psz_encoding
!= NULL
?
963 strdup(p_es
->subs
.psz_encoding
) : NULL
;
968 vlc_mutex_unlock( &p_input_item
->lock
);
972 /**************************************************************************
973 * Get codec description from media elementary stream
974 **************************************************************************/
976 libvlc_media_get_codec_description( libvlc_track_type_t i_type
,
981 case libvlc_track_audio
:
982 return vlc_fourcc_GetDescription( AUDIO_ES
, i_codec
);
983 case libvlc_track_video
:
984 return vlc_fourcc_GetDescription( VIDEO_ES
, i_codec
);
985 case libvlc_track_text
:
986 return vlc_fourcc_GetDescription( SPU_ES
, i_codec
);
987 case libvlc_track_unknown
:
989 return vlc_fourcc_GetDescription( UNKNOWN_ES
, i_codec
);
993 /**************************************************************************
994 * Release media descriptor's elementary streams description array
995 **************************************************************************/
996 void libvlc_media_tracks_release( libvlc_media_track_t
**p_tracks
, unsigned i_count
)
998 for( unsigned i
= 0; i
< i_count
; ++i
)
1002 free( p_tracks
[i
]->psz_language
);
1003 free( p_tracks
[i
]->psz_description
);
1004 switch( p_tracks
[i
]->i_type
)
1006 case libvlc_track_audio
:
1008 case libvlc_track_video
:
1010 case libvlc_track_text
:
1011 free( p_tracks
[i
]->subtitle
->psz_encoding
);
1013 case libvlc_track_unknown
:
1017 free( p_tracks
[i
]->audio
);
1018 free( p_tracks
[i
] );
1023 /**************************************************************************
1024 * Get the media type of the media descriptor object
1025 **************************************************************************/
1026 libvlc_media_type_t
libvlc_media_get_type( libvlc_media_t
*p_md
)
1031 input_item_t
*p_input_item
= p_md
->p_input_item
;
1033 vlc_mutex_lock( &p_input_item
->lock
);
1034 i_type
= p_md
->p_input_item
->i_type
;
1035 vlc_mutex_unlock( &p_input_item
->lock
);
1039 case ITEM_TYPE_FILE
:
1040 return libvlc_media_type_file
;
1041 case ITEM_TYPE_NODE
:
1042 case ITEM_TYPE_DIRECTORY
:
1043 return libvlc_media_type_directory
;
1044 case ITEM_TYPE_DISC
:
1045 return libvlc_media_type_disc
;
1046 case ITEM_TYPE_STREAM
:
1047 return libvlc_media_type_stream
;
1048 case ITEM_TYPE_PLAYLIST
:
1049 return libvlc_media_type_playlist
;
1051 return libvlc_media_type_unknown
;