From 2dfa55bd53357dc8bfcb6c94ec9a204dc9d3fe65 Mon Sep 17 00:00:00 2001 From: Jean-Paul Saman Date: Wed, 20 Dec 2006 22:11:54 +0000 Subject: [PATCH] Audio track and channel support for JavaScript API. The ActiveX vlc.audio.channel interface still has a bug left. --- activex/axvlc.idl | 4 +- activex/vlccontrol2.cpp | 19 +++-- include/vlc/libvlc.h | 22 +++--- mozilla/control/npolibvlc.cpp | 61 ++++++++++------ mozilla/control/npolibvlc.h | 6 +- src/control/audio.c | 129 ++++++++++++++++++++++++++-------- src/control/video.c | 10 +-- 7 files changed, 170 insertions(+), 81 deletions(-) diff --git a/activex/axvlc.idl b/activex/axvlc.idl index 4290902404..0d0054176d 100644 --- a/activex/axvlc.idl +++ b/activex/axvlc.idl @@ -205,9 +205,9 @@ library AXVLC [propput, helpstring("Returns/sets audio track used/to use.")] HRESULT track([in] long track); - [propget, helpstring("Returns audio channel: reverse, stereo, left, right, dolby.")] + [propget, helpstring("Returns audio channel: reverse stereo, stereo, left, right, dolby.")] HRESULT channel([out, retval] BSTR* channel); - [propput, helpstring("Sets audio channel to: reverse, stereo, left, right, dolby.")] + [propput, helpstring("Sets audio channel to: reverse stereo, stereo, left, right, dolby.")] HRESULT channel([in] BSTR channel); }; diff --git a/activex/vlccontrol2.cpp b/activex/vlccontrol2.cpp index 4a1669afbd..d60e71266d 100644 --- a/activex/vlccontrol2.cpp +++ b/activex/vlccontrol2.cpp @@ -211,7 +211,9 @@ STDMETHODIMP VLCAudio::get_track(long* track) libvlc_exception_t ex; libvlc_exception_init(&ex); - *track = libvlc_audio_get_track(p_libvlc, &ex); + libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex); + *track = libvlc_audio_get_track(p_input, &ex); + libvlc_input_free(p_input); if( libvlc_exception_raised(&ex) ) { _p_instance->setErrorInfo(IID_IVLCAudio, libvlc_exception_get_message(&ex)); @@ -232,7 +234,9 @@ STDMETHODIMP VLCAudio::put_track(long track) libvlc_exception_t ex; libvlc_exception_init(&ex); - libvlc_audio_set_track(p_libvlc, track, &ex); + libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex); + libvlc_audio_set_track(p_input, track, &ex); + libvlc_input_free(p_input); if( libvlc_exception_raised(&ex) ) { _p_instance->setErrorInfo(IID_IVLCAudio, libvlc_exception_get_message(&ex)); @@ -265,9 +269,11 @@ STDMETHODIMP VLCAudio::get_channel(BSTR *channel) *channel = BSTRFromCStr(CP_UTF8, psz_channel); free( psz_channel ); - return NOERROR; + psz_channel = NULL; + return (NULL == *channel) ? E_OUTOFMEMORY : NOERROR; } if( psz_channel ) free( psz_channel ); + psz_channel = NULL; _p_instance->setErrorInfo(IID_IVLCAudio, libvlc_exception_get_message(&ex)); libvlc_exception_clear(&ex); @@ -297,7 +303,6 @@ STDMETHODIMP VLCAudio::put_channel(BSTR channel) return E_OUTOFMEMORY; libvlc_audio_set_channel(p_libvlc, psz_channel, &ex); - CoTaskMemFree(psz_channel); if( libvlc_exception_raised(&ex) ) { @@ -2087,12 +2092,13 @@ STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect) if( NULL == psz_aspect ) return E_OUTOFMEMORY; - *aspect = SysAllocStringByteLen(psz_aspect, strlen(psz_aspect)); + *aspect = BSTRFromCStr(CP_UTF8, psz_aspect); free( psz_aspect ); psz_aspect = NULL; - return NOERROR; + return (NULL == *aspect) ? E_OUTOFMEMORY : NOERROR; } if( psz_aspect ) free( psz_aspect ); + psz_aspect = NULL; } _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex)); libvlc_exception_clear(&ex); @@ -2466,4 +2472,3 @@ STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj) } return E_OUTOFMEMORY; }; - diff --git a/include/vlc/libvlc.h b/include/vlc/libvlc.h index 12406a36c5..8e4c51eb21 100644 --- a/include/vlc/libvlc.h +++ b/include/vlc/libvlc.h @@ -492,33 +492,33 @@ int libvlc_audio_get_volume( libvlc_instance_t *, libvlc_exception_t * ); void libvlc_audio_set_volume( libvlc_instance_t *, int, libvlc_exception_t *); /** - * Get current audio track - * \param p_instance libvlc instance - * \param p_exception an initialized exception - * \return the audio track (int) - */ -int libvlc_audio_get_track( libvlc_instance_t *, libvlc_exception_t * ); ++ * Get current audio track ++ * \param p_input input instance ++ * \param p_exception an initialized exception ++ * \return the audio track (int) ++ */ +int libvlc_audio_get_track( libvlc_input_t *, libvlc_exception_t * ); /** * Set current audio track - * \param p_instance libvlc instance + * \param p_input input instance * \param i_track the track (int) * \param p_exception an initialized exception * \return void */ -void libvlc_audio_set_track( libvlc_instance_t *, int, libvlc_exception_t * ); +void libvlc_audio_set_track( libvlc_input_t *, int, libvlc_exception_t * ); /** * Get current audio channel - * \param p_instance libvlc instance + * \param p_instance input instance * \param p_exception an initialized exception * \return the audio channel (char *) */ char *libvlc_audio_get_channel( libvlc_instance_t *, libvlc_exception_t * ); /** - * Set current audio track - * \param p_instance libvlc instance + * Set current audio channel + * \param p_instance input instance * \param psz_channel the audio channel (char *) * \param p_exception an initialized exception * \return void diff --git a/mozilla/control/npolibvlc.cpp b/mozilla/control/npolibvlc.cpp index 597c21b1bb..1221d7fd87 100755 --- a/mozilla/control/npolibvlc.cpp +++ b/mozilla/control/npolibvlc.cpp @@ -199,11 +199,20 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVari libvlc_exception_t ex; libvlc_exception_init(&ex); + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + switch( index ) { case ID_audio_mute: { vlc_bool_t muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex); + libvlc_input_free(p_input); if( libvlc_exception_raised(&ex) ) { NPN_SetException(this, libvlc_exception_get_message(&ex)); @@ -216,6 +225,7 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVari case ID_audio_volume: { int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex); + libvlc_input_free(p_input); if( libvlc_exception_raised(&ex) ) { NPN_SetException(this, libvlc_exception_get_message(&ex)); @@ -227,7 +237,8 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVari } case ID_audio_track: { - int track = libvlc_audio_get_track(p_plugin->getVLC(), &ex); + int track = libvlc_audio_get_track(p_input, &ex); + libvlc_input_free(p_input); if( libvlc_exception_raised(&ex) ) { NPN_SetException(this, libvlc_exception_get_message(&ex)); @@ -239,35 +250,24 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVari } case ID_audio_channel: { - char *channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex); + NPUTF8 *psz_channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex); + libvlc_input_free(p_input); if( libvlc_exception_raised(&ex) ) { NPN_SetException(this, libvlc_exception_get_message(&ex)); libvlc_exception_clear(&ex); return INVOKERESULT_GENERIC_ERROR; } - if( channel ) - { - int len = strlen(channel); - NPUTF8 *retval = (NPUTF8*)NPN_MemAlloc(len); - if( retval ) - { - memcpy(retval, channel, len); - STRINGN_TO_NPVARIANT(retval, len, result); - } - else - { - NULL_TO_NPVARIANT(result); - } - free( channel ); - channel = NULL; - return INVOKERESULT_NO_ERROR; - } - return INVOKERESULT_NO_SUCH_METHOD; + if( !psz_channel ) + return INVOKERESULT_GENERIC_ERROR; + + STRINGZ_TO_NPVARIANT(psz_channel, result); + return INVOKERESULT_NO_ERROR; } default: ; } + libvlc_input_free(p_input); } return INVOKERESULT_GENERIC_ERROR; } @@ -280,6 +280,14 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const libvlc_exception_t ex; libvlc_exception_init(&ex); + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + switch( index ) { case ID_audio_mute: @@ -287,6 +295,7 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const { libvlc_audio_set_mute(p_plugin->getVLC(), NPVARIANT_TO_BOOLEAN(value), &ex); + libvlc_input_free(p_input); if( libvlc_exception_raised(&ex) ) { NPN_SetException(this, libvlc_exception_get_message(&ex)); @@ -297,6 +306,7 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const } return INVOKERESULT_INVALID_VALUE; case ID_audio_volume: + libvlc_input_free(p_input); if( isNumberValue(value) ) { libvlc_audio_set_volume(p_plugin->getVLC(), @@ -313,8 +323,9 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const case ID_audio_track: if( isNumberValue(value) ) { - libvlc_audio_set_track(p_plugin->getVLC(), + libvlc_audio_set_track(p_input, numberValue(value), &ex); + libvlc_input_free(p_input); if( libvlc_exception_raised(&ex) ) { NPN_SetException(this, libvlc_exception_get_message(&ex)); @@ -323,15 +334,15 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const } return INVOKERESULT_NO_ERROR; } + libvlc_input_free(p_input); return INVOKERESULT_INVALID_VALUE; case ID_audio_channel: { char *psz_channel = NULL; + libvlc_input_free(p_input); if( ! NPVARIANT_IS_STRING(value) ) - { return INVOKERESULT_INVALID_VALUE; - } psz_channel = stringValue(NPVARIANT_TO_STRING(value)); if( !psz_channel ) @@ -352,6 +363,7 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const default: ; } + libvlc_input_free(p_input); } return INVOKERESULT_GENERIC_ERROR; } @@ -1900,7 +1912,10 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::setProperty(int index, const psz_aspect = stringValue(NPVARIANT_TO_STRING(value)); if( !psz_aspect ) + { + libvlc_input_free(p_input); return INVOKERESULT_GENERIC_ERROR; + } libvlc_video_set_aspect_ratio(p_input, psz_aspect, &ex); if( psz_aspect ) diff --git a/mozilla/control/npolibvlc.h b/mozilla/control/npolibvlc.h index d9f635fb01..b0639ff580 100755 --- a/mozilla/control/npolibvlc.h +++ b/mozilla/control/npolibvlc.h @@ -80,7 +80,7 @@ protected: LibvlcInputNPObject(NPP instance, const NPClass *aClass) : RuntimeNPObject(instance, aClass) {}; - + virtual ~LibvlcInputNPObject() {}; static const int propertyCount; @@ -106,7 +106,7 @@ protected: LibvlcMessageNPObject(NPP instance, const NPClass *aClass) : RuntimeNPObject(instance, aClass) {}; - + virtual ~LibvlcMessageNPObject() {}; static const int propertyCount; @@ -152,7 +152,7 @@ protected: LibvlcMessagesNPObject(NPP instance, const NPClass *aClass) : RuntimeNPObject(instance, aClass) {}; - + virtual ~LibvlcMessagesNPObject() {}; static const int propertyCount; diff --git a/src/control/audio.c b/src/control/audio.c index 52033cadc9..f6b7bdc619 100644 --- a/src/control/audio.c +++ b/src/control/audio.c @@ -25,8 +25,56 @@ #include "libvlc_internal.h" #include +#include #include +/* + * Remember to release the returned input_thread_t since it is locked at + * the end of this function. + */ +static input_thread_t *GetInput( libvlc_input_t *p_input, + libvlc_exception_t *p_exception ) +{ + input_thread_t *p_input_thread = NULL; + + if( !p_input ) + { + libvlc_exception_raise( p_exception, "Input is NULL" ); + return NULL; + } + + p_input_thread = (input_thread_t*)vlc_object_get( + p_input->p_instance->p_libvlc_int, + p_input->i_input_id ); + if( !p_input_thread ) + { + libvlc_exception_raise( p_exception, "Input does not exist" ); + return NULL; + } + + return p_input_thread; +} + +/* + * Remember to release the returned aout_instance_t since it is locked at + * the end of this function. + */ +static aout_instance_t *GetAOut( libvlc_instance_t *p_instance, + libvlc_exception_t *p_exception ) +{ + aout_instance_t * p_aout = NULL; + + p_aout = vlc_object_find( p_instance->p_libvlc_int, VLC_OBJECT_AOUT, FIND_CHILD ); + if( !p_aout ) + { + libvlc_exception_raise( p_exception, "No active audio output" ); + return NULL; + } + + return p_aout; +} + + /***************************************************************************** * libvlc_audio_get_mute : Get the volume state, true if muted *****************************************************************************/ @@ -94,12 +142,14 @@ void libvlc_audio_set_volume( libvlc_instance_t *p_instance, int i_volume, /***************************************************************************** * libvlc_audio_get_track : Get the current audio track *****************************************************************************/ -int libvlc_audio_get_track( libvlc_instance_t *p_instance, +int libvlc_audio_get_track( libvlc_input_t *p_input, libvlc_exception_t *p_e ) { + input_thread_t *p_input_thread = GetInput( p_input, p_e ); int i_track = 0; - i_track = var_GetInteger( p_instance->p_libvlc_int, "audio-track" ); + i_track = var_GetInteger( p_input_thread, "audio-es" ); + vlc_object_release( p_input_thread ); return i_track; } @@ -107,17 +157,31 @@ int libvlc_audio_get_track( libvlc_instance_t *p_instance, /***************************************************************************** * libvlc_audio_set_track : Set the current audio track *****************************************************************************/ -void libvlc_audio_set_track( libvlc_instance_t *p_instance, int i_track, +void libvlc_audio_set_track( libvlc_input_t *p_input, int i_track, libvlc_exception_t *p_e ) { + input_thread_t *p_input_thread = GetInput( p_input, p_e ); + vlc_value_t val_list; int i_ret = -1; + int i; - i_ret = var_SetInteger( p_instance->p_libvlc_int, "audio-track", i_track ); - - if( i_ret < 0 ) + var_Change( p_input_thread, "audio-es", VLC_VAR_GETCHOICES, &val_list, NULL ); + for( i = 0; i < val_list.p_list->i_count; i++ ) { - libvlc_exception_raise( p_e, "Setting audio track failed" ); + vlc_value_t val = val_list.p_list->p_values[i]; + if( i_track == val.i_int ) + { + i_ret = var_SetInteger( p_input_thread, "audio-es", i_track ); + if( i_ret < 0 ) + { + libvlc_exception_raise( p_e, "Setting audio track failed" ); + } + vlc_object_release( p_input_thread ); + return; + } } + libvlc_exception_raise( p_e, "Audio track out of range" ); + vlc_object_release( p_input_thread ); } /***************************************************************************** @@ -126,14 +190,15 @@ void libvlc_audio_set_track( libvlc_instance_t *p_instance, int i_track, char *libvlc_audio_get_channel( libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) { + aout_instance_t *p_aout = GetAOut( p_instance, p_e ); char *psz_channel = NULL; - int i_channel = 0; + vlc_value_t val; - i_channel = var_GetInteger( p_instance->p_libvlc_int, "audio-channel" ); - switch( i_channel ) + var_Get( p_aout, "audio-channels", &val ); + switch( val.i_int ) { case AOUT_VAR_CHAN_RSTEREO: - psz_channel = strdup("reverse"); + psz_channel = strdup("reverse stereo"); break; case AOUT_VAR_CHAN_STEREO: psz_channel = strdup("stereo"); @@ -151,6 +216,7 @@ char *libvlc_audio_get_channel( libvlc_instance_t *p_instance, psz_channel = strdup("disabled"); break; } + vlc_object_release( p_aout ); return psz_channel; } @@ -160,30 +226,33 @@ char *libvlc_audio_get_channel( libvlc_instance_t *p_instance, void libvlc_audio_set_channel( libvlc_instance_t *p_instance, char *psz_channel, libvlc_exception_t *p_e ) { - int i_ret = -1; - int i_channel = 0; + aout_instance_t *p_aout = GetAOut( p_instance, p_e ); + vlc_value_t val_list, text_list; + int i_ret = -1, i; - if( !psz_channel ) + i_ret = var_Change( p_aout, "audio-channels", VLC_VAR_GETCHOICES, &val_list, &text_list ); + if( (i_ret < 0) || !psz_channel ) { - libvlc_exception_raise( p_e, "Audio track out of range" ); + libvlc_exception_raise( p_e, "Audio channel out of range" ); + vlc_object_release( p_aout ); + return; } - else + + for( i = 0; i < val_list.p_list->i_count; i++ ) { - if( strncmp( psz_channel, "reverse", 7 ) == 0 ) - i_channel = AOUT_VAR_CHAN_RSTEREO; - else if( strncmp( psz_channel, "stereo", 6 ) == 0 ) - i_channel = AOUT_VAR_CHAN_STEREO; - else if( strncmp( psz_channel, "left", 4 ) == 0 ) - i_channel = AOUT_VAR_CHAN_LEFT; - else if( strncmp( psz_channel, "right", 5 ) == 0 ) - i_channel = AOUT_VAR_CHAN_RIGHT; - else if( strncmp( psz_channel, "dolby", 5 ) == 0 ) - i_channel = AOUT_VAR_CHAN_DOLBYS; - - i_ret = var_SetInteger( p_instance->p_libvlc_int, "audio-channel", i_channel ); - if( i_ret < 0 ) + vlc_value_t val = val_list.p_list->p_values[i]; + vlc_value_t text = text_list.p_list->p_values[i]; + + if( strncasecmp( psz_channel, text.psz_string, strlen(text.psz_string) ) == 0 ) { - libvlc_exception_raise( p_e, "Audio track out of range" ); + i_ret = var_Set( p_aout, "audio-channels", val ); + if( i_ret < 0 ) + { + break; + } } } + libvlc_exception_raise( p_e, "Audio channel out of range" ); + vlc_object_release( p_aout ); } + diff --git a/src/control/video.c b/src/control/video.c index 371739f645..d6d850bbf1 100644 --- a/src/control/video.c +++ b/src/control/video.c @@ -200,10 +200,10 @@ vlc_bool_t libvlc_input_has_vout( libvlc_input_t *p_input, if ( libvlc_exception_raised( p_e ) ) { if ( strcmp( "No active video output", libvlc_exception_get_message( p_e ) ) == 0 ) - { - libvlc_exception_clear( p_e ); - } - return VLC_FALSE; + { + libvlc_exception_clear( p_e ); + } + return VLC_FALSE; } vlc_object_release( p_vout ); @@ -221,7 +221,7 @@ int libvlc_video_reparent( libvlc_input_t *p_input, libvlc_drawable_t d, /// \todo: set exception return 0; } - + vout_Control( p_vout , VOUT_REPARENT, d); vlc_object_release( p_vout ); -- 2.39.2