lms-video/Gem/plugins/videoVLC/videoVLC.cpp
Santi Noreña e85d191b46 - Reestructuración de ficheros y directorios general
- merge v0.01 --> Añadido fileselector
- Añadidas fuentes de Gem y Pure Data
- pix2jpg incluído en Gem. Archivos de construcción de Gem modificados.
- Añadido fichero ompiling.txt con instrucciones de compilación
2013-02-04 18:00:17 +01:00

313 lines
7.4 KiB
C++

////////////////////////////////////////////////////////
//
// GEM - Graphics Environment for Multimedia
//
// zmoelnig@iem.kug.ac.at
//
// Implementation file
//
// Copyright (c) 2011 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at
// For information on usage and redistribution, and for a DISCLAIMER OF ALL
// WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
//
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_LIBVLC
#include <stdio.h>
#ifdef _MSC_VER
# define snprintf _snprintf
#endif
#include "videoVLC.h"
#include "plugins/PluginFactory.h"
#include "Gem/Exception.h"
#include "Gem/RTE.h"
#define MAXVLCSTRING 1024
using namespace gem::plugins;
#if 0
# define LOCK(x) post("%04d\t%s LOCK", __LINE__, __FUNCTION__), x.unlock(), post("%04d\t%s LOCKed", __LINE__, __FUNCTION__)
# define UNLOCK(x) post("%04d\t%s UNLOCK", __LINE__, __FUNCTION__), x.unlock(), post("%04d\t%s UNLOCKed", __LINE__, __FUNCTION__)
#else
# define LOCK(x) x.lock()
# define UNLOCK(x) x.unlock()
#endif
REGISTER_VIDEOFACTORY("vlc", videoVLC);
videoVLC::videoVLC(void) :
m_name(std::string("vlc")),
m_type(0),
m_instance(NULL),
m_mediaplayer(NULL)
{
const char * const vlc_args[] = {
// "--plugin-path=c:\\program files\\videolan\\vlc\\plugins",
"-I", "dummy", /* Don't use any interface */
"--ignore-config", /* Don't use VLC's config */
"--quiet",
// "--sout=#transcode{vcodec=RV24,acodec=s16l}:smem",
};
m_instance=libvlc_new (sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
if(!m_instance) {
throw(GemException("couldn't initialize libVLC"));
}
m_pixBlock.image.xsize = 64;
m_pixBlock.image.ysize = 64;
m_pixBlock.image.setCsizeByFormat(GL_RGBA);
m_pixBlock.image.reallocate();
}
videoVLC::~videoVLC(void) {
if(m_instance)
libvlc_release(m_instance);
}
void videoVLC::close(void) {
if(m_mediaplayer)
libvlc_media_player_release(m_mediaplayer);
m_mediaplayer=NULL;
}
bool videoVLC::open(gem::Properties&props) {
if(m_mediaplayer)close();
setProperties(props);
if(m_devname.empty())
return false;
libvlc_media_t*media = libvlc_media_new_location (m_instance, m_devname.c_str());
if(!media)
media = libvlc_media_new_path (m_instance, m_devname.c_str());
if(!media)
return false;
char buf[MAXVLCSTRING];
libvlc_media_add_option(media,":noaudio");
libvlc_media_add_option(media,":no-video-title-show");
int w=m_pixBlock.image.xsize;
int h=m_pixBlock.image.ysize;
std::vector<std::string>keys=props.keys();
unsigned int i;
for(i=0; i<keys.size(); i++) {
std::string key=keys[i];
double d;
std::string s;
buf[0]=0;
if(0) {}
else if("width"==key) {
if(props.get(key, d)&&(d>0))
w=d;
} else if("height"==key) {
if(props.get(key, d)&&(d>0))
h=d;
} else {
gem::Properties::PropertyType type = props.type(key);
switch(type) {
case gem::Properties::NONE:
snprintf(buf, MAXVLCSTRING, ":%s", key.c_str());
break;
case gem::Properties::DOUBLE:
if(props.get(key, d)) {
snprintf(buf, MAXVLCSTRING, ":%s=%g", key.c_str(), d);
}
break;
case gem::Properties::STRING:
if(props.get(key, s)) {
/* need to find an option that actually takes strings, so i can test this with spaces */
snprintf(buf, MAXVLCSTRING, ":%s=%s", key.c_str(), s.c_str());
}
break;
default:
break;
}
if(0!=buf[0]) {
buf[MAXVLCSTRING-1]=0;
//post("vlc-option: '%s'", buf);
libvlc_media_add_option(media,buf);
}
}
}
m_pixBlock.image.xsize = w;
m_pixBlock.image.ysize = h;
m_pixBlock.image.setCsizeByFormat(GL_RGBA);
m_pixBlock.image.reallocate();
m_pixBlock.image.setWhite();
m_mediaplayer=libvlc_media_player_new_from_media(media);
libvlc_media_release(media);
libvlc_video_set_callbacks(m_mediaplayer,
lockCB,
unlockCB,
NULL,
this);
libvlc_video_set_format(m_mediaplayer,
"RGBA",
m_pixBlock.image.xsize,
m_pixBlock.image.ysize,
m_pixBlock.image.xsize*m_pixBlock.image.csize);
return true;
}
pixBlock*videoVLC::getFrame(void) {
LOCK(m_mutex);
return &m_pixBlock;
}
void videoVLC::releaseFrame(void) {
// post("release frame");
UNLOCK(m_mutex);
}
std::vector<std::string>videoVLC::enumerate(void) {
std::vector<std::string>result;
result.push_back("vlc");
return result;
}
bool videoVLC::setDevice(int ID) {
m_devname.clear();
return false;
}
bool videoVLC::setDevice(std::string device) {
m_devname=device;
return true;
}
bool videoVLC::enumProperties(gem::Properties&readable,
gem::Properties&writeable) {
readable.clear();
writeable.clear();
writeable.set("width", m_pixBlock.image.xsize); readable.set("width", m_pixBlock.image.xsize);
writeable.set("height", m_pixBlock.image.ysize); readable.set("height", m_pixBlock.image.ysize);
return false;
}
void videoVLC::setProperties(gem::Properties&props) {
int width=-1;
int height=-1;
m_props=props;
double d;
if(props.get("width", d)) {
if(d>0)
width = d;
}
if(props.get("height", d)) {
if(d>0)
height=d;
}
if(!m_mediaplayer) {
if(width>0)
m_pixBlock.image.xsize=width;
if(height>0)
m_pixBlock.image.ysize=height;
} else {
// changes will take effect with next restart
}
}
void videoVLC::getProperties(gem::Properties&props) {
std::vector<std::string>keys=props.keys();
double d;
int i;
for(i=0; i<keys.size(); i++) {
if("width"==keys[i]) {
props.set(keys[i], m_pixBlock.image.xsize);
}
if("height"==keys[i]) {
props.set(keys[i], m_pixBlock.image.ysize);
}
}
}
std::vector<std::string>videoVLC::dialogs(void) {
std::vector<std::string>result;
return result;
}
bool videoVLC::provides(const std::string name) {
return (name==m_name);
}
std::vector<std::string>videoVLC::provides(void) {
std::vector<std::string>result;
result.push_back(m_name);
return result;
}
const std::string videoVLC::getName(void) {
return m_name;
}
bool videoVLC::start(void) {
int ret=-1;
if(m_mediaplayer) {
int ret=libvlc_media_player_play(m_mediaplayer);
}
return (0!=ret);
}
bool videoVLC::stop (void) {
if(!m_mediaplayer)
return false;
libvlc_media_player_stop(m_mediaplayer);
return true;
}
void*videoVLC::lockFrame(void**plane ) {
LOCK(m_mutex);
*plane=m_pixBlock.image.data;
// post("prepareFrame %p @ %p --> %p", *plane, plane, m_pixBlock.image.data);
return NULL;
}
void videoVLC::unlockFrame(void*picture, void*const*plane) {
// post("processFrame %p\t%p", picture, *plane);
m_pixBlock.newimage=true;
m_pixBlock.image.upsidedown=true;
UNLOCK(m_mutex);
}
void*videoVLC::lockCB(void*opaque, void**plane ) {
// post(" lockCB: %p", opaque);
videoVLC*obj=(videoVLC*)opaque;
if(obj)
return obj->lockFrame(plane);
return NULL;
}
void videoVLC::unlockCB(void*opaque, void*picture, void*const*plane) {
// post(" unlockCB: %p", opaque);
videoVLC*obj=(videoVLC*)opaque;
if(obj)
obj->unlockFrame(picture, plane);
}
void videoVLC::displayCB(void*opaque, void*picture) {
// post("displayCB: %p -> %p", opaque, picture);
videoVLC*obj=(videoVLC*)opaque;
}
#endif /* HAVE_LIBVLC */