summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rMD-exp/include/recordmydesktop.h3
-rw-r--r--rMD-exp/src/cache_frame.c101
-rw-r--r--rMD-exp/src/encode_image_buffer.c19
-rw-r--r--rMD-exp/src/encode_sound_buffer.c30
-rw-r--r--rMD-exp/src/load_cache.c89
-rw-r--r--rMD-exp/src/poll_damage.c1
-rw-r--r--rMD-exp/src/recordmydesktop.c35
-rw-r--r--rMD-exp/src/register_callbacks.c10
8 files changed, 166 insertions, 122 deletions
diff --git a/rMD-exp/include/recordmydesktop.h b/rMD-exp/include/recordmydesktop.h
index 0eafa01..e78b11a 100644
--- a/rMD-exp/include/recordmydesktop.h
+++ b/rMD-exp/include/recordmydesktop.h
@@ -610,5 +610,8 @@ void *CacheImageBuffer(void *pdata);
void InitCacheData(ProgData *pdata,EncData *enc_data_t,CacheData *cache_data_t);
void *CacheSoundBuffer(void *pdata);
void *LoadCache(void *pdata);
+void SyncEncodeImageBuffer(ProgData *pdata);
+void CancelTimer(void);
+void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff);
#endif
diff --git a/rMD-exp/src/cache_frame.c b/rMD-exp/src/cache_frame.c
index c83b54b..45fb660 100644
--- a/rMD-exp/src/cache_frame.c
+++ b/rMD-exp/src/cache_frame.c
@@ -96,12 +96,20 @@ void *CacheImageBuffer(void *pdata){
while(((ProgData *)pdata)->running){
+ int prev;
+ int j;
+ unsigned short ynum,unum,vnum;
+ unsigned char yblocks[256],ublocks[64],vblocks[64];
+ FrameHeader fheader;
+ ynum=unum=vnum=0;
+
pthread_cond_wait(&((ProgData *)pdata)->image_buffer_ready,&imut);
if(Paused)
pthread_cond_wait(&((ProgData *)pdata)->pause_cond,&pmut);
pthread_mutex_lock(&((ProgData *)pdata)->yuv_mutex);
//rotate buffers
+ prev=current;
current=(current)?0:1;
//copy incoming
memcpy(yuv[current].y,((ProgData *)pdata)->enc_data->yuv.y,yuv[current].y_width*yuv[current].y_height);
@@ -117,16 +125,21 @@ void *CacheImageBuffer(void *pdata){
//find and flush different blocks
if(firstrun){
firstrun=0;
- continue;
+ for(j=0;j<pow(divisor,2);j++){
+ ynum++;
+ yblocks[ynum-1]=j;
+ }
+ for(j=0;j<pow(divisor/2,2);j++){
+ unum++;
+ ublocks[unum-1]=j;
+ }
+ for(j=0;j<pow(divisor/2,2);j++){
+ vnum++;
+ vblocks[vnum-1]=j;
+ }
+
}
else{
- int prev=(current)?0:1;
- int j;
- unsigned short ynum,unum,vnum;
- unsigned char yblocks[256],ublocks[64],vblocks[64];
- FrameHeader fheader;
- ynum=unum=vnum=0;
-
for(j=0;j<pow(divisor,2);j++){
if(checksums_y[current][j]!=checksums_y[prev][j]){
ynum++;
@@ -145,43 +158,41 @@ void *CacheImageBuffer(void *pdata){
vblocks[vnum-1]=j;
}
}
- /**WRITE FRAME TO DISK*/
- if(ynum+unum+vnum>(pow(divisor,2)+pow(divisor/2,2)*2)/10)
- gzsetparams (fp,1,Z_FILTERED);
- else
- gzsetparams (fp,0,Z_FILTERED);
- strncpy(fheader.frame_prefix,"FRAM",4);
- fheader.frameno=++frameno;
- fheader.current_total=frames_total;
- fheader.Ynum=ynum;
- fheader.Unum=unum;
- fheader.Vnum=vnum;
- fheader.pad=0;
- gzwrite(fp,(void*)&fheader,sizeof(FrameHeader));
- //flush indexes
- if(ynum)gzwrite(fp,yblocks,ynum);
- if(unum)gzwrite(fp,ublocks,unum);
- if(vnum)gzwrite(fp,vblocks,vnum);
-
-
- //flush the blocks for each buffer
- if(ynum)
- for(j=0;j<ynum;j++)
- FlushBlock(yuv[current].y,yblocks[j],yuv[current].y_width,yuv[current].y_height,divisor,fp);
- if(unum)
- for(j=0;j<unum;j++)
- FlushBlock(yuv[current].u,ublocks[j],yuv[current].uv_width,yuv[current].uv_height,divisor/2,fp);
- if(vnum)
- for(j=0;j<vnum;j++)
- FlushBlock(yuv[current].v,vblocks[j],yuv[current].uv_width,yuv[current].uv_height,divisor/2,fp);
-
-
- /**@________________@**/
- ((ProgData *)pdata)->avd+=((ProgData *)pdata)->frametime*2*((ProgData *)pdata)->args.channels;
-
-
-
}
+ /**WRITE FRAME TO DISK*/
+ if(ynum+unum+vnum>(pow(divisor,2)+pow(divisor/2,2)*2)/10)
+ gzsetparams (fp,1,Z_FILTERED);
+ else
+ gzsetparams (fp,0,Z_FILTERED);
+ strncpy(fheader.frame_prefix,"FRAM",4);
+ fheader.frameno=++frameno;
+ fheader.current_total=frames_total;
+ fheader.Ynum=ynum;
+ fheader.Unum=unum;
+ fheader.Vnum=vnum;
+ fheader.pad=0;
+ gzwrite(fp,(void*)&fheader,sizeof(FrameHeader));
+ //flush indexes
+ if(ynum)gzwrite(fp,yblocks,ynum);
+ if(unum)gzwrite(fp,ublocks,unum);
+ if(vnum)gzwrite(fp,vblocks,vnum);
+
+
+ //flush the blocks for each buffer
+ if(ynum)
+ for(j=0;j<ynum;j++)
+ FlushBlock(yuv[current].y,yblocks[j],yuv[current].y_width,yuv[current].y_height,divisor,fp);
+ if(unum)
+ for(j=0;j<unum;j++)
+ FlushBlock(yuv[current].u,ublocks[j],yuv[current].uv_width,yuv[current].uv_height,divisor/2,fp);
+ if(vnum)
+ for(j=0;j<vnum;j++)
+ FlushBlock(yuv[current].v,vblocks[j],yuv[current].uv_width,yuv[current].uv_height,divisor/2,fp);
+
+
+ /**@________________@**/
+ ((ProgData *)pdata)->avd+=((ProgData *)pdata)->frametime*2*((ProgData *)pdata)->args.channels;
+
}
//clean up since we're not finished
@@ -190,7 +201,7 @@ void *CacheImageBuffer(void *pdata){
free(yuv[i].u);
free(yuv[i].v);
}
- fprintf(stderr,"Saved %d frames in a total of %d requests",frameno,frames_total);
+ fprintf(stderr,"Saved %d frames in a total of %d requests\n",frameno,frames_total);
gzclose(fp);
pthread_exit(&errno);
}
diff --git a/rMD-exp/src/encode_image_buffer.c b/rMD-exp/src/encode_image_buffer.c
index 2718d0e..0eb5bfb 100644
--- a/rMD-exp/src/encode_image_buffer.c
+++ b/rMD-exp/src/encode_image_buffer.c
@@ -62,4 +62,21 @@ void *EncodeImageBuffer(void *pdata){
pthread_exit(&errno);
}
-
+//this function is meant to be called normally
+//not through a thread of it's own
+void SyncEncodeImageBuffer(ProgData *pdata){
+ if(theora_encode_YUVin(&pdata->enc_data->m_th_st,
+ &pdata->enc_data->yuv)){
+ fprintf(stderr,"Encoder not ready!\n");
+ }
+ else{
+ if(theora_encode_packetout(&pdata->enc_data->m_th_st,0,
+ &pdata->enc_data->m_ogg_pckt1)==1){
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ ogg_stream_packetin(&pdata->enc_data->m_ogg_ts,
+ &pdata->enc_data->m_ogg_pckt1);
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ pdata->avd+=pdata->frametime*2*pdata->args.channels;
+ }
+ }
+} \ No newline at end of file
diff --git a/rMD-exp/src/encode_sound_buffer.c b/rMD-exp/src/encode_sound_buffer.c
index 85e277d..73f6d48 100644
--- a/rMD-exp/src/encode_sound_buffer.c
+++ b/rMD-exp/src/encode_sound_buffer.c
@@ -90,4 +90,32 @@ void *EncodeSoundBuffer(void *pdata){
pthread_exit(&errno);
}
-
+void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff){
+ float **vorbis_buffer;
+ int count=0,i,j;
+ int sampread=pdata->periodsize/(2*pdata->args.channels);
+ vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,sampread);
+ for(i=0;i<sampread;i++){
+ for(j=0;j<pdata->args.channels;j++){
+ vorbis_buffer[j][i]=((buff[count+1]<<8)|
+ (0x00ff&(int)buff[count]))/32768.f;
+ count+=2;
+ }
+ }
+
+ vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread);
+
+ while(vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp,&pdata->enc_data->m_vo_block)==1){
+
+ vorbis_analysis(&pdata->enc_data->m_vo_block,NULL);
+ vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block);
+
+ while(vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp,&pdata->enc_data->m_ogg_pckt2)){
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ ogg_stream_packetin(&pdata->enc_data->m_ogg_vs,&pdata->enc_data->m_ogg_pckt2);
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ }
+ }
+ pdata->avd-=pdata->periodtime;
+}
+
diff --git a/rMD-exp/src/load_cache.c b/rMD-exp/src/load_cache.c
index 246b14e..1c5b29a 100644
--- a/rMD-exp/src/load_cache.c
+++ b/rMD-exp/src/load_cache.c
@@ -36,11 +36,10 @@ void LoadBlock(unsigned char *dest,unsigned char *source,int blockno,int width,
memcpy( &dest[block_i*(width*height/divisor)+j*width+block_k*width/divisor],
&source[j*width/divisor],
width/divisor);
-// gzread(fp,(void *)&dest[block_i*(width*height/divisor)+j*width+block_k*width/divisor],width/divisor);
-// ;
}
+
void *LoadCache(void *pdata){
yuv_buffer *yuv=&((ProgData *)pdata)->enc_data->yuv;
@@ -48,7 +47,13 @@ void *LoadCache(void *pdata){
FILE *afp=((ProgData *)pdata)->cache_data->afp;
FrameHeader fheader;
CachedFrame frame;
+ signed char *sound_data=(signed char *)malloc(((ProgData *)pdata)->periodsize);
+
int j=0,
+ audio_end=0,
+ extra_frames=0,//total number of duplicated frames
+ missing_frames=0,//if this is found >0 current run will not load
+ //a frame but it will proccess the previous
thread_exit=0,//0 success, -1 couldn't find files,1 couldn't remove
divisor=16,
blockszy=0,//size of y plane block in bytes
@@ -69,8 +74,6 @@ void *LoadCache(void *pdata){
pthread_exit(&thread_exit);
}
}
-// int first=10;
-
//recalculate the divisor since it is not saved
while(((((ProgData *)pdata)->brwin.rgeom.width*
((ProgData *)pdata)->brwin.rgeom.width )
@@ -85,16 +88,26 @@ void *LoadCache(void *pdata){
blockszy=(yuv->y_width*yuv->y_height )/pow(divisor,2);
blockszuv=(yuv->uv_width*yuv->uv_height)/pow(divisor/2,2);
-
+ //this will be used now to define if we proccess audio or video
+ //on any given loop.
+ ((ProgData *)pdata)->avd=0;
+ //If sound finishes first,we go on with the video.
+ //If video ends we will do one more run to flush audio in the ogg file
+
while(((ProgData *)pdata)->running){
- int framesize=0;
-// if(first){
- if(gzread(ifp,frame.header,sizeof(FrameHeader))==sizeof(FrameHeader)){
-// fprintf(stderr,"1:%c%c%c%c \n1: %d \n1: %d \n1: %d \n1: %d \n1: %d \n1: %d\n",
-// frame.header->frame_prefix[0],frame.header->frame_prefix[1],frame.header->frame_prefix[2],frame.header->frame_prefix[3],
-// frame.header->frameno,frame.header->current_total
-// ,frame.header->Ynum,frame.header->Unum,frame.header->Vnum,frame.header->pad);fflush(stderr);
- fprintf(stderr,"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b %d of %d",frame.header->frameno,frame.header->current_total);
+ //video load and encoding
+ if(((ProgData *)pdata)->avd<=0 || ((ProgData *)pdata)->args.nosound || audio_end){
+ if(missing_frames>0){
+ extra_frames++;
+ missing_frames--;
+ SyncEncodeImageBuffer((ProgData *)pdata);
+ }
+ else if(gzread(ifp,frame.header,sizeof(FrameHeader))==sizeof(FrameHeader)){
+ //sync
+ missing_frames+=frame.header->current_total-(extra_frames+frame.header->frameno);
+
+ fprintf(stdout,"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+ "%d of %d",frame.header->frameno+extra_frames,frames_total);fflush(stdout);
if( (frame.header->Ynum<=pow(divisor,2)) &&
(frame.header->Unum<=pow(divisor/2,2)) &&
(frame.header->Vnum<=pow(divisor/2,2)) &&
@@ -104,14 +117,6 @@ void *LoadCache(void *pdata){
(gzread(ifp,frame.YData,blockszy*frame.header->Ynum)==blockszy*frame.header->Ynum) &&
(gzread(ifp,frame.UData,(blockszuv*frame.header->Unum))==(blockszuv*frame.header->Unum)) &&
(gzread(ifp,frame.VData,(blockszuv*frame.header->Vnum))==(blockszuv*frame.header->Vnum))){
- framesize+=sizeof(FrameHeader)
- +frame.header->Ynum+frame.header->Unum+frame.header->Vnum
- +blockszy*frame.header->Ynum+(blockszuv*frame.header->Unum)
- +(blockszuv*frame.header->Vnum);
-// fprintf(stderr,"OK! %d \n%d %d %d\n",framesize,blockszy,blockszuv,sizeof(FrameHeader));fflush(stderr);
-
- pthread_mutex_lock(&((ProgData *)pdata)->yuv_mutex);
-
//load the blocks for each buffer
if(frame.header->Ynum)
for(j=0;j<frame.header->Ynum;j++)
@@ -137,44 +142,34 @@ void *LoadCache(void *pdata){
yuv->uv_width,
yuv->uv_height,
divisor/2);
- pthread_mutex_unlock(&((ProgData *)pdata)->yuv_mutex);
-
- while(encoder_busy){
- usleep(100);
- }
- pthread_cond_broadcast(&((ProgData *)pdata)->image_buffer_ready);
- while(encoder_busy){
- usleep(100);
- }
- }
+ //encode. This is not made in a thread since now blocking is not a problem
+ //and this way sync problems can be avoided more easily.
+ SyncEncodeImageBuffer((ProgData *)pdata);
+ }
else{
-// first=0;
raise(SIGINT);
continue;
}
}
else{
-// first=0;
raise(SIGINT);
continue;
}
-
-// }
-
-
- //call loading func{
- //if avd>=0
- //load image from cache
- //signal buffer
- ////if avd<0
- //load sound from cache
- //signal buffer
- //}
-
-// sleep(1);
+ }
+ //audio load and encoding
+ else{
+ if(!audio_end){
+ int nbytes=fread(sound_data,((ProgData *)pdata)->periodsize,1,afp);
+ if(nbytes<=0)
+ audio_end=1;
+ else
+ SyncEncodeSoundBuffer((ProgData *)pdata,sound_data);
+ }
+ }
}
CLEAR_FRAME(&frame)
+ free(sound_data);
gzclose(ifp);
if(remove(((ProgData *)pdata)->cache_data->imgdata)){
diff --git a/rMD-exp/src/poll_damage.c b/rMD-exp/src/poll_damage.c
index 1878439..7ac4e52 100644
--- a/rMD-exp/src/poll_damage.c
+++ b/rMD-exp/src/poll_damage.c
@@ -36,7 +36,6 @@ void *PollDamage(void *pdata){
damage= XDamageCreate( ((ProgData *)pdata)->dpy, ((ProgData *)pdata)->brwin.windowid, XDamageReportRawRectangles);
while(((ProgData *)pdata)->running){
-// if(Paused)pthread_cond_wait(&((ProgData *)pdata)->pause_cond,&((ProgData *)pdata)->pause_cond_mutex);
//damage polling doesn't stop,eventually full image may be needed
XNextEvent(((ProgData *)pdata)->dpy,&event);
if(event.type == ((ProgData *)pdata)->damage_event + XDamageNotify ){
diff --git a/rMD-exp/src/recordmydesktop.c b/rMD-exp/src/recordmydesktop.c
index a90a953..8bb86f8 100644
--- a/rMD-exp/src/recordmydesktop.c
+++ b/rMD-exp/src/recordmydesktop.c
@@ -247,11 +247,9 @@ int main(int argc,char **argv){
pthread_join(flush_to_ogg_t,NULL);
fprintf(stderr,".");
- //this thread will get cancelled instead of joined
- //this is neccessary to terminate the application, if for some reason
- //damage events are not delivered(i.e comp windopw managers)
if(!pdata.args.full_shots)
- pthread_cancel(poll_damage_t);
+ pthread_join(poll_damage_t,NULL);
+
fprintf(stderr,".");
if((!pdata.args.noshared)||(!pdata.args.nocondshared)){
@@ -262,16 +260,16 @@ int main(int argc,char **argv){
fprintf(stderr,"\n");
-
+ //Now that we are done with recording we cancel the timer
+ CancelTimer();
/** Encoding */
if(!pdata.args.encOnTheFly){
if(!Aborted){
-
+ fprintf(stderr,"Encoding started!\nPlease wait...\n");
pdata.running=1;
InitEncoder(&pdata,&enc_data,1);
//load encoding and flushing threads
- pthread_create(&image_encode_t,NULL,EncodeImageBuffer,(void *)&pdata);
if(!pdata.args.nosound){
//before we start loading again
//we need to free any left-overs
@@ -279,8 +277,6 @@ int main(int argc,char **argv){
free(pdata.sound_buffer->data);
pdata.sound_buffer=pdata.sound_buffer->next;
}
- pthread_create(&sound_encode_t,NULL,EncodeSoundBuffer,(void *)&pdata);
-
}
pthread_create(&flush_to_ogg_t,NULL,FlushToOgg,(void *)&pdata);
@@ -288,32 +284,17 @@ int main(int argc,char **argv){
//start loading image and audio
pthread_create(&load_cache_t,NULL,LoadCache,(void *)&pdata);
-
- //call loading func{
- //if avd>=0
- //load image from cache
- //signal buffer
- ////if avd<0
- //load sound from cache
- //signal buffer
- //}
-
//join and finish
-
pthread_join(load_cache_t,NULL);
- pthread_cond_broadcast(&pdata.image_buffer_ready);
- pthread_join(image_encode_t,NULL);
- if(!pdata.args.nosound)
- pthread_join(sound_encode_t,NULL);
-
+ fprintf(stderr,"Encoding finished!\nWait a moment please...\n");
+ pthread_join(flush_to_ogg_t,NULL);
+ fprintf(stderr,"Done!!!\n");
}
- //clean-up data
}
/**@_______________________________________________@*/
//This can happen earlier, but in some cases it might get stuck.
//So we must make sure the recording is not wasted.
- XFlush(pdata.dpy);
XCloseDisplay(pdata.dpy);
if(Aborted){
diff --git a/rMD-exp/src/register_callbacks.c b/rMD-exp/src/register_callbacks.c
index 677fc75..08c528f 100644
--- a/rMD-exp/src/register_callbacks.c
+++ b/rMD-exp/src/register_callbacks.c
@@ -56,6 +56,16 @@ void SetRunning(int signum){
Aborted=1;
}
+void CancelTimer(void){
+ struct itimerval value;
+ value.it_interval.tv_sec=
+ value.it_value.tv_sec=
+ value.it_interval.tv_usec=
+ value.it_value.tv_usec=0;
+
+ setitimer(ITIMER_REAL,&value,NULL);
+}
+
void RegisterCallbacks(ProgArgs *args){
struct itimerval value;
© All Rights Reserved