Skip to content

Instantly share code, notes, and snippets.

@zhangjianyu1979
Forked from TimSC/vlcsms.c
Last active March 4, 2019 07:59
Show Gist options
  • Save zhangjianyu1979/ebd6efe7b040ee88d24c to your computer and use it in GitHub Desktop.
Save zhangjianyu1979/ebd6efe7b040ee88d24c to your computer and use it in GitHub Desktop.
Using libvlc to extract raw frames and audio from media via smem
//To compile:
//cc vlcsms.c -o vlcsms -lvlc
//This source is by Tim Sheerman-Chase and it is released as public domain.
#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},"
, (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
"--ignore-config", // Don't use VLC's config
"--extraintf=logger", // Log anything
"--verbose=1", // 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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment