I am trying to use smem to do asynchronous video decoding (faster than media would normally play). This seems to be the only mechanism to quickly decode frames in libvlc. When I run the following code, it runs in synchronous mode which is not what I want. The time-sync and no-sout-smem-time-sync options are apparently ignored.
I am running the nightly build git20121120 on Linux Mint 13 (based on Precise).
Is this a bug, or am I missing something more obvious?
Thanks,
Tim
Code: Select all
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <vlc/vlc.h>
int done = 0;
libvlc_media_player_t *media_player = NULL;
uint8_t *videoBuffer = 0;
uint8_t *audioBuffer = 0;
unsigned int videoBufferSize = 0;
unsigned int audioBufferSize = 0;
// Audio prerender callback
void cbAudioPrerender (void* p_audio_data, uint8_t** pp_pcm_buffer , unsigned int size)
{
// TODO: Lock the mutex
//printf("cbAudioPrerender %i\n",size);
//printf("atest: %lld\n",(long long int)p_audio_data);
if (size > audioBufferSize || !audioBuffer)
{
printf("Reallocate raw audio buffer\n");
if(audioBuffer) free(audioBuffer);
audioBuffer = (uint8_t *)malloc(size);
audioBufferSize = size;
}
*pp_pcm_buffer = audioBuffer;
}
// Audio postrender callback
void cbAudioPostrender(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 )
{
//printf("cbAudioPostrender %i\n", size);
// TODO: explain how data should be handled
// TODO: Unlock the mutex
}
void cbVideoPrerender(void *p_video_data, uint8_t **pp_pixel_buffer, int size) {
// Locking
//printf("cbVideoPrerender %i\n",size);
//printf("vtest: %lld\n",(long long int)p_video_data);
if (size > videoBufferSize || !videoBuffer)
{
printf("Reallocate raw video buffer\n");
if(audioBuffer) free(videoBuffer);
videoBuffer = (uint8_t *)malloc(size);
videoBufferSize = size;
}
*pp_pixel_buffer = videoBuffer;
}
void cbVideoPostrender(void *p_video_data, uint8_t *p_pixel_buffer
, int width, int height, int pixel_pitch, int size, int64_t pts) {
//printf("cbVideoPostrender %i\n",size);
// Unlocking
}
static void handleEvent(const libvlc_event_t* pEvt, void* pUserData)
{
libvlc_time_t time;
switch(pEvt->type)
{
case libvlc_MediaPlayerTimeChanged:
time = libvlc_media_player_get_time(media_player);
printf(">>>MediaPlayerTimeChanged %lld ms\n", (long long)time);
break;
case libvlc_MediaPlayerEndReached:
printf ("MediaPlayerEndReached\n");
done = 1;
break;
default:
printf("%s\n", libvlc_event_type_name(pEvt->type));
}
}
int main(int argc, char **argv)
{
// VLC pointers
libvlc_instance_t *vlcInstance;
void *pUserData = 0;
// VLC options
char smem_options[1000];
sprintf(smem_options
, "#transcode{vcodec=I444,acodec=s16l}:smem{"
"video-prerender-callback=%lld,"
"video-postrender-callback=%lld,"
"audio-prerender-callback=%lld,"
"audio-postrender-callback=%lld,"
"audio-data=%lld,"
"video-data=%lld,"
"time-sync=false},"
, (long long int)(intptr_t)(void*)&cbVideoPrerender
, (long long int)(intptr_t)(void*)&cbVideoPostrender
, (long long int)(intptr_t)(void*)&cbAudioPrerender
, (long long int)(intptr_t)(void*)&cbAudioPostrender
, (long long int)100 //This would normally be useful data, 100 is just test data
, (long long int)200 //Test data
);
const char * const vlc_args[] = {
"-I", "dummy", // Don't use any interface
"--no-sout-smem-time-sync",
"--ignore-config", // Don't use VLC's config
"--extraintf=logger", // Log anything
"--verbose=2", // Be verbose
"--sout", smem_options // Stream to memory
};
// We launch VLC
vlcInstance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
media_player = libvlc_media_player_new(vlcInstance);
libvlc_event_manager_t* eventManager = libvlc_media_player_event_manager(media_player);
libvlc_event_attach(eventManager, libvlc_MediaPlayerTimeChanged, handleEvent, pUserData);
libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached, handleEvent, pUserData);
//libvlc_event_attach(eventManager, libvlc_MediaPlayerPositionChanged, handleEvent, pUserData);
libvlc_media_t *media = libvlc_media_new_path(vlcInstance, "test.wav");
libvlc_media_player_set_media(media_player, media);
libvlc_media_player_play(media_player);
while (!done)
{
sleep(1);
//libvlc_media_player_set_position(media_player, 0.);
}
libvlc_media_release(media);
return 0;
}
Code: Select all
-- logger module started --
main debug: using interface module "logger"
main debug: Creating an input for 'test.wav'
main debug: using sout chain=`transcode{vcodec=I444,acodec=s16l}:smem{video-prerender-callback=4197146,video-postrender-callback=4197272,audio-prerender-callback=4196996,audio-postrender-callback=4197118,audio-data=100,video-data=200,time-sync=false},'
main debug: stream=`smem'
main debug: looking for sout stream module matching "smem": 20 candidates
main debug: set config option: sout-smem-video-prerender-callback to 4197146
main debug: set config option: sout-smem-video-postrender-callback to 4197272
main debug: set config option: sout-smem-audio-prerender-callback to 4196996
main debug: set config option: sout-smem-audio-postrender-callback to 4197118
main debug: set config option: sout-smem-audio-data to 100
main debug: set config option: sout-smem-video-data to 200
main debug: set config option: sout-smem-time-sync to false
main debug: using sout stream module "stream_out_smem"
main debug: stream=`transcode'
main debug: looking for sout stream module matching "transcode": 20 candidates
main debug: set config option: sout-transcode-vcodec to I444
main debug: set config option: sout-transcode-acodec to s16l
stream_out_transcode debug: codec audio=s16l 0Hz 0 channels 96Kb/s
stream_out_transcode debug: codec video=I444 0x0 scaling: 0.000000 0kb/s
main debug: using sout stream module "stream_out_transcode"
main debug: using timeshift granularity of 50 MiB, in path '/tmp'
main debug: `file:///home/tim/dev/libvlc/test.wav' gives access `file' demux `' path `/home/tim/dev/libvlc/test.wav'
main debug: creating demux: access='file' demux='' location='/home/tim/dev/libvlc/test.wav' file='/home/tim/dev/libvlc/test.wav'
main debug: looking for access_demux module matching "file": 18 candidates
main debug: no access_demux modules matched
main debug: creating access 'file' location='/home/tim/dev/libvlc/test.wav', path='/home/tim/dev/libvlc/test.wav'
main debug: looking for access module matching "file": 24 candidates
filesystem debug: opening file `/home/tim/dev/libvlc/test.wav'
main debug: using access module "filesystem"
main debug: Using stream method for AStream*
main debug: starting pre-buffering
main debug: received first data after 0 ms
main debug: pre-buffering done 1024 bytes in 0s - 7936 KiB/s
main debug: looking for stream_filter module matching "any": 9 candidates
main debug: no stream_filter modules matched
main debug: looking for stream_filter module matching "stream_filter_record": 9 candidates
main debug: no stream_filter modules matched
main debug: creating demux: access='file' demux='' location='/home/tim/dev/libvlc/test.wav' file='/home/tim/dev/libvlc/test.wav'
main debug: looking for demux module matching "any": 63 candidates
wav debug: chunk: fcc=`fmt ` size=16
wav debug: format: 0x0001, fourcc: araw, channels: 1, freq: 16000 Hz, bitrate: 31Ko/s, blockalign: 2, bits/samples: 16, extra size: 0
wav debug: found Raw audio audio format
wav debug: chunk: fcc=`data` size=17366
main debug: selecting program id=0
main debug: using demux module "wav"
main debug: looking for a subtitle file in /home/tim/dev/libvlc/
main debug: looking for packetizer module matching "any": 21 candidates
main debug: using packetizer module "packetizer_copy"
main debug: starting in async mode
main debug: looking for meta reader module matching "any": 2 candidates
lua debug: Trying Lua scripts in /home/tim/.local/share/vlc/lua/meta/reader
lua debug: Trying Lua scripts in /usr/lib/vlc/lua/meta/reader
lua debug: Trying Lua playlist script /usr/lib/vlc/lua/meta/reader/filename.luac
lua debug: Trying Lua scripts in /usr/share/vlc/lua/meta/reader
main debug: no meta reader modules matched
main debug: `file:///home/tim/dev/libvlc/test.wav' successfully opened
main debug: Buffering 0%
main debug: switching to sync mode
main debug: Buffering 16%
main debug: Buffering 33%
main debug: Buffering 50%
main debug: adding a new sout input (sout_input:0x7f91500008c0)
main debug: Buffering 66%
stream_out_transcode debug: creating audio transcoding from fcc=`s16l' to fcc=`s16l'
main debug: Buffering 83%
main debug: Buffering 100%
main debug: Stream buffering done (350 ms in 0 ms)
main debug: looking for decoder module matching "any": 36 candidates
araw debug: samplerate:16000Hz channels:1 bits/sample:16
main debug: using decoder module "araw"
main debug: looking for encoder module matching "any": 16 candidates
araw debug: samplerate:16000Hz channels:1 bits/sample:16
main debug: using encoder module "araw"
main debug: Decoder buffering done in 3 ms
main debug: EOF reached
main debug: removing module "packetizer_copy"
main debug: killing decoder fourcc `s16l', 0 PES in FIFO
main debug: removing a sout input (sout_input:0x7f91500008c0)
main debug: removing module "araw"
main debug: removing module "araw"
main debug: removing module "wav"
main debug: removing module "filesystem"
main debug: Program doesn't contain anymore ES