summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorniels <niels@dyne.org>2015-08-02 12:03:22 (GMT)
committer niels <niels@dyne.org>2015-08-02 12:03:22 (GMT)
commite690de0b5073d6738b333f260480a8790cf0b9c8 (patch)
treea5d3e7a948c415e428607e0644a20d53c4bfa2bc
parent811673f5b1252ce49632a0bf1003ef9c0e8eaccc (diff)
add commandline option --pace-correction, reduce ringbuffer size, auto-mute audio when audio/video is out of pace, auto-unmute audio when back in pace.
-rw-r--r--veejay-current/veejay-server/bio2jack/bio2jack.c22
-rw-r--r--veejay-current/veejay-server/veejay/liblavplayvj.c26
-rw-r--r--veejay-current/veejay-server/veejay/veejay.c9
-rw-r--r--veejay-current/veejay-server/veejay/vj-lib.h2
-rw-r--r--veejay-current/veejay-server/veejay/vj-perform.c21
-rw-r--r--veejay-current/veejay-server/veejay/vj-pjack.c7
6 files changed, 61 insertions, 26 deletions
diff --git a/veejay-current/veejay-server/bio2jack/bio2jack.c b/veejay-current/veejay-server/bio2jack/bio2jack.c
index 8f93095..f5f97fb 100644
--- a/veejay-current/veejay-server/bio2jack/bio2jack.c
+++ b/veejay-current/veejay-server/bio2jack/bio2jack.c
@@ -40,7 +40,7 @@
/* set to 1 to enable debug messages */
#define DEBUG_OUTPUT 1
-#define DEFAULT_RB_SIZE 8192
+#define DEFAULT_RB_SIZE 2048
#define OUTFILE stderr
@@ -496,11 +496,11 @@ JACK_callback(nframes_t nframes, void *arg)
the rest of the space with zero bytes so at least there is silence */
if(jackFramesAvailable)
{
- DEBUG("buffer underrun of %ld frames", jackFramesAvailable);
- /* for(i = 0; i < drv->num_output_channels; i++)
+ DEBUG("buffer underrun of %ld frames", jackFramesAvailable);
+ for(i = 0; i < drv->num_output_channels; i++)
sample_silence_float(out_buffer[i] +
(nframes - jackFramesAvailable),
- jackFramesAvailable); */
+ jackFramesAvailable);
}
/* apply volume and demux */
@@ -559,23 +559,16 @@ JACK_callback(nframes_t nframes, void *arg)
nframes, drv->num_input_channels);
}
- long write_space = jack_ringbuffer_write_space(drv->pRecPtr);
- /* if there isn't enough room, make some. sure this discards data, but when dealing with input sources
- it seems like it's better to throw away old data than new */
+ /* long write_space = jack_ringbuffer_write_space(drv->pRecPtr);
if(write_space < jack_bytes)
{
- /* the ringbuffer is designed such that only one thread should ever access each pointer.
- since calling read_advance here will be touching the read pointer which is also accessed
- by JACK_Read, we need to lock the mutex first for safety */
- /* double check the write space after we've gained the lock, just
- in case JACK_Read was being called before we gained it */
write_space = jack_ringbuffer_write_space(drv->pRecPtr);
if(write_space < jack_bytes)
{
ERR("buffer overrun of %ld bytes", jack_bytes - write_space);
jack_ringbuffer_read_advance(drv->pRecPtr, jack_bytes - write_space);
}
- }
+ }*/
jack_ringbuffer_write(drv->pRecPtr, drv->callback_buffer1,
jack_bytes);
@@ -1129,7 +1122,7 @@ JACK_Reset(int deviceID)
* open the audio device for writing to
*
* deviceID is set to the opened device
- * if client is non-zero and in_use is FALSE then just set in_use to TRUE
+ * if client is non-zero and in_use is FALSE then just set in_use to TRU
*
* return value is zero upon success, non-zero upon failure
*
@@ -1423,7 +1416,6 @@ JACK_Write(int deviceID, unsigned char *data, unsigned long bytes)
/* handle the case where the user calls this routine with 0 bytes */
if(bytes == 0 || frames_free < 1)
{
- DEBUG("no room left");
return 0; /* indicate that we couldn't write any bytes */
}
diff --git a/veejay-current/veejay-server/veejay/liblavplayvj.c b/veejay-current/veejay-server/veejay/liblavplayvj.c
index 948e89a..8c1c217 100644
--- a/veejay-current/veejay-server/veejay/liblavplayvj.c
+++ b/veejay-current/veejay-server/veejay/liblavplayvj.c
@@ -2187,11 +2187,13 @@ static void veejay_playback_cycle(veejay_t * info)
editlist *el = info->edit_list;
struct mjpeg_sync bs;
struct timespec time_now;
+ struct timespec time_last;
double tdiff1=0.0, tdiff2=0.0;
int first_free, skipv, skipa, skipi, nvcorr,frame;
long ts, te;
int n;
-
+ const int spvf_c = (const int) (1000 * settings->spvf);
+ int pace_warning = 0;
veejay_set_instance( info );
stats.tdiff = 0.0;
stats.num_corrs_a = 0;
@@ -2349,7 +2351,7 @@ static void veejay_playback_cycle(veejay_t * info)
stats.tdiff += settings->spvf;
}
}
-
+
frame = n % QUEUE_LEN;
#ifdef HAVE_SDL
ts= SDL_GetTicks();
@@ -2389,10 +2391,24 @@ static void veejay_playback_cycle(veejay_t * info)
#else
info->real_fps = 0;
#endif
+ //@ add pace correction
+ if( info->audio == AUDIO_PLAY ){
+ info->real_fps += settings->pace_correction;
+ }
- if( (stats.tdiff > settings->spvf || info->real_fps > (1000 * settings->spvf)) && info->real_fps && info->audio == AUDIO_PLAY) {
- veejay_msg(VEEJAY_MSG_WARNING, "Can't keep pace with audio! Rendering audio/video frame takes too long (measured %-4ld ms, out of sync by %-2.4f seconds)",(float) stats.tdiff, info->real_fps);
-
+ if( (fabs(stats.tdiff) > settings->spvf || info->real_fps > spvf_c) && info->real_fps && info->audio == AUDIO_PLAY) {
+ if( pace_warning == 0 ) {
+ veejay_msg(VEEJAY_MSG_WARNING, "Can't keep pace with audio! Rendering audio/video frame takes too long (measured %-4ld ms, out of sync by %-2.4f ms)",info->real_fps,
+ (spvf_c - info->real_fps));
+ pace_warning = (pace_warning + 1) % spvf_c;
+ }
+ if(!settings->auto_mute)
+ settings->auto_mute = 1;
+ } else {
+ if( info->audio == AUDIO_PLAY && settings->auto_mute ) {
+ veejay_msg(VEEJAY_MSG_WARNING, "Back in pace with audio, audio is now unmuted." );
+ settings->auto_mute = 0;
+ }
}
if( skipv ) {
diff --git a/veejay-current/veejay-server/veejay/veejay.c b/veejay-current/veejay-server/veejay/veejay.c
index 41a9da4..a99ea09 100644
--- a/veejay-current/veejay-server/veejay/veejay.c
+++ b/veejay-current/veejay-server/veejay/veejay.c
@@ -236,6 +236,8 @@ static void Usage(char *progname)
" -g/--clip-as-sample\t\tLoad every video clip as a new sample\n");
fprintf(stderr,
" -a/--audio [01]\t\tEnable (1) or disable (0) audio (default 1)\n");
+ fprintf(stderr,
+ " --pace-correction [ms]\tAudio pace correction offset in milliseconds\n");
fprintf(stderr,
" -c/--synchronization [01]\tSync correction off/on (default on)\n");
fprintf(stderr,
@@ -339,6 +341,12 @@ static int set_option(const char *name, char *value)
veejay_set_colors(0);
} else if (strcmp(name, "audio") == 0 || strcmp(name, "a") == 0) {
info->audio = atoi(optarg);
+ } else if (strcmp(name, "pace-correction") == 0 ) {
+ info->settings->pace_correction = atoi( optarg);
+ if( info->settings->pace_correction < 0 ) {
+ fprintf(stderr, "Audio pace correction must be a positive value\n");
+ nerr++;
+ }
} else if ( strcmp(name, "A" ) == 0 || strcmp(name, "capture-device" ) == 0 ) {
live = atoi(optarg);
} else if ( strcmp(name, "Z" ) == 0 || strcmp(name, "load-generators" ) == 0 ) {
@@ -600,6 +608,7 @@ static int check_command_line_options(int argc, char *argv[])
{"qrcode-connection-info",0,0,0},
{"scene-detection",1,0,0},
{"dynamic-fx-chain",0,0,0},
+ {"pace-correction",1,0,0},
{0, 0, 0, 0}
};
#endif
diff --git a/veejay-current/veejay-server/veejay/vj-lib.h b/veejay-current/veejay-server/veejay/vj-lib.h
index 6a3d3ec..02c7fe5 100644
--- a/veejay-current/veejay-server/veejay/vj-lib.h
+++ b/veejay-current/veejay-server/veejay/vj-lib.h
@@ -196,6 +196,8 @@ typedef struct {
int hold_pos;
int hold_resume;
int hold_status;
+ int auto_mute;
+ int pace_correction;
} video_playback_setup;
typedef struct {
diff --git a/veejay-current/veejay-server/veejay/vj-perform.c b/veejay-current/veejay-server/veejay/vj-perform.c
index fdda36f..1fd2430 100644
--- a/veejay-current/veejay-server/veejay/vj-perform.c
+++ b/veejay-current/veejay-server/veejay/vj-perform.c
@@ -110,6 +110,7 @@ static int cached_tag_frames[CACHE_SIZE]; /* cache a frame into the buffer only
static int cached_sample_frames[CACHE_SIZE];
static int frame_info[64][SAMPLE_MAX_EFFECTS]; /* array holding frame lengths */
static uint8_t *audio_buffer[SAMPLE_MAX_EFFECTS]; /* the audio buffer */
+static uint8_t *audio_silence_ = NULL;
static uint8_t *lin_audio_buffer_ = NULL;
static uint8_t *top_audio_buffer = NULL;
static uint8_t *audio_rec_buffer = NULL;
@@ -197,9 +198,15 @@ static void vj_perform_copy3( uint8_t **input, uint8_t **output, int Y_len, int
}
#ifdef HAVE_JACK
-static inline void vj_perform_play_audio( uint8_t *source, int len )
+static inline void vj_perform_play_audio( video_playback_setup *settings, uint8_t *source, int len )
{
- vj_jack_play( source, len );
+ // if auto mute is enabled, play muted data
+ // audio_silence_ is allocated once and played in-place of, thus recording chain is not affected by auto-mute
+ if( settings->auto_mute ) {
+ vj_jack_play( audio_silence_, len );
+ } else {
+ vj_jack_play( source, len );
+ }
}
#endif
@@ -788,6 +795,8 @@ size_t vj_perform_fx_chain_size()
static void vj_perform_close_audio() {
if( lin_audio_buffer_ )
free(lin_audio_buffer_ );
+ if( audio_silence_ )
+ free(audio_silence_);
veejay_memset( audio_buffer, 0, sizeof(uint8_t*) * SAMPLE_MAX_EFFECTS );
#ifdef HAVE_JACK
@@ -843,6 +852,10 @@ int vj_perform_init_audio(veejay_t * info)
audio_buffer[i] = lin_audio_buffer_ + (PERFORM_AUDIO_SIZE * i);
}
+ audio_silence_ = (uint8_t*) vj_calloc( sizeof(uint8_t) * PERFORM_AUDIO_SIZE * SAMPLE_MAX_EFFECTS );
+ if(!audio_silence_)
+ return 0;
+
/*
* The simplest way to time stretch the audio is to resample it and then playback the waveform at the original sampling frequency
* This also lowers or raises the pitch, making it just like speeding up or down a tape recording. Perfect!
@@ -2926,7 +2939,7 @@ int vj_perform_queue_audio_frame(veejay_t *info)
int num_samples = (info->edit_list->audio_rate / info->edit_list->video_fps);
int bps = info->edit_list->audio_bps;
veejay_memset( top_audio_buffer, 0, num_samples * bps);
- vj_perform_play_audio( top_audio_buffer, (num_samples * bps ));
+ vj_perform_play_audio( settings, top_audio_buffer, (num_samples * bps ));
return 1;
}
@@ -2982,7 +2995,7 @@ int vj_perform_queue_audio_frame(veejay_t *info)
}
vj_jack_continue( settings->current_playback_speed );
- vj_perform_play_audio( a_buf, (num_samples * bps ));
+ vj_perform_play_audio( settings, a_buf, (num_samples * bps ));
}
#endif
diff --git a/veejay-current/veejay-server/veejay/vj-pjack.c b/veejay-current/veejay-server/veejay/vj-pjack.c
index 12507d8..6d23960 100644
--- a/veejay-current/veejay-server/veejay/vj-pjack.c
+++ b/veejay-current/veejay-server/veejay/vj-pjack.c
@@ -127,7 +127,6 @@ int vj_jack_continue(int speed)
int vj_jack_stop()
{
-
JACK_Reset( driver );
if(JACK_Close(driver))
@@ -156,7 +155,11 @@ int vj_jack_c_play(void *data, int len, int entry)
int vj_jack_play(void *data, int len)
{
- return JACK_Write(driver,data,len);
+ int res = JACK_Write( driver, data, len );
+ if( res == 0 && JACK_GetState(driver) == PLAYING ) {
+ vj_jack_disable();
+ }
+ return res;
}
int vj_jack_set_volume(int volume)