From ddadc36097da1ecd2c68a55ca5b6c65b387be3da Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 4 May 2015 19:13:50 +0200 Subject: Autodetect VLC version --- src/VLCInput.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/VLCInput.cpp b/src/VLCInput.cpp index 5115c53..70381fb 100644 --- a/src/VLCInput.cpp +++ b/src/VLCInput.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include "VLCInput.h" @@ -28,11 +29,12 @@ #include +int check_vlc_uses_size_t(); using namespace std; // VLC Audio prerender callback -void prepareRender( +void prepareRender_size_t( void* p_audio_data, uint8_t** pp_pcm_buffer, size_t size) @@ -42,9 +44,19 @@ void prepareRender( in->preRender_cb(pp_pcm_buffer, size); } +void prepareRender( + void* p_audio_data, + uint8_t** pp_pcm_buffer, + unsigned int size) +{ + VLCInput* in = (VLCInput*)p_audio_data; + + in->preRender_cb(pp_pcm_buffer, size); +} + // Audio postrender callback -void handleStream( +void handleStream_size_t( void* p_audio_data, uint8_t* p_pcm_buffer, unsigned int channels, @@ -66,6 +78,28 @@ void handleStream( in->postRender_cb(); } +// convert from unsigned int size to size_t size +void handleStream( + void* p_audio_data, + uint8_t* p_pcm_buffer, + unsigned int channels, + unsigned int rate, + unsigned int nb_samples, + unsigned int bits_per_sample, + unsigned int size, + int64_t pts) +{ + handleStream_size_t( + p_audio_data, + p_pcm_buffer, + channels, + rate, + nb_samples, + bits_per_sample, + size, + pts); +} + // VLC Exit callback void handleVLCExit(void* opaque) { @@ -77,6 +111,29 @@ int VLCInput::prepare() int err; fprintf(stderr, "Initialising VLC...\n"); + long long int handleStream_address; + long long int prepareRender_address; + + int vlc_version_check = check_vlc_uses_size_t(); + if (vlc_version_check == 0) { + fprintf(stderr, "You are using VLC with unsigned int size callbacks\n"); + + handleStream_address = (long long int)(intptr_t)(void*)&handleStream; + prepareRender_address = (long long int)(intptr_t)(void*)&prepareRender; + } + else if (vlc_version_check == 1) { + fprintf(stderr, "You are using VLC with size_t size callbacks\n"); + + handleStream_address = (long long int)(intptr_t)(void*)&handleStream_size_t; + prepareRender_address = (long long int)(intptr_t)(void*)&prepareRender_size_t; + } + else { + fprintf(stderr, "Error detecting VLC version!\n"); + fprintf(stderr, " you are using %s\n", libvlc_get_version()); + return -1; + } + + // VLC options char smem_options[512]; snprintf(smem_options, sizeof(smem_options), @@ -89,8 +146,8 @@ int VLCInput::prepare() "audio-data=%lld" "}", m_rate, - (long long int)(intptr_t)(void*)&handleStream, - (long long int)(intptr_t)(void*)&prepareRender, + handleStream_address, + prepareRender_address, (long long int)(intptr_t)this); char verb_options[512]; @@ -244,5 +301,42 @@ void VLCInput::write_icy_text(const std::string& filename) const fclose(fd); } +/* VLC up to version 2.1.0 used a different callback function signature. + * VLC 2.2.0 uses size_t + * + * \return 1 if the callback with size_t size should be used. + * 0 if the callback with unsigned int size should be used. + * -1 if there was an error. + */ +int check_vlc_uses_size_t() +{ + int retval = -1; + + char libvlc_version[256]; + strncpy(libvlc_version, libvlc_get_version(), 256); + + char *space_position = strstr(libvlc_version, " "); + + if (space_position) { + *space_position = '\0'; + } + + char *saveptr; + char *major_ver_sz = strtok_r(libvlc_version, ".", &saveptr); + if (major_ver_sz) { + int major_ver = atoi(major_ver_sz); + + char *minor_ver_sz = strtok_r(NULL, ".", &saveptr); + if (minor_ver_sz) { + int minor_ver = atoi(minor_ver_sz); + + retval = (major_ver >= 2 && minor_ver >= 2) ? 1 : 0; + } + } + + return retval; +} + + #endif // HAVE_VLC -- cgit v1.2.3