- Apr 17, 2025
-
-
Diogo Simao Marques authored
This helper allows to properly select a track of a given type at a given index. If a track of the same type is already selected, it will be replaced by the new one.
-
- Feb 08, 2025
-
-
- Jan 10, 2025
-
-
- Dec 05, 2024
-
-
Picture in Picture in libvlc now require to dispatch an event when seeking is finished and needs to know if the played media is seekable. An API change in VLCMediaPlayer allows VLCKit users to pass a dispatch block that will be called when seeking is complete. Picture in Picture example is also updated to work with these changes.
-
- Oct 02, 2024
-
-
Maxime Chapelet authored
-
-
Maxime Chapelet authored
-
- Jul 01, 2024
-
-
Felix Paul Kühne authored
-
- Apr 14, 2024
-
-
Hank Anderson authored
-
- Mar 21, 2024
-
-
Felix Paul Kühne authored
-
Felix Paul Kühne authored
-
- Mar 19, 2024
-
-
Felix Paul Kühne authored
-
- Mar 17, 2024
-
-
Felix Paul Kühne authored
-
Felix Paul Kühne authored
This removes the forks for iOS and tvOS to achieve a universal API
-
-
Felix Paul Kühne authored
This moves both sources and headers to new designated places and groups
-
- Feb 18, 2024
-
-
Felix Paul Kühne authored
-
- Nov 07, 2023
-
-
Hank Anderson authored
Related to vlc@12fa8556.
-
- Oct 08, 2023
-
-
- Sep 24, 2023
-
-
Hank Anderson authored
-
Hank Anderson authored
-
- Sep 18, 2023
-
-
Hank Anderson authored
VLCMediaPlayerDelegate: Rename from recordingStoppedAtPath to recordingStoppedAtURL If recording fails, return url as nil
-
- Sep 16, 2023
-
-
- Aug 09, 2023
-
-
Felix Paul Kühne authored
Manual forward-port of 2108244f
-
- Jun 14, 2023
-
-
Maxime Chapelet authored
With this proposal VLCKit will provide a new mechanism to configure events dispatch. Any configuration can be provided with the use of the introduction of the `VLCEventsConfiguring` protocol: ```objectivec @protocol VLCEventsConfiguring <NSObject> - (dispatch_queue_t _Nullable) dispatchQueue; - (BOOL) isAsync; @end ``` Any configuration can be set globally with `+[VLCLibrary sharedEventsConfiguration]`. `VLCEventsDefaultConfiguration` is set when `VLCLibrary` class loads at runtime. ```objectivec @implementation VLCEventsDefaultConfiguration - (dispatch_queue_t _Nullable)dispatchQueue { return nil; } - (BOOL)isAsync { return NO; } @end ``` The above implementation tells the events to be dispatched synchronously from any callback's calling threads. Another `VLCEventsLegacyConfiguration` is available if any client needs to use the former events dispatching mechanism. ```objectivec @implementation VLCEventsLegacyConfiguration - (dispatch_queue_t _Nullable)dispatchQueue { return dispatch_get_main_queue(); } - (BOOL)isAsync { return YES; } @end ``` The above implementation tells the events to be dispatched asynchronously on the global main thread's queue. This one would be of great help when we would like to migrate to VLCKit 4 when we're already using VLCKit 3. The configuration will be used in `-[VLCEventsHandler handleEvent:]` implementation : ```objectivec - (void)handleEvent:(void (^)(id))handle { ///[truncated] dispatch_block_t block = ^{handle(object);}; if (_configuration.dispatchQueue) { if (_configuration.isAsync) dispatch_async(_configuration.dispatchQueue, block); else dispatch_sync(_configuration.dispatchQueue, block); } else { block(); } ///[truncated] } ```
-
Maxime Chapelet authored
Internally, libvlc sends events using the internal function `libvlc_event_send` on a `libvlc_event_manager_t` reference. An iteration over an array of listeners created with `libvlc_event_attach` on the `libvlc_event_manager_t` is performed while a `libvlc_event_manager_t::lock mutex` is locked. VLCKit objects attach themselves to various events on their initialisation phase. VLCKit objects detach themselves from those events once the VLCKit object references count reach 0 and deallocation phase is triggered. `libvlc_event_manager_t::lock mutex` is also locked when `libvlc_event_detach` is called. This means detaching events always waits for any currently performed callback event. --- An event callback implementation in VLCKit can actually be illustrated like this : ```objectivec static void AnyEventCallback(const libvlc_event_t * event, void* opaque) { @autoreleasepool { VLCKitObject *obj = (__bridge VLCKitObject *)opaque; dispatch_async(dispatch_get_main_queue(), ^{ [obj doSomething]; }); } } ``` But considering at the same time : - `VLCKitObject *obj` can be either in an allocated or deallocating state when bridge assignement is performed by `VLCKitObject *obj = (__bridge VLCKitObject *)opaque` - `VLCKitObject *obj` refcount can reach 0 from any other thread hence it's deallocation can be initiated from any other thread - `VLCKitObject *obj` reference is used asynchronously on main thread to send a `doSomething` message but `VLCKitObject *obj` can be in a deallocating state So here we’re facing a situation where an `EXC_BAD_ACCESS` would happen once an attempt to perform any `(__bridge MyObject *)opaque` or send message on `VLCKitObject *obj` is done when it becomes an object in a deallocated/deallocating state. We can then be tempted to try this strategy : ```objectivec static void AnyEventCallback(const libvlc_event_t * event, void* opaque) { @autoreleasepool { __weak VLCKitObject *weak_obj = (__bridge VLCKitObject *)opaque; dispatch_async(dispatch_get_main_queue(), ^{ __strong VLCKitObject *strong_obj = weak_obj; [strong_obj doSomething]; }); } } ``` But once we run this, a `SIGABRT` would reach us with : ``` objc[10281]: Cannot form weak reference to instance (0x28266b040) of class VLCKitObject. It is possible that this object was over-released, or is in the process of deallocation. ``` So the idea of this patch is to provide a new mechanism to handle the events where `_bridge` cast of `void *opaque` never lead to an `EXC_BAD_ACCESS`. By the way, another situation have to be considered. To prevent this `EXC_BAD_ACCESS` issue, we have to prevent the `VLCKitObject *obj` to enter in a deallocating state from another thread. The only option to achieve that is to find a way to keep a strong reference to the `VLCKitObject *obj` while we're using it in the event's callback's scope. Hence given we enter a callback and the `VLCKitObject *obj` is still allocated, it makes sense that it would be possible that a deallocation will be triggered from the callback's calling thread. Here's a reminder of the new problem we would get: - A `VLCKitObject*`, if not nil when assigned in a callback, will have to be strongly referenced to not be deallocated from another thread, hence it will be deallocated from the callback's calling thread if the refcount reaches 0 when going out of it's scope - A `-[VLCKitObject dealloc]` call will trigger `libvlc_event_detach` - Given a callback is called, the `libvlc_event_manager_t::lock mutex` is locked - Given an event is detached with `libvlc_event_detach`, the `libvlc_event_manager_t::lock mutex` is locked It means in the callback calling thread we would potentially get this kind of call stack : `lock(mutex)` => `AnyEventCallback` => `-[VLCKitObject dealloc]` => `libvlc_event_detach` => `lock(mutex)` A recursive deadlock issue would be introduced if we keep a strong reference of a `VLCKitObject*` and allow its deallocation from any callback's calling thread. --- The introduction of the new `VLCEventsHandler` object should perform a proper memory management which would help to to prevent any previously enumerated corner cases. Any VLCKit object that observe libvlc events owns a strong reference to his `VLCEventsHandler` object and use it as a replacement for any callback user data, hence it's deallocated after all event callbacks are detached from vlc objects. This is how VLCKit object reference memory management is handled : ```objectivec @interface VLCEventsHandler : NSObject ///[truncated] @property (nonatomic, readonly, weak) id _Nullable object; ///[truncated] @end ``` ```objectivec @implementation VLCEventsHandler { ///[truncated] /// Queue used to release asynchronously the retained object dispatch_queue_t _releaseQueue; } ///[truncated] - (void)handleEvent:(void (^)(id))handle { __block id object = _object; // We keep a strong reference and make it mutable in a block if (!object) { // We check if already deallocated return; // Object seems already deallocated, no need to handle the event } ///[truncated] dispatch_async(_releaseQueue, ^{ object = nil; // We decrease object refcount in another thread, potentially triggering a deallocation if refcount reaches 0 }); } ///[truncated] @end ``` In the above code any `VLCEventsHandler` weakly references its related VLCKit object and pass it, if not nil, as strong reference to the block parameter in any `-[VLCEventsHandler handleEvent:]` call. The `VLCEventsHandler` uses an internal queue to release the VLCKit object strong reference asynchronously, which helps to prevent the `libvlc_event_manager_t` mutex deadlock given a deallocation would happen on any callback calling thread.
-
- Feb 20, 2023
-
-
Alexandre Janniaux authored
When the player is changing state, the delegate doesn't care about receiving an NSNotification or knowing from which player it was triggered, but it will need to know the new state from the player. It prevents calling libvlc methods from the callback, which is usually forbidden and works only because of the dispatch_async.
-
Alexandre Janniaux authored
The event signalling a change of media length is not a state change and should be reported separately with the correct metadata.
-
Alexandre Janniaux authored
Add mediaPlayerTrackSelected API to signal changes reported from the libvlc_media_player_t object. For now, it mimics the API, by just transforming raw char strings into NSString, but it should be improved to report VLCMediaTrack instead. The blocker for reporting VLCMediaTrack is that libvlc_media_track_t are not reported by the media player as events currently, so it's not possible to get a matching libvlc object, which makes it impossible to get the matching VLCKit object without duplicating them.
-
Alexandre Janniaux authored
Add mediaPlayerTrackAdded/Updated/Removed API to signal changes reported from the libvlc_media_player_t object. For now, it mimics the API, by just transforming raw char strings into NSString, but it should be improved to report VLCMediaTrack instead. The blocker for reporting VLCMediaTrack is that libvlc_media_track_t are not reported by the media player as events currently, so it's not possible to get a matching libvlc object, which makes it impossible to get the matching VLCKit object without duplicating them.
-
ESAdded/Delete are not VLCMediaPlayer states.
-
- Feb 16, 2023
-
-
Hank Anderson authored
-
Hank Anderson authored
-
Hank Anderson authored
-
- Feb 15, 2023
-
-
`parseWithOptions` is provided through multiple selectors allowing default values to be provided in most cases. Refactor the documentation so that the specialized variants are referencing the more general variant and document the most general one.
-
Now that preparsing doesn't depend on a library assigned to the VLCMedia object but directly from the libvlc_instance_t used, the user might want to alter the parameters by providing their own VLCLibrary object, until a better API is made for VLCKit.
-
- Feb 08, 2023
-
-
- Jan 17, 2023
-
-