summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaromil <jaromil@dyne.org>2011-04-20 16:57:50 (GMT)
committer Jaromil <jaromil@dyne.org>2011-04-20 16:57:50 (GMT)
commit89c80f478c3e42ed00ed1d0e64d22aecd32217de (patch)
tree21541c2d7bb6e41fe80dc6e0b342307cbc831242
parent54e148c55f0cf677977e360392166b18f6977bc7 (diff)
parente5664d8352555bf6c05954a04a67a3df1692bb94 (diff)
Merge remote branch 'origin/sound'
-rw-r--r--qt/.gitignore13
-rw-r--r--qt/Makefile.am12
-rw-r--r--qt/QqWidget.cpp26
-rw-r--r--qt/QqWidget.h5
-rw-r--r--qt/TODO19
-rw-r--r--qt/qJackClient.cpp16
-rw-r--r--qt/qJackClient.h2
-rw-r--r--qt/qfreej.cpp5
-rw-r--r--qt/qfreej.h1
-rw-r--r--src/fps.cpp69
-rw-r--r--src/include/context.h2
-rw-r--r--src/include/fps.h22
-rw-r--r--src/include/layer.h2
-rw-r--r--src/include/theorautils.h2
-rw-r--r--src/include/video_encoder.h2
-rw-r--r--src/include/video_layer.h2
-rw-r--r--src/theorautils.cpp98
-rw-r--r--src/v4l2_layer.cpp2
-rw-r--r--src/video_encoder.cpp46
-rw-r--r--src/video_layer.cpp6
20 files changed, 213 insertions, 139 deletions
diff --git a/qt/.gitignore b/qt/.gitignore
index ef7f961..79bd332 100644
--- a/qt/.gitignore
+++ b/qt/.gitignore
@@ -1,4 +1,5 @@
tmp/*
+*.swp
toto*
thedaytrip_512kb.*
Qfreej.pro.user.2.1pre1
@@ -29,24 +30,18 @@ dump.*
dump_t.*
capture_client
capture_client.*
-aaa.avi
atime.3gp
film.mp4
-film2.avi
-film_mono.avi
-film_org.avi
-kury_s.avi
-kury_s_mono.avi
*.o
qfreej_s
git_doc.txt
Qfreej.pro.user
Qfreej.pro.user.1.3
moc_*
-kury.avi
-term.avi
ui_qfreej.h
*.ods
TODO.txt
-atruc.avi
Video/*
+*.avi
+*.mp4
+*.ogv
diff --git a/qt/Makefile.am b/qt/Makefile.am
index 8b92c88..4710fe4 100644
--- a/qt/Makefile.am
+++ b/qt/Makefile.am
@@ -23,9 +23,9 @@ BUILT_SOURCES = ui_qfreej.h \
moc_QqComboFilter.cpp \
moc_QqFiltersApplied.cpp \
moc_QqTabWidget.cpp \
- moc_Sound.cpp \
moc_qJackClient.cpp \
moc_qOpacity.cpp \
+ moc_qLogging.cpp \
moc_qEncoder.cpp
@@ -38,10 +38,10 @@ SOURCES = main.cpp \
specialeventget.cpp \
FakeWindow.cpp \
QqTabWidget.cpp \
- Sound.cpp \
qJackClient.cpp \
qOpacity.cpp \
qEncoder.cpp \
+ qLogging.cpp \
$(BUILT_SOURCES)
@@ -49,7 +49,7 @@ bin_PROGRAMS = qfreej
qfreej_SOURCES = $(SOURCES)
qfreej_LDADD = $(top_builddir)/src/libfreej.la $(SDL_LIBS) $(QTGUI_LIBS)
-clean:
- rm -f qfreej *.o
- rm -f moc_*.cpp moc_*.h
- rm -f ui_*.h \ No newline at end of file
+#clean:
+# rm -f qfreej *.o
+# rm -f moc_*.cpp moc_*.h
+# rm -f ui_*.h
diff --git a/qt/QqWidget.cpp b/qt/QqWidget.cpp
index c346d87..7ab0048 100644
--- a/qt/QqWidget.cpp
+++ b/qt/QqWidget.cpp
@@ -43,7 +43,7 @@ QqWidget::QqWidget(Context *freej, QqTabWidget* tabWidget, Qfreej* qfreej, QStri
fakeView = NULL;
fakeLay = NULL;
ctx = NULL;
- actualFps = normalFps = 0;
+ actualFps = normalFps = fpsP = 0;
qLayer = freej->open((char*)fichier.toStdString().c_str(), 0, 0); // hey, this already init and open the layer !!
if(qLayer)
{
@@ -51,20 +51,11 @@ QqWidget::QqWidget(Context *freej, QqTabWidget* tabWidget, Qfreej* qfreej, QStri
{
qLayer->start(); //launches JSyncThread::start()
-/* if (qLayer->frame_rate > 50) //pb de determination de FPS
- {
- std::cout << "--------- qfreej : frame_rate problem : " << qLayer->frame_rate << " FPS" << std::endl;
- qLayer->fps.set(qLayer->frame_rate / 10);
- normalFps = qLayer->frame_rate / 10;
- actualFps = qLayer->frame_rate / 10;
- }
- else
- {*/
- qLayer->fps.set(qLayer->frame_rate);
+// qLayer->fps.set(qLayer->frame_rate);
normalFps = qLayer->frame_rate;
actualFps = qLayer->frame_rate;
- qDebug() << "--- actualFps :" << actualFps;
-// }
+ fpsP = 100;
+// qDebug() << "--- actualFps :" << actualFps;
tabWidget->addTab(this, qLayer->get_filename());
qLayer->move(freej->screen->layers.len()); //put the layer at the end of the list
m_tabWidg = tabWidget;
@@ -119,9 +110,9 @@ QqWidget::QqWidget(Context *freej, QqTabWidget* tabWidget, Qfreej* qfreej, QStri
slowFps = new QSlider(this);
slowFps->setOrientation(Qt::Vertical);
connect(slowFps, SIGNAL(sliderMoved(int)), this, SLOT(changeFps(int)));
- slowFps->setRange(1, (normalFps*2));
+ slowFps->setRange(2, 100);
slowFps->setToolTip("speed control (grey: normal speed, red: higher or lower)");
- slowFps->setValue(normalFps);
+ slowFps->setValue(50);
slowFps->setSliderDown(true);
slowFps->setStyleSheet("background: grey");
layoutH->addWidget(slowFps);
@@ -537,9 +528,10 @@ void QqWidget::changeFps(int val)
{
if (qLayer)
{
- if (val != actualFps)
+ if (val != 50)
{
- qLayer->fps.set(val);
+ actualFps = ((double)val / 50.0) * normalFps;
+ qLayer->fps.set(actualFps);
slowFps->setStyleSheet("background: red");
}
else
diff --git a/qt/QqWidget.h b/qt/QqWidget.h
index 7ab0b0c..b52bd72 100644
--- a/qt/QqWidget.h
+++ b/qt/QqWidget.h
@@ -57,8 +57,9 @@ private:
QPushButton *textButton;
QPushButton *slowButton;
QSlider *slowFps;
- int normalFps;
- int actualFps;
+ double normalFps;
+ double actualFps;
+ int fpsP;
QPushButton *playButton;
bool isPlaying;
QComboBox *fontSizeBox;
diff --git a/qt/TODO b/qt/TODO
index d205367..88b64c2 100644
--- a/qt/TODO
+++ b/qt/TODO
@@ -1,21 +1,22 @@
//move main window in accordance with the size
//resize ViewPort in accordance to the biggest layer .... (not sure it is good thing)
//be able to record all marked opened layers with the same quality .... a challenge :)
-//see to use Linklist.completion to add blit, filters and generators
//devide the fake size window by two .... not sure :)
//insert STRING filters parameters
//add a x:x ratio button, resizing to the closest width and lenght to obtain this ratio
//create a console for messages comming from func() warning() notice() act(). see Logger class
//see to integrate ogg skeleton config on the graphic interface
-//there is the amount of delay between audio and video if you open a video before creating
+//there is a delay between audio and video if you open a video before creating
the QJackClient of the time you waited to open the QJackClient .... see if a fix possible or needed.
//Jack server sample rate and buffer size is hard coded for the moment, provide a way to put it manualy
//try to fix sound problem issue when opening several VideoLayer with audio
-//add the capability to have a config file..... important :)
-//if resizing the wiewport when the layer is bigger, you need to just touch the layer size to display it correctly
-//why qfreej doesn't install with the AUR packages
+//add the capability to keep the actual config in a file..... important :)
+//if resizing the wiewport when the layer is bigger, you just need to touch the layer size to display it correctly
//see if possible to manage an audio layer
-//be able to change v4l2 resolution from the graphic interface
-//see why sound delay increases on video during streaming
-//see why sound stops after a whyle when streaming .... have to deconnect jack ports and connect back
-//need do adjust stream bitrate value.
+//be able to change v4l2 resolution from the graphic interface and to disable it for some bad v4l2 devices
+//try to suppress the drift taken when applying an effect
+//streaming a/v, when stopping audio, the stream is corrupted and the client stops (oggmux_flush)
+//needs to launch QJackClient before start streaming when you want audio.
+//needs to re-launch streaming when disconnect and reconnect the jack input port
+//try to see why there is around 100 us more in between each call to the fps class (40100 instead od 40000 for 25fps)
+//merge with mastr branch ..... mainly for qt config modif \ No newline at end of file
diff --git a/qt/qJackClient.cpp b/qt/qJackClient.cpp
index 7078e6e..1ff8d5f 100644
--- a/qt/qJackClient.cpp
+++ b/qt/qJackClient.cpp
@@ -29,6 +29,7 @@ QJackClient::QJackClient(Qfreej *qfreej) : QWidget()
QJackClient::~QJackClient()
{
+ if (m_Qfreej->getQEnc()) delete (m_Qfreej->getQEnc());
if (m_JackIsOn && m_Jack) m_Jack->Detach();
m_Jack = NULL;
m_Qfreej->resetQJack();
@@ -71,14 +72,15 @@ bool QJackClient::init()
m_Coef->setEnabled(false);
layoutG->addWidget(m_Coef, 2, 0, 1, 2);
m_Coef->setToolTip("sets the Mix coefficient between Jack Input and Video Layer output");
-
+
+ //not used
m_SampleRate = new QLineEdit;
- connect (m_SampleRate, SIGNAL(returnPressed()), this, SLOT(chgSampleRate()));
+// connect (m_SampleRate, SIGNAL(returnPressed()), this, SLOT(chgSampleRate()));
m_SampleRate->setValidator(new QIntValidator(m_SampleRate));
m_SampleRate->setText("48000"); //default Jackd sample rate
m_SampleRate->setEnabled(false);
// m_Jack->m_SampleRate = 48000; //not necessary as it is donne in AudioCollector constructor
-
+ //
QLabel *vSampleRate = new QLabel("J SampleRate :");
layoutG->addWidget(vSampleRate, 3, 0);
layoutG->addWidget(m_SampleRate, 3, 1);
@@ -166,10 +168,10 @@ void QJackClient::addInput()
}
}
-void QJackClient::chgSampleRate()
-{
- m_Jack->m_SampleRate = m_SampleRate->text().toInt();
-}
+// void QJackClient::chgSampleRate()
+// {
+// m_Jack->m_SampleRate = m_SampleRate->text().toInt();
+// }
int QJackClient::getSampleRate()
{
diff --git a/qt/qJackClient.h b/qt/qJackClient.h
index 4f005a2..9180445 100644
--- a/qt/qJackClient.h
+++ b/qt/qJackClient.h
@@ -25,7 +25,7 @@ public:
public slots:
void addInput();
void addOutput();
- void chgSampleRate();
+// void chgSampleRate();
void chgSamples();
void changeMixCoef(int);
diff --git a/qt/qfreej.cpp b/qt/qfreej.cpp
index a92de91..858ff16 100644
--- a/qt/qfreej.cpp
+++ b/qt/qfreej.cpp
@@ -241,6 +241,11 @@ OggTheoraEncoder *Qfreej::getEnc()
return (NULL);
}
+QEncoder *Qfreej::getQEnc()
+{
+ return(m_Enc);
+}
+
void Qfreej::addTextLayer()
{
QqWidget *aWidget = new QqWidget(freej, tabWidget, this);
diff --git a/qt/qfreej.h b/qt/qfreej.h
index 9f747ae..cc726f6 100644
--- a/qt/qfreej.h
+++ b/qt/qfreej.h
@@ -39,6 +39,7 @@ public:
QJackClient *getQjack();
Context *getFreej();
OggTheoraEncoder *getEnc();
+ QEncoder *getQEnc();
void resetEnc();
void resetQJack();
diff --git a/src/fps.cpp b/src/fps.cpp
index bfd2f16..ae4f3c6 100644
--- a/src/fps.cpp
+++ b/src/fps.cpp
@@ -19,6 +19,7 @@
*
*/
+#include <iostream>
#include <stdlib.h>
#include <errno.h>
@@ -33,7 +34,7 @@
FPS::FPS() {
_fps = 0;
-
+ _period = 0;
fpsd.sum = 0;
fpsd.i = 0;
fpsd.n = 30;
@@ -42,26 +43,26 @@ FPS::FPS() {
wake_ts.tv_sec = wake_ts.tv_nsec = 0;
- if(pthread_mutex_init (&_mutex,NULL) == -1)
- error("error initializing POSIX thread feed mutex");
- if(pthread_cond_init (&_cond, NULL) == -1)
- error("error initializing POSIX thread feed condtition");
+// if(pthread_mutex_init (&_mutex,NULL) == -1)
+// error("error initializing POSIX thread feed mutex");
+// if(pthread_cond_init (&_cond, NULL) == -1)
+// error("error initializing POSIX thread feed condtition");
}
FPS::~FPS() {
free(fpsd.data);
- if(pthread_mutex_destroy(&_mutex) == -1)
+/* if(pthread_mutex_destroy(&_mutex) == -1)
error("error destroying POSIX thread feed mutex");
if(pthread_cond_destroy(&_cond) == -1)
- error("error destroying POSIX thread feed attribute");
+ error("error destroying POSIX thread feed attribute");*/
}
-void FPS::init(int rate) {
+void FPS::init(double rate) {
- this->set(25);
+ this->set(rate);
for (int i=0; i<30; i++) {
fpsd.data[i] = 0;
@@ -84,10 +85,12 @@ void FPS::calc() {
}
timersub(&now_tv, &start_tv, &done);
- int rate = 1000000 / _fps;
+ _period = 1000000 / _fps;
+// std::cerr << "++ tv_sec :" << done.tv_sec << " us :" << done.tv_usec \
+// << " _period :" << _period << " _fps :" << _fps << std::endl;
if ( (done.tv_sec > 0)
- || (done.tv_usec >= rate) ) {
+ || (done.tv_usec >= _period) ) {
start_tv.tv_sec = now_tv.tv_sec;
start_tv.tv_usec = now_tv.tv_usec;
@@ -96,26 +99,26 @@ void FPS::calc() {
}
wake_ts.tv_sec = 0;
- wake_ts.tv_nsec = (rate - done.tv_usec)*1000; // set the delay
+ wake_ts.tv_nsec = (_period - done.tv_usec)*1000; // set the delay
// statistic only
- if (done.tv_usec)
+/* if (done.tv_usec)
curr_fps = 1000000 / done.tv_usec;
else
curr_fps = 0;
fpsd.sum = fpsd.sum - fpsd.data[fpsd.i] + curr_fps;
fpsd.data[fpsd.i] = curr_fps;
- if (++fpsd.i >= fpsd.n) fpsd.i = 0;
+ if (++fpsd.i >= fpsd.n) fpsd.i = 0;*/
}
-int FPS::get() {
+float FPS::get() {
return (_fps ? fpsd.sum / fpsd.n : 0 );
}
-int FPS::set(int rate) {
- func("FPS set to %u",rate);
+double FPS::set(double rate) {
+ func("FPS set to %f",rate);
if (rate < 0) // invalid
return fps_old;
@@ -132,7 +135,9 @@ int FPS::set(int rate) {
#if 1 // use nanosleep (otherwise select_sleep)
void FPS::delay() {
struct timespec remaining = { 0, 0 };
-
+ if(wake_ts.tv_nsec >= 1000000) {
+ wake_ts.tv_nsec = wake_ts.tv_nsec - 1000000; // set the delay
+ }
do {
if (nanosleep(&wake_ts, &remaining) == -1) {
if (errno == EINTR) {
@@ -150,7 +155,33 @@ void FPS::delay() {
} while (wake_ts.tv_nsec > 0);
// update lo start time
gettimeofday(&start_tv,NULL);
-
+ timeval did;
+ timersub(&start_tv, &m_OldTime, &did);
+ int fineAdjust;
+ if ((_period - did.tv_usec) > 100) {
+ wake_ts.tv_nsec = ((_period - did.tv_usec)-(100 + fineAdjust)) * 1000; // set the delay
+ do {
+ if (nanosleep(&wake_ts, &remaining) == -1) {
+ if (errno == EINTR) {
+ // we've been interrupted use remaining and then reset it
+ wake_ts.tv_nsec = remaining.tv_nsec;
+ remaining.tv_sec = remaining.tv_nsec = 0;
+ } else {
+ error("nanosleep returned an error, not performing delay!");
+ wake_ts.tv_sec = wake_ts.tv_nsec = 0;
+ }
+ } else {
+ // nanosleep successful, reset wake_ts
+ wake_ts.tv_sec = wake_ts.tv_nsec = 0;
+ }
+ } while (wake_ts.tv_nsec > 0);
+ gettimeofday(&start_tv,NULL);
+ timersub(&start_tv, &m_OldTime, &did);
+ }
+ fineAdjust = _period - did.tv_usec;
+// std::cerr << "++ did in us :" << did.tv_usec << std::endl;
+ m_OldTime.tv_sec = start_tv.tv_sec;
+ m_OldTime.tv_usec = start_tv.tv_usec;
}
#else
diff --git a/src/include/context.h b/src/include/context.h
index 1626e50..0c2583f 100644
--- a/src/include/context.h
+++ b/src/include/context.h
@@ -164,7 +164,7 @@ class Context {
/* Set the interval (in frames) after
the fps counter is updated */
FPS fps;
- int fps_speed;
+ double fps_speed;
bool clear_all;
bool start_running;
diff --git a/src/include/fps.h b/src/include/fps.h
index ae790cb..c6182ea 100644
--- a/src/include/fps.h
+++ b/src/include/fps.h
@@ -21,7 +21,7 @@
#ifndef __FPS_H__
#define __FPS_H__
-#include <pthread.h>
+// #include <pthread.h>
#include <inttypes.h>
class FPS {
@@ -29,16 +29,15 @@ class FPS {
FPS();
~FPS();
- void init(int rate);
+ void init(double rate);
- int get();
- int set(int rate);
+ float get();
+ double set(double rate);
void calc();
void delay();
void select_sleep(long usec);
- float fps, fps_old;
- struct timespec wake_ts;
+ double fps, fps_old;
private:
@@ -49,12 +48,13 @@ class FPS {
float *data;
} fpsd;
- float _delay, _fps;
- struct timeval start_tv;
-
+ struct timespec wake_ts;
+ double _delay, _fps;
+ struct timeval start_tv, m_OldTime;
+ long int _period;
/* mutex and conditional for the delay */
- pthread_mutex_t _mutex;
- pthread_cond_t _cond;
+// pthread_mutex_t _mutex;
+// pthread_cond_t _cond;
};
diff --git a/src/include/layer.h b/src/include/layer.h
index 15d30aa..77e0da6 100644
--- a/src/include/layer.h
+++ b/src/include/layer.h
@@ -213,7 +213,7 @@ class Layer: public Entry, public JSyncThread {
unsigned int textureID; ///< opengl texture id
- int frame_rate; ///< value set by implemented layer type
+ float frame_rate; ///< value set by implemented layer type
protected:
diff --git a/src/include/theorautils.h b/src/include/theorautils.h
index fa9eb71..4cc1a65 100644
--- a/src/include/theorautils.h
+++ b/src/include/theorautils.h
@@ -21,7 +21,7 @@
#define _F2T_THEORAUTILS_H_
#include <config.h>
-
+#include <samplerate.h>
#include <stdint.h>
#include <theora/theora.h>
#include <vorbis/codec.h>
diff --git a/src/include/video_encoder.h b/src/include/video_encoder.h
index 5070345..d2124a1 100644
--- a/src/include/video_encoder.h
+++ b/src/include/video_encoder.h
@@ -126,7 +126,7 @@ class VideoEncoder: public Entry, public JSyncThread {
// char encbuf[1024*128];
// char encbuf[1024*2096];
char *encbuf;
- struct timeval m_ActualTime, m_OldTime;
+ struct timeval m_ActualTime, m_OldTime, m_lastTime;
double m_StreamRate;
int m_Streamed;
double m_ElapsedTime;
diff --git a/src/include/video_layer.h b/src/include/video_layer.h
index 48118f3..37ddea9 100644
--- a/src/include/video_layer.h
+++ b/src/include/video_layer.h
@@ -157,7 +157,7 @@ class VideoLayer: public Layer {
double mark_out;
/** dropping frames variables */
int user_play_speed; /** play speed to be visualized to the user */
- int play_speed; /** real speed */
+ float play_speed; /** real speed */
int play_speed_control;
diff --git a/src/theorautils.cpp b/src/theorautils.cpp
index dec9077..3526519 100644
--- a/src/theorautils.cpp
+++ b/src/theorautils.cpp
@@ -25,7 +25,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <time.h>
+#include <sys/time.h>
#include <iostream>
@@ -72,7 +72,7 @@ static double rint(double x)
void init_info(oggmux_info *info) {
info->audio_only = 0;
- info->with_skeleton = 0; /* skeleton is enabled by default */
+ info->with_skeleton = 1; /* skeleton is enabled by default */
info->frontend = NULL; /*frontend mode*/
info->videotime = 0;
info->audiotime = 0;
@@ -279,17 +279,25 @@ void *timer_start(void)
return (void *)start;
}
-
+int sampleError;
+SRC_STATE *src_state;
+SRC_DATA *src_data;
+double ratio, averageR;
+double *sampleOut, samplesA;
void oggmux_init (oggmux_info *info){
ogg_page og;
ogg_packet op;
TIMER *timer;
-
+ src_state = NULL;
+ src_data = NULL;
+ ratio = 1.0;
+ averageR = 1.0;
+ samplesA = 1.0;
+ sampleOut = NULL;
+
/* yayness. Set up Ogg output stream */
srand (time (NULL));
-/* if (ogg_stream_init (&info->vo, rand ()) == -1)*/
-
if(!info->audio_only){
ogg_stream_init (&info->to, rand ()); /* oops, add one ot the above */
@@ -312,7 +320,12 @@ void oggmux_init (oggmux_info *info){
std::cerr << "-------- ogg_stream_init -- failed !!" << std::endl;
return;
}
-
+ if (!(src_state = src_new (0, info->channels, &sampleError))) {
+ std::cerr << "--- error initialysing the SRC_STATE :" << src_strerror (sampleError) << std::endl;
+ }
+ else {
+ src_data = (SRC_DATA *)malloc(sizeof(SRC_DATA));
+ }
vorbis_info_init (&info->vi);//
if (!(info->vorbis_quality >= -0.1) || !(info->vorbis_quality <= 1.0))
info->vorbis_quality = 0.5; //if quality has a wrong value, sets to 0.5
@@ -572,7 +585,6 @@ void oggmux_init (oggmux_info *info){
if (info->with_skeleton) {
add_fisbone_packet (info);
while (1) {
- std::cerr << "------- with_skeleton !!!!" << std::endl;
int result = ogg_stream_flush (&info->so, &og); //3 with_skeleton
if (result < 0) {
/* can't get here */
@@ -666,6 +678,7 @@ void oggmux_add_video (oggmux_info *info, yuv_buffer *yuv, int e_o_s){
}
}
+
/**
* adds audio samples to encoding sink
* @param buffer pointer to buffer
@@ -676,6 +689,7 @@ void oggmux_add_video (oggmux_info *info, yuv_buffer *yuv, int e_o_s){
void oggmux_add_audio (oggmux_info *info, float * buffer, int bytes, int samples, int e_o_s){
ogg_packet op;
float *ptr = buffer;
+ float *sampleOut = NULL;
int i,j, c, count = 0;
float **vorbis_buffer;
@@ -684,18 +698,32 @@ void oggmux_add_audio (oggmux_info *info, float * buffer, int bytes, int samples
if(e_o_s)
vorbis_analysis_wrote (&info->vd, 0);
}
- else{
- vorbis_buffer = vorbis_analysis_buffer (&info->vd, samples); //samples = rv/(channels*sizeof(float))
+ else{ //resample code
+ sampleOut = (float *)realloc(sampleOut, ((samples * info->channels * sizeof(float)) \
+ + (1.2 * ((samples * info->channels * sizeof(float))))));
+ memset(src_data, 0, sizeof(SRC_DATA));
+ src_data->data_in = buffer;
+ src_data->input_frames = (long)samples;
+ src_data->data_out = sampleOut;
+ src_data->output_frames = (long)((double)samples * 1.1);
+ if (ratio > 1.1 || ratio < 0.9)
+ ratio = 1.0;
+ src_data->src_ratio = ratio;
+ src_data->end_of_input = 0;
+ if (int processError = src_process (src_state, src_data)) {
+ std::cerr << "--- resample error :" << src_strerror (processError) << std::endl;
+ }
+
+ vorbis_buffer = vorbis_analysis_buffer (&info->vd, src_data->output_frames_gen); //samples = rv/(channels*sizeof(float))
for (j=0; j < info->channels; j++)
{
- for (i=0, c=0; i < samples; i++, c+=info->channels)
+ for (i=0, c=0; i < src_data->output_frames_gen ; i++, c+=info->channels)
{
- vorbis_buffer[j][i] = buffer[c+j];
+ vorbis_buffer[j][i] = sampleOut[c+j];
}
}
- vorbis_analysis_wrote (&info->vd, samples);
+ vorbis_analysis_wrote (&info->vd, src_data->output_frames_gen);
}
- //for the moment same as encode.c
int ret;
while((ret = vorbis_analysis_blockout (&info->vd, &info->vb)) == 1){ //idem
/* analysis, assume we want to use bitrate management */
@@ -716,7 +744,6 @@ void oggmux_add_audio (oggmux_info *info, float * buffer, int bytes, int samples
else if (bet && OV_EIMPL)
std::cerr << std::endl << "vorbis_analysis_blockout : Unimplemented; \
not supported by this version of the library." << std::endl << std::flush;
-
}
if (ret && OV_EINVAL)
std::cerr << std::endl << "vorbis_analysis_blockout :Invalid parameters." << std::endl << std::flush;
@@ -919,6 +946,14 @@ static int find_best_valid_kate_page(oggmux_info *info)
return best;
}
+double _fabs (double val)
+{
+ if (val >= 0)
+ return (val);
+ else
+ return (-val);
+}
+
void oggmux_flush (oggmux_info *info, int e_o_s)
{
int len;
@@ -930,13 +965,7 @@ void oggmux_flush (oggmux_info *info, int e_o_s)
while(1) {
/* Get pages for both streams, if not already present, and if available.*/
if(!info->audio_only && !info->videopage_valid) {
- // this way seeking is much better,
- // not sure if 23 packets is a good value. it works though
int v_next=0;
-/* if (info->v_pkg>22 && ogg_stream_flush(&info->to, &og) > 0) {
-// std::cerr << "--1--" << std::endl << std::flush;
- v_next=1;
- }*/
if(ogg_stream_pageout(&info->to, &og) > 0) { //2
v_next=1;
}
@@ -958,22 +987,14 @@ void oggmux_flush (oggmux_info *info, int e_o_s)
{
std::cerr << "the given theora granulepos is invalid" << std::endl << std::flush;
}
-// std::cerr << "Theora time :" << info->videotime << std::endl << std::flush;
}
}
}
if(!info->video_only && !info->audiopage_valid) {
- // this way seeking is much better,
- // not sure if 23 packets is a good value. it works though
int a_next=0;
-// if(info->a_pkg>22 && ogg_stream_flush(&info->vo, &og) > 0) {
if(ogg_stream_pageout(&info->vo, &og) > 0) {
a_next=1;
}
-/* else if(ogg_stream_pageout(&info->vo, &og) > 0) {
-// std::cerr << "--v1--" << std::endl << std::flush;
- a_next=1;
- }*/
if(a_next) {
len = og.header_len + og.body_len;
if(info->audiopage_buffer_length < len) {
@@ -990,8 +1011,25 @@ void oggmux_flush (oggmux_info *info, int e_o_s)
ogg_page_granulepos(&og));
if (info->audiotime == -1)
std::cerr << "the given vorbis granulepos is invalid" << std::endl << std::flush;
+ else {
+ samplesA++;
+ ratio = ((info->videotime - info->audiotime) / 60.0 )+ averageR;
+ averageR = (ratio + (averageR * (samplesA - 1))) / samplesA;
+// std::cerr << "ratio :" << ratio << " averageR :" << averageR;
+ if (ratio > (averageR * 1.01)) {
+ ratio = averageR * 1.01;
+// std::cerr << " resampled at:" << ratio << std::endl;
+ }
+ else if (ratio < (averageR * 0.99)) {
+ ratio = averageR * 0.99;
+// std::cerr << " resampled at:" << ratio << std::endl;
+ }
+// else
+// std::cerr << " resampled at:" << ratio << std::endl;
+ }
}
-// std::cerr << "Vorbis time :" << info->audiotime << std::endl << std::flush;
+/* std::cerr << "--- Vorbis time :" << info->audiotime << " Theora time :" \
+ << info->videotime << std::endl << std::flush;*/
}
}
diff --git a/src/v4l2_layer.cpp b/src/v4l2_layer.cpp
index b65dc97..352322c 100644
--- a/src/v4l2_layer.cpp
+++ b/src/v4l2_layer.cpp
@@ -129,7 +129,7 @@ bool V4L2CamLayer::open(const char *devfile) {
return (false);
}
-// memset(&format, 0, sizeof format);
+///////////// does not work with my ricoh and the uvcvideo module .... just comment out if needed
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.width = 352;
format.fmt.pix.height = 288;
diff --git a/src/video_encoder.cpp b/src/video_encoder.cpp
index 21b5e51..2690b7f 100644
--- a/src/video_encoder.cpp
+++ b/src/video_encoder.cpp
@@ -96,28 +96,32 @@ VideoEncoder::VideoEncoder()
fps = new FPS();
fps->init(25); // default FPS
-
// initialize the encoded data pipe
// TODO: set the size to width * height * 4 * nframes (3-4)
ringbuffer = ringbuffer_create(1048*2096);
shout_init();
- ice = shout_new();
+ if ((ice = shout_new()) != NULL) {
- if( shout_set_protocol(ice,SHOUT_PROTOCOL_HTTP) )
- error("shout_set_protocol: %s", shout_get_error(ice));
+ if( shout_set_protocol(ice,SHOUT_PROTOCOL_HTTP) )
+ error("shout_set_protocol: %s", shout_get_error(ice));
- if( shout_set_format(ice,SHOUT_FORMAT_OGG) )
- error("shout_set_format: %s", shout_get_error(ice));
+ if( shout_set_format(ice,SHOUT_FORMAT_OGG) )
+ error("shout_set_format: %s", shout_get_error(ice));
- if( shout_set_agent(ice,"FreeJ - freej.dyne.org") )
- error("shout_set_agent: %s", shout_get_error(ice));
+ if( shout_set_agent(ice,"FreeJ - freej.dyne.org") )
+ error("shout_set_agent: %s", shout_get_error(ice));
- if( shout_set_public(ice,1) )
- error("shout_set_public: %s", shout_get_error(ice));
+ if( shout_set_public(ice,1) )
+ error("shout_set_public: %s", shout_get_error(ice));
+ }
func("init picture_yuv for colorspace conversion (avcodec)");
gettimeofday(&m_OldTime, NULL);
+
+ //uncomment this and beyond to see how long it takes between two frames
+/* m_OldTime.tv_sec = m_lastTime.tv_sec;
+ m_OldTime.tv_usec = m_lastTime.tv_usec;*/
}
VideoEncoder::~VideoEncoder() {
@@ -138,7 +142,7 @@ VideoEncoder::~VideoEncoder() {
nn = fwrite(encbuf, 1, encnum, filedump_fd);
}
- if(write_to_stream) {
+ if(write_to_stream && ice) {
shout_sync(ice);
shout_send(ice, (const unsigned char*)encbuf, encnum);
}
@@ -202,11 +206,14 @@ void VideoEncoder::thread_loop() {
" tv_usec :" << fps->start_tv.tv_usec << " \r" << std::endl;
return;
}
- //gettimeofday(&actual_time,NULL);
- fps->calc(); //without this the thread_loop is called nearly two times more and
- fps->delay(); //stream speed is too slow
- //std::cout << "actual_time.tv_sec :" << actual_time.tv_sec << \
- " tv_usec :" << actual_time.tv_usec << " \r" << std::endl;
+ //uncomment this to see how long it takes between two frames in us.
+/* timeval start_t;
+ gettimeofday(&start_t,NULL);
+ timeval did;
+ timersub(&start_t, &m_lastTime, &did);
+ m_lastTime.tv_sec = start_t.tv_sec;
+ m_lastTime.tv_usec = start_t.tv_usec;
+ std::cerr << "diff time :" << did.tv_usec << std::endl;*/
screen->lock();
switch(screen->get_pixel_format()) {
@@ -259,8 +266,11 @@ void VideoEncoder::thread_loop() {
if(write_to_disk && filedump_fd)
fwrite(encbuf, 1, encnum, filedump_fd);
- if(write_to_stream) {
-// shout_sync(ice); //no sound when commented out !!
+ if(write_to_stream && ice) {
+/* int wait_ms;
+ wait_ms = shout_delay(ice);
+ std::cerr << "---- shout delay :" << wait_ms << std::endl;*/
+ shout_sync(ice);
if( shout_send(ice, (const unsigned char*)encbuf, encnum)
!= SHOUTERR_SUCCESS) {
error("shout_send: %s", shout_get_error(ice));
diff --git a/src/video_layer.cpp b/src/video_layer.cpp
index cfa0348..a127b07 100644
--- a/src/video_layer.cpp
+++ b/src/video_layer.cpp
@@ -218,7 +218,6 @@ bool VideoLayer::open(const char *file) {
*/
case CODEC_TYPE_VIDEO:
// enc->flags |= CODEC_FLAG_LOOP_FILTER;
- std::cout << "CODEC_TYPE_VIDEO i:" << i << std::endl;
video_index = i;
video_codec_ctx = enc;
@@ -252,7 +251,7 @@ bool VideoLayer::open(const char *file) {
/* this saves only file without full path! */
set_filename (file);
- act ("%s (codec: %s) has resolution %dx%d and framerate %d",
+ act ("%s (codec: %s) has resolution %dx%d and framerate %f",
get_filename(), video_codec->name,
video_codec_ctx->width, video_codec_ctx->height, frame_rate);
@@ -262,7 +261,6 @@ bool VideoLayer::open(const char *file) {
break; // //////////////// end of video section
case CODEC_TYPE_AUDIO:
- std::cout << "CODEC_TYPE_AUDIO i:" << i << std::endl;
audio_index = i;
audio_codec_ctx = enc;
func ("VideoLayer :: audio id=%i", audio_index);
@@ -317,7 +315,7 @@ bool VideoLayer::open(const char *file) {
geo.init(video_codec_ctx->width, video_codec_ctx->height, 32);
func("VideoLayer :: w[%u] h[%u] size[%u]", geo.w, geo.h, geo.bytesize);
- func("VideoLayer :: frame_rate[%d]",frame_rate);
+ func("VideoLayer :: frame_rate[%f]",frame_rate);
// initialize picture
if( new_picture(rgba_picture) < 0) {