fixes to the audio collector and video encoder,

new add_audio method for video encoder,
more updates and cleanups
This commit is contained in:
Jaromil
2008-05-03 20:10:28 +02:00
parent 05b3026ce1
commit a9cf290696
20 changed files with 160 additions and 70 deletions
+10 -8
View File
@@ -1,12 +1,14 @@
Freej 0.9.x Experimental
* new AudioJack() collector for realtime sound parametrization
* new MouseController()
* new ViMoContoller() for serial Video Mouse device
* tons of bugfixes
* JS garbage collection framework, rem_controller() and rem_layer()
* new fps syncing per layer
* Layer.start() .stop()
* experimental ViewportLayer() using Xv extension
AudioJack() collector for realtime sound parametrization
WiiController() for bluetooth WiiMote device
MouseController() for mouse pointer
ViMoContoller() for serial Video Mouse device
tons of bugfixes
JS garbage collection framework, rem_controller() and rem_layer()
new fps sync architecture to let layers go
Layer.start() .stop()
OpenGL viewport fixes
experimental ViewportLayer() using Xv extension
FreeJ 0.9.1 BeTV - 26 Nov 2007
New video encoder (ffmpeg2theora)
+1 -2
View File
@@ -19,8 +19,7 @@
<div class="desc">
This object collects audio from a <a
href="http://www.jackaudio.org">Jack</a> source, it can be used to
change parameter values based on the audio input.
</div>
change parameter values based on the audio input. </div>
<div class="desc">
16 harmonics are provided using a fast fourier transform, returning
+6 -5
View File
@@ -12,10 +12,12 @@
/////// VIDEO ENCODER
/**
This object compresses the video output of FreeJ (using the
Ogg/Vorbis/Theora codec) and can be configured to save the
compressed video in a file (playable later) or stream che
compressed video on the internet for live playback (using icecast2)
This object compresses the video output of FreeJ
@class The Video Encoder compresses video to save in a file or
stream on the net (using the Ogg/Vorbis/Theora codec) and can be
configured to save the compressed video in a file (playable later)
or stream che compressed video on the internet for live playback
(using icecast2)
<div class="example">Example:
@@ -34,7 +36,6 @@
// encoder.start_filesave("prova.ogg");
</div>
@class The Video Encoder compresses video to save in a file or stream on the net
@author Xiph.org, Kysucix, Jaromil
@constructor
@param {int} video_quality quality of the video compression, from 1 to 100.
+12 -3
View File
@@ -3,13 +3,22 @@
// also check the values (samplesize and samplerate) to match your conf
// -jrml
H=640;
H=800;
M=H/128;
W=H/(H/80);
//W=600
set_resolution(W,H);
audio = new AudioJack("xine:out_l", 2048, 44100);
audio = new AudioJack("alsa_pcm:capture_1", 2048, 44100);
encoder = new VideoEncoder(10, 64000, 5, 24000);
encoder.add_audio(audio);
register_encoder(encoder);
encoder.start_filesave("prova.ogg");
geo = new GeometryLayer();
geo.activate(true);
@@ -63,4 +72,4 @@ bang.frame = function() {
}
register_controller(bang);
gc();
gc();
+12
View File
@@ -0,0 +1,12 @@
// simple use of goom and audio
// -jrml
audio = new AudioJack("xine:out_l", 2048, 44100);
goom = new GoomLayer();
audio.add_output(goom);
goom.start();
add_layer(goom);
+1 -2
View File
@@ -15,8 +15,7 @@ INCLUDES = -I$(top_srcdir)/src/include \
-I$(top_srcdir)/lib/slw \
-I$(top_srcdir)/lib/cwiid \
-I/usr/include/slang \
@XIPH_INCLUDE@ \
@X11_LIBS@
@XIPH_INCLUDE@
AM_CXXFLAGS = @SDL_CFLAGS@ @FT2_CFLAGS@ \
-DPREFIX="\"$(prefix)\"" -DDATADIR="\"$(datadir)\""
+22 -13
View File
@@ -78,10 +78,10 @@ void FFT::Impulse2Freq(float *imp, float *out)
///////////////////////////////////////////////////////////////////////////////////////////////////////////
AudioCollector::AudioCollector(const string &port, int BufferLength, unsigned int Samplerate, int FFTBuffers) :
AudioCollector::AudioCollector(const string &port, int n_BufferLength, unsigned int n_Samplerate, int FFTBuffers) :
m_Gain(1),
m_SmoothingBias(1.2),
m_FFT(BufferLength),
m_FFT(n_BufferLength),
m_FFTBuffers(FFTBuffers),
m_JackBuffer(NULL),
m_OSSBuffer(NULL),
@@ -89,9 +89,9 @@ m_OneOverSHRT_MAX(1/(float)SHRT_MAX),
m_Processing(false),
m_ProcessPos(0)
{
m_BufferLength = BufferLength;
m_Samplerate = Samplerate;
m_BufferTime = m_BufferLength/(float)m_Samplerate;
BufferLength = n_BufferLength;
Samplerate = n_Samplerate;
m_BufferTime = BufferLength/(float)Samplerate;
m_Buffer = (float*) jalloc(BufferLength * sizeof(float));
memset(m_Buffer,0,BufferLength*sizeof(float));
@@ -149,10 +149,10 @@ float *AudioCollector::GetFFT()
{
if (m_Processing)
{
if (m_ProcessPos+m_BufferLength<m_ProcessLength)
if (m_ProcessPos+BufferLength<m_ProcessLength)
{
m_FFT.Impulse2Freq(m_ProcessBuffer+m_ProcessPos,m_FFTBuffer);
m_ProcessPos+=m_BufferLength;
m_ProcessPos+=BufferLength;
}
else
{
@@ -165,7 +165,7 @@ float *AudioCollector::GetFFT()
else
{
pthread_mutex_lock(m_Mutex);
memcpy((void*)m_AudioBuffer,(void*)m_Buffer,m_BufferLength*sizeof(float));
jmemcpy((void*)m_AudioBuffer,(void*)m_Buffer,BufferLength*sizeof(float));
pthread_mutex_unlock(m_Mutex);
m_FFT.Impulse2Freq(m_AudioBuffer,m_FFTBuffer);
@@ -191,7 +191,7 @@ float *AudioCollector::GetFFT()
return m_FFTOutput;
}
/*
/*
void AudioCollector::Process(const string &filename)
{
if (m_Processing) return;
@@ -230,13 +230,22 @@ void AudioCollector::Process(const string &filename)
m_Processing=true;
m_ProcessPos=0;
}*/
}
*/
void AudioCollector::get_audio(void *dest) {
if (!pthread_mutex_trylock(m_Mutex))
{
jmemcpy(dest, (void*)m_Buffer, BufferLength*sizeof(float));
pthread_mutex_unlock(m_Mutex);
}
}
void AudioCollector::AudioCallback_i(unsigned int Size)
{
if (Size<=m_BufferLength && !pthread_mutex_trylock(m_Mutex))
if (Size<=BufferLength && !pthread_mutex_trylock(m_Mutex))
{
jmemcpy((void*)m_Buffer,(void*)m_JackBuffer,m_BufferLength*sizeof(float));
jmemcpy((void*)m_Buffer,(void*)m_JackBuffer,BufferLength*sizeof(float));
pthread_mutex_unlock(m_Mutex);
}
}
-1
View File
@@ -157,7 +157,6 @@ JS(js_audio_jack_fft) {
void js_audio_jack_gc(JSContext *cx, JSObject *obj) {
func("%s",__PRETTY_FUNCTION__);
char excp_msg[MAX_ERR_MSG + 1];
AudioCollector *audio = (AudioCollector*)JS_GetPrivate(cx, obj);
if(!audio) return;
+11 -8
View File
@@ -151,11 +151,11 @@ bool Context::init(int wx, int hx, bool opengl, bool init_audio) {
notice("initializing context environment", wx, hx);
// If selected use opengl as video output!
#ifdef WITH_OPENGL
if (opengl)
screen = new SdlGlScreen();
else
#endif
//#ifdef WITH_OPENGL
// if (opengl)
// screen = new SdlGlScreen();
// else
//#endif
screen = new SdlScreen();
@@ -199,8 +199,8 @@ bool Context::init(int wx, int hx, bool opengl, bool init_audio) {
SDL_initFramerate(&FPS);
SDL_setFramerate(&FPS, fps_speed);
if(init_audio)
audio = new AudioCollector("alsa_pcm:capture_1", 2048, 44100);
// if(init_audio)
// audio = new AudioCollector("alsa_pcm:capture_1", 2048, 44100);
// initialize MLT
// mlt_factory_init( NULL );
@@ -486,11 +486,14 @@ void Context::add_encoder(VideoEncoder *enc) {
func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__);
if(enc->list) enc->rem();
enc->env = this;
enc->init(this);
encoders.append(enc);
encoders.sel(0);
enc->sel(true);
func("encoder %s succesfully added", enc->name);
}
+2 -2
View File
@@ -60,6 +60,8 @@ public:
bool IsProcessing() { return m_Processing; }
float BufferTime() { return m_BufferTime; }
void get_audio(void *buffer);
unsigned int Samplerate;
unsigned int BufferLength;
@@ -70,9 +72,7 @@ public:
float m_Gain;
float m_SmoothingBias;
unsigned int m_Samplerate;
float m_BufferTime;
unsigned int m_BufferLength;
FFT m_FFT;
pthread_mutex_t* m_Mutex;
float *m_Buffer;
+1
View File
@@ -421,6 +421,7 @@ JS(txt_layer_calculate_size);
#ifdef WITH_OGGTHEORA
JS(vid_enc_start_filesave);
JS(vid_enc_stop_filesave);
JS(vid_enc_add_audio);
// Shouter methods
JS(start_stream);
JS(stop_stream);
-3
View File
@@ -26,7 +26,6 @@
#include <config.h>
#include <linklist.h>
#include <video_encoder.h>
#include <screen.h>
#include <ccvt.h>
#ifdef WITH_OGGTHEORA
@@ -58,7 +57,6 @@ class OggTheoraEncoder: public VideoEncoder {
int encode_frame();
private:
oggmux_info oggmux; // theorautils object
@@ -82,7 +80,6 @@ class OggTheoraEncoder: public VideoEncoder {
unsigned char *yuvframe[2]; /* yuv 420 */
ViewPort *screen;
};
+3
View File
@@ -18,6 +18,9 @@
* "$Id$"
*
*/
#include <config.h>
#ifdef WITH_OPENGL
#ifndef __SDLGL_SCREEN_H__
#define __SDLGL_SCREEN_H__
+4 -1
View File
@@ -38,6 +38,7 @@
#include <shout/shout.h>
class Context;
class AudioCollector;
/**
* Class describing the general interface of an encoder
@@ -92,6 +93,8 @@ class VideoEncoder: public Entry, public JSyncThread {
bool write_to_stream; ///< true if encoder should write to a stream
bool use_audio; ///< true if the encoded data should include also audio
AudioCollector *audio; ///< holding the pointer to the @AudioCollector class
float *audio_buf; ///< audio buffer (local copy for the encoder)
bool streaming; ///< set true when streaming by js start_stream()
@@ -101,7 +104,7 @@ class VideoEncoder: public Entry, public JSyncThread {
shout_t *ice;
ViewPort *screen;
private:
FILE *filedump_fd;
+1 -1
View File
@@ -336,7 +336,7 @@ void rtc_close() {
}
#endif
void *(* jmemcpy)(void *to, const void *from, size_t len) = memcpy;
void *(* jmemcpy)(void *to, const void *from, size_t len);
bool filecheck(char *file) {
+28 -15
View File
@@ -52,7 +52,9 @@ OggTheoraEncoder::OggTheoraEncoder()
// enc_rgb24 = NULL;
enc_y = enc_u = enc_v = NULL;
use_audio = true;
use_audio = false;
audio = NULL;
audio_buf = NULL;
init_info(&oggmux);
theora_comment_init(&oggmux.tc);
@@ -74,6 +76,7 @@ OggTheoraEncoder::~OggTheoraEncoder() { // XXX TODO clear the memory !!
if(enc_v) free(enc_v);
if(enc_yuyv) free(enc_yuyv);
if(audio_buf) free(audio_buf);
}
@@ -89,17 +92,25 @@ bool OggTheoraEncoder::init (Context *_env) {
oggmux.bytes_encoded = 0;
oggmux.audio_only = 0;
if(use_audio && env->audio)
if(use_audio && audio) {
func("allocating encoder audio buffer of %u bytes",audio->BufferLength);
audio_buf = (float*)calloc(audio->BufferLength, sizeof(float));
oggmux.video_only = 0;
else {
oggmux.sample_rate = audio->Samplerate;
oggmux.channels = 1; // only 1 channel jack support for now
oggmux.vorbis_quality = audio_quality / 100;
oggmux.vorbis_bitrate = audio_bitrate;
} else {
oggmux.video_only = 1;
use_audio = false;
}
oggmux.sample_rate = 44100;
oggmux.channels = 1;
oggmux.vorbis_quality = audio_quality / 100;
oggmux.vorbis_bitrate = audio_bitrate;
/* Set up Theora encoder */
@@ -199,12 +210,13 @@ bool OggTheoraEncoder::feed_video() {
(see mlt_frame.h in mltframework.org sourcecode)
i can't tell as i don't have PPC, waiting for u mr.goil :)
*/
env->screen->lock();
mlt_convert_rgb24a_to_yuv422((uint8_t*)env->screen->get_surface(),
env->screen->w, env->screen->h,
env->screen->w<<2, (uint8_t*)enc_yuyv, NULL);
env->screen->unlock();
mlt_convert_rgb24a_to_yuv422((uint8_t*)screen->get_surface(),
screen->w, screen->h,
screen->w<<2, (uint8_t*)enc_yuyv, NULL);
ccvt_yuyv_420p(screen->w, screen->h, enc_yuyv, enc_y, enc_u, enc_v);
ccvt_yuyv_420p(env->screen->w, env->screen->h, enc_yuyv, enc_y, enc_u, enc_v);
return true;
}
@@ -242,15 +254,16 @@ int OggTheoraEncoder::encode_video( int end_of_stream) {
int OggTheoraEncoder::encode_audio( int end_of_stream) {
// num = env->audio->framesperbuffer*env->audio->channels*sizeof(int16_t);
func("going to encode %u bytes of audio", audio->BufferLength);
///// QUAAAA
// oggmux_add_audio (oggmux_info *info, int16_t * readbuffer, int bytesread, int samplesread,int e_o_s);
// oggmux_add_audio(&oggmux, env->audio->input,
// read,
// read / env->audio->channels /2,
// end_of_stream );
oggmux_add_audio_float(&oggmux, env->audio->GetAudioBuffer(),
env->audio->BufferLength, end_of_stream);
audio->get_audio(audio_buf);
oggmux_add_audio_float(&oggmux, audio_buf,
audio->BufferLength, end_of_stream);
return 1;
+1
View File
@@ -46,6 +46,7 @@ Plugger::Plugger() {
addsearchdir("/usr/lib/freej");
addsearchdir("/usr/local/lib/freej");
addsearchdir("/opt/video/lib/freej");
addsearchdir("/usr/lib/FreeFrame");
}
+9 -1
View File
@@ -18,7 +18,10 @@
* "$Id$"
*
*/
#include <config.h>
#ifdef WITH_OPENGL
#include <stdlib.h>
#include <string.h>
#include <SDL_syswm.h>
@@ -26,7 +29,6 @@
#include <sdlgl_screen.h>
#include <jutils.h>
#include <config.h>
@@ -335,6 +337,12 @@ void SdlGlScreen::show() {
notice("GL_TABLE_TOO_LARGE");
}
// notice("");
int x_translation = 0;
int y_translation = 0;
int x_rotation = 0;
int y_rotation = 0;
int rotation = 0;
int zoom = 0;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glGetError ();
+1 -1
View File
@@ -60,7 +60,7 @@ static double rint(double x)
}
void init_info(oggmux_info *info) {
info->with_skeleton = 0; /* skeleton is disabled by default */
info->with_skeleton = 1; /* skeleton is disabled by default */
info->frontend = 0; /*frontend mode*/
info->videotime = 0;
info->audiotime = 0;
+35 -4
View File
@@ -38,6 +38,8 @@ JSFunctionSpec js_vid_enc_methods[] = {
{ "start_stream", start_stream, 0},
{ "stop_stream", stop_stream, 0},
{ "add_audio", vid_enc_add_audio, 1 },
{ "stream_host", stream_host, 1},
{ "stream_port", stream_port, 1},
{ "stream_mountpoint", stream_mount, 1},
@@ -76,10 +78,8 @@ JS(js_vid_enc_constructor) {
enc->audio_bitrate = JSVAL_TO_INT(argv[3]);
if(!enc->init(env)) {
error("JS::VideoEncoder : failed initialization");
delete enc; return JS_FALSE;
}
// initialization is done with audio
if(!JS_SetPrivate(cx,obj,(void*)enc)) {
error("JS::VideoEncoder : can't set the private value");
delete enc; return JS_FALSE;
@@ -88,6 +88,37 @@ JS(js_vid_enc_constructor) {
return JS_TRUE;
}
JS(vid_enc_add_audio) {
func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__);
JS_CHECK_ARGC(1);
js_is_instanceOf(&js_audio_jack_class, argv[0]);
JSObject *jsaudio;
jsaudio = JSVAL_TO_OBJECT(argv[0]);
AudioCollector *audio =
(AudioCollector*) JS_GetPrivate(cx, jsaudio);
VideoEncoder *enc = (VideoEncoder*)JS_GetPrivate(cx, obj);
if(!enc) {
error("%u:%s:%s :: VideoEncoder core data is NULL",
__LINE__,__FILE__,__FUNCTION__);
return JS_FALSE;
}
enc->use_audio = true;
enc->audio = audio;
if(!enc->init(env)) {
error("JS::VideoEncoder : failed initialization");
delete enc; return JS_FALSE;
}
return JS_TRUE;
}
JS(vid_enc_start_filesave) {
func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__);