summaryrefslogtreecommitdiffstats
path: root/libtoolame-dab/vlc_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtoolame-dab/vlc_input.c')
-rw-r--r--libtoolame-dab/vlc_input.c430
1 files changed, 0 insertions, 430 deletions
diff --git a/libtoolame-dab/vlc_input.c b/libtoolame-dab/vlc_input.c
deleted file mode 100644
index 11e04c7..0000000
--- a/libtoolame-dab/vlc_input.c
+++ /dev/null
@@ -1,430 +0,0 @@
-#include "vlc_input.h"
-
-#if defined(VLC_INPUT)
-#include <stdlib.h>
-#include <errno.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-int check_vlc_uses_size_t();
-struct vlc_buffer* vlc_buffer_new();
-void vlc_buffer_free(struct vlc_buffer* node);
-
-libvlc_instance_t *m_vlc;
-libvlc_media_player_t *m_mp;
-
-unsigned int vlc_rate;
-unsigned int vlc_channels;
-
-struct vlc_buffer *head_buffer;
-
-// now playing information can get written to
-// a file. This writing happens in a separate thread
-#define NOWPLAYING_LEN 512
-char vlc_nowplaying[NOWPLAYING_LEN];
-int vlc_nowplaying_running;
-pthread_t vlc_nowplaying_thread;
-const char* vlc_nowplaying_filename;
-
-struct icywriter_task_data {
- char text[NOWPLAYING_LEN];
- int success;
- sem_t sem;
-};
-
-struct icywriter_task_data icy_task_data;
-
-
-pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER;
-
-struct vlc_buffer* vlc_buffer_new()
-{
- struct vlc_buffer* node;
- node = malloc(sizeof(struct vlc_buffer));
- memset(node, 0, sizeof(struct vlc_buffer));
- return node;
-}
-
-void vlc_buffer_free(struct vlc_buffer* node)
-{
- if (node->buf) {
- free(node->buf);
- }
-
- free(node);
-}
-
-size_t vlc_buffer_totalsize(struct vlc_buffer* node)
-{
- size_t totalsize = 0;
- for (; node != NULL; node = node->next) {
- totalsize += node->size;
- }
-
- return totalsize;
-}
-
-// VLC Audio prerender callback, we must allocate a buffer here
-void prepareRender_size_t(
- void* p_audio_data,
- uint8_t** pp_pcm_buffer,
- size_t size)
-{
- *pp_pcm_buffer = malloc(size);
-}
-
-void prepareRender(
- void* p_audio_data,
- uint8_t** pp_pcm_buffer,
- unsigned int size)
-{
- *pp_pcm_buffer = malloc(size);
-}
-
-
-// Audio postrender callback
-void handleStream_size_t(
- void* p_audio_data,
- uint8_t* p_pcm_buffer,
- unsigned int channels,
- unsigned int rate,
- unsigned int nb_samples,
- unsigned int bits_per_sample,
- size_t size,
- int64_t pts)
-{
- assert(channels == vlc_channels);
- assert(rate == vlc_rate);
- assert(bits_per_sample == 16);
-
- // 16 is a bit arbitrary, if it's too small we might enter
- // a deadlock if toolame asks for too much data
- const size_t max_length = 16 * size;
-
- for (;;) {
- pthread_mutex_lock(&buffer_lock);
-
- if (vlc_buffer_totalsize(head_buffer) < max_length) {
- struct vlc_buffer* newbuf = vlc_buffer_new();
-
- newbuf->buf = p_pcm_buffer;
- newbuf->size = size;
-
- // Append the new buffer to the end of the linked list
- struct vlc_buffer* tail = head_buffer;
- while (tail->next) {
- tail = tail->next;
- }
- tail->next = newbuf;
-
- pthread_mutex_unlock(&buffer_lock);
- return;
- }
-
- pthread_mutex_unlock(&buffer_lock);
- usleep(100);
- }
-}
-
-// 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);
-}
-
-int vlc_in_prepare(
- unsigned verbosity,
- unsigned int rate,
- const char* uri,
- unsigned channels,
- const char* icy_write_file
- )
-{
- fprintf(stderr, "Initialising VLC...\n");
-
- vlc_nowplaying_running = 0;
- vlc_nowplaying_filename = icy_write_file;
-
- 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_rate = rate;
- vlc_channels = channels;
-
- // VLC options
- char smem_options[512];
- snprintf(smem_options, sizeof(smem_options),
- "#transcode{acodec=s16l,samplerate=%d}:"
- // We are using transcode because smem only support raw audio and
- // video formats
- "smem{"
- "audio-postrender-callback=%lld,"
- "audio-prerender-callback=%lld"
- "}",
- vlc_rate,
- handleStream_address,
- prepareRender_address);
-
- char verb_options[512];
- snprintf(verb_options, sizeof(verb_options),
- "--verbose=%d", verbosity);
-
- const char * const vlc_args[] = {
- verb_options,
- "--sout", smem_options // Stream to memory
- };
-
- // Launch VLC
- m_vlc = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
-
- // Load the media
- libvlc_media_t *m;
- m = libvlc_media_new_location(m_vlc, uri);
- m_mp = libvlc_media_player_new_from_media(m);
- libvlc_media_release(m);
-
- // Allocate the list
- head_buffer = vlc_buffer_new();
-
- // Start playing
- int ret = libvlc_media_player_play(m_mp);
-
- if (ret == 0) {
- libvlc_media_t *media = libvlc_media_player_get_media(m_mp);
- libvlc_state_t st;
-
- ret = -1;
-
- int timeout;
- for (timeout = 0; timeout < 100; timeout++) {
- st = libvlc_media_get_state(media);
- usleep(10*1000);
- if (st != libvlc_NothingSpecial) {
- ret = 0;
- break;
- }
- }
- }
-
- return ret;
-}
-
-ssize_t vlc_in_read(void *buf, size_t len)
-{
- if (len == 0) {
- return 0;
- }
-
- assert(buf);
-
- size_t requested = len;
- for (;;) {
- pthread_mutex_lock(&buffer_lock);
-
- if (vlc_buffer_totalsize(head_buffer) >= len) {
- while (len >= head_buffer->size) {
- if (head_buffer->buf && head_buffer->size) {
- // Get all the data from this list element
- memcpy(buf, head_buffer->buf, head_buffer->size);
-
- buf += head_buffer->size;
- len -= head_buffer->size;
- }
-
- if (head_buffer->next) {
- struct vlc_buffer *next_head = head_buffer->next;
- vlc_buffer_free(head_buffer);
- head_buffer = next_head;
- }
- else {
- vlc_buffer_free(head_buffer);
- head_buffer = vlc_buffer_new();
- break;
- }
- }
-
- if (len > 0) {
- assert(len < head_buffer->size);
- assert(head_buffer->buf);
-
- memcpy(buf, head_buffer->buf, len);
-
- // split the current head into two parts
- size_t remaining = head_buffer->size - len;
- uint8_t *newbuf = malloc(remaining);
-
- memcpy(newbuf, head_buffer->buf + len, remaining);
- free(head_buffer->buf);
- head_buffer->buf = newbuf;
- head_buffer->size = remaining;
- }
-
- pthread_mutex_unlock(&buffer_lock);
- return requested;
- }
-
- pthread_mutex_unlock(&buffer_lock);
- usleep(100);
-
- libvlc_media_t *media = libvlc_media_player_get_media(m_mp);
- libvlc_state_t st = libvlc_media_get_state(media);
- if (!(st == libvlc_Opening ||
- st == libvlc_Buffering ||
- st == libvlc_Playing) ) {
- return -1;
- }
-
- char* nowplaying_sz = libvlc_media_get_meta(media, libvlc_meta_NowPlaying);
- if (nowplaying_sz) {
- snprintf(vlc_nowplaying, NOWPLAYING_LEN, "%s", nowplaying_sz);
- free(nowplaying_sz);
- }
- }
-
- abort();
-}
-
-// This task is run in a separate thread
-void* vlc_in_write_icy_task(void* arg)
-{
- struct icywriter_task_data* data = arg;
-
- FILE* fd = fopen(vlc_nowplaying_filename, "wb");
- if (fd) {
- int ret = fputs(data->text, fd);
- fclose(fd);
-
- if (ret >= 0) {
- data->success = 1;
- }
- }
- else {
- data->success = 0;
- }
-
- sem_post(&data->sem);
- return NULL;
-}
-
-void vlc_in_write_icy(void)
-{
- if (vlc_nowplaying_filename == NULL) {
- return;
- }
- else if (vlc_nowplaying_running == 0) {
- memcpy(icy_task_data.text, vlc_nowplaying, NOWPLAYING_LEN);
- icy_task_data.success = 0;
-
- int ret = sem_init(&icy_task_data.sem, 0, 0);
- if (ret == 0) {
- ret = pthread_create(&vlc_nowplaying_thread, NULL, vlc_in_write_icy_task, &icy_task_data);
-
- if (ret == 0) {
- vlc_nowplaying_running = 1;
- }
- else {
- fprintf(stderr, "ICY Text writer: thread start failed: %s\n", strerror(ret));
- }
- }
- else {
- fprintf(stderr, "ICY Text writer: semaphore init failed: %s\n", strerror(errno));
- }
-
- }
- else {
- int ret = sem_trywait(&icy_task_data.sem);
- if (ret == -1 && errno == EAGAIN) {
- return;
- }
- else if (ret == 0) {
- ret = pthread_join(vlc_nowplaying_thread, NULL);
- if (ret != 0) {
- fprintf(stderr, "ICY Text writer: pthread_join error: %s\n", strerror(ret));
- }
-
- vlc_nowplaying_running = 0;
- }
- else {
- fprintf(stderr, "ICY Text writer: semaphore trywait failed: %s\n", strerror(errno));
- }
- }
-}
-
-
-/* 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(), 255);
-
- 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 // defined(VLC_INPUT)
-