mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-20 06:40:01 +01:00
prepared sample recorder , prepared status outlet
git-svn-id: svn://code.dyne.org/veejay/trunk@585 eb8d1916-c9e9-0310-b8de-cf0c9472ead5
This commit is contained in:
@@ -71,4 +71,11 @@ typedef struct AFrame_t
|
|||||||
#define PREVIEW_GREYSCALE 1
|
#define PREVIEW_GREYSCALE 1
|
||||||
#define PREVIEW_COLOR 2
|
#define PREVIEW_COLOR 2
|
||||||
|
|
||||||
|
#define ENCODER_MJPEG 0
|
||||||
|
#define ENCODER_YUV420 1
|
||||||
|
#define ENCODER_YUV422 2
|
||||||
|
#define ENCODER_MPEG4 3
|
||||||
|
#define ENCODER_DIVX 4
|
||||||
|
#define ENCODER_DVVIDEO 5
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -901,15 +901,19 @@ int veejay_init(veejay_t * info)
|
|||||||
|
|
||||||
void veejay_playback_status( veejay_t *info )
|
void veejay_playback_status( veejay_t *info )
|
||||||
{
|
{
|
||||||
char status[100];
|
char status_message[300];
|
||||||
|
|
||||||
sprintf( status, "V%03dS%s", 3, "1 0");
|
int len = strlen( info->message );
|
||||||
|
|
||||||
|
sprintf( status_message, "V%03dS%s", len, info->message);
|
||||||
|
|
||||||
|
veejay_msg(0, "Status: '%s'", info->message );
|
||||||
|
|
||||||
int res = vj_server_send(
|
int res = vj_server_send(
|
||||||
info->status_socket,
|
info->status_socket,
|
||||||
info->current_link,
|
info->current_link,
|
||||||
status,
|
status_message,
|
||||||
strlen(status)
|
strlen(status_message)
|
||||||
);
|
);
|
||||||
|
|
||||||
if( res <= 0 )
|
if( res <= 0 )
|
||||||
@@ -1086,12 +1090,18 @@ static void veejay_playback_cycle(veejay_t * info)
|
|||||||
performer_queue_frame(info,skipi);
|
performer_queue_frame(info,skipi);
|
||||||
|
|
||||||
sample_save_cache_data( info->current_sample );
|
sample_save_cache_data( info->current_sample );
|
||||||
|
|
||||||
|
performer_save_frame( info );
|
||||||
|
|
||||||
int cur_id = sample_get_key_ptr( info->current_sample);
|
int cur_id = sample_get_key_ptr( info->current_sample);
|
||||||
if( cur_id != last_id )
|
if( cur_id != last_id )
|
||||||
{
|
{
|
||||||
last_id = cur_id;
|
last_id = cur_id;
|
||||||
performer_audio_restart(info);
|
performer_audio_restart(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sample_format_status( info->current_sample, info->message );
|
||||||
|
|
||||||
//@ and restart performer on sample switch!
|
//@ and restart performer on sample switch!
|
||||||
|
|
||||||
if(skipv) continue;
|
if(skipv) continue;
|
||||||
|
|||||||
@@ -536,6 +536,20 @@ static uint8_t *performer_fetch_audio_frames( veejay_t *info, int *gen_samples )
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void performer_save_frame( veejay_t *info )
|
||||||
|
{
|
||||||
|
performer_t *p = (performer_t*) info->performer;
|
||||||
|
|
||||||
|
if(sample_is_recording( info->current_sample ))
|
||||||
|
sample_record_frame(
|
||||||
|
info->current_sample,
|
||||||
|
p->display,
|
||||||
|
NULL,
|
||||||
|
0 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int performer_queue_audio_frame( veejay_t *info, int skipa )
|
int performer_queue_audio_frame( veejay_t *info, int skipa )
|
||||||
{
|
{
|
||||||
static uint8_t *buffer_ = NULL;
|
static uint8_t *buffer_ = NULL;
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ typedef struct
|
|||||||
pthread_mutex_t display_mutex;
|
pthread_mutex_t display_mutex;
|
||||||
|
|
||||||
int itu601;
|
int itu601;
|
||||||
|
char message[256];
|
||||||
} veejay_t;
|
} veejay_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <libhash/hash.h>
|
#include <libhash/hash.h>
|
||||||
#include <libvevo/libvevo.h>
|
#include <libvevo/libvevo.h>
|
||||||
#include <libel/vj-el.h>
|
#include <libel/vj-el.h>
|
||||||
|
#include <libel/lav_io.h>
|
||||||
#include <veejay/defs.h>
|
#include <veejay/defs.h>
|
||||||
#include <vevosample/defs.h>
|
#include <vevosample/defs.h>
|
||||||
#include <vevosample/vevosample.h>
|
#include <vevosample/vevosample.h>
|
||||||
@@ -99,8 +100,21 @@ typedef struct
|
|||||||
int bps;
|
int bps;
|
||||||
int bits;
|
int bits;
|
||||||
int channels;
|
int channels;
|
||||||
|
double rec; //!< Rec. percentage done
|
||||||
} sampleinfo_t;
|
} sampleinfo_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int rec;
|
||||||
|
int con;
|
||||||
|
int max_size;
|
||||||
|
char format;
|
||||||
|
void *fd;
|
||||||
|
long tf;
|
||||||
|
long nf;
|
||||||
|
uint8_t *buf;
|
||||||
|
} samplerecord_t;
|
||||||
|
|
||||||
//! \typedef sample_runtime_data Sample Runtime Data structure
|
//! \typedef sample_runtime_data Sample Runtime Data structure
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -111,6 +125,7 @@ typedef struct
|
|||||||
int format;
|
int format;
|
||||||
int palette;
|
int palette;
|
||||||
int type; /* type of sample */
|
int type; /* type of sample */
|
||||||
|
samplerecord_t *record;
|
||||||
sampleinfo_t *info;
|
sampleinfo_t *info;
|
||||||
} sample_runtime_data;
|
} sample_runtime_data;
|
||||||
|
|
||||||
@@ -723,6 +738,9 @@ int sample_process_fx( void *sample, int fx_entry )
|
|||||||
return VEVO_NO_ERROR;
|
return VEVO_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int sample_fx_num_in_channels( void *port )
|
int sample_fx_num_in_channels( void *port )
|
||||||
{
|
{
|
||||||
void *fx_channels = NULL;
|
void *fx_channels = NULL;
|
||||||
@@ -1038,6 +1056,8 @@ void *sample_new( int type )
|
|||||||
sampleinfo_t *sit = (sampleinfo_t*) vj_malloc(sizeof(sampleinfo_t));
|
sampleinfo_t *sit = (sampleinfo_t*) vj_malloc(sizeof(sampleinfo_t));
|
||||||
memset( sit,0,sizeof(sampleinfo_t));
|
memset( sit,0,sizeof(sampleinfo_t));
|
||||||
rtdata->info = sit;
|
rtdata->info = sit;
|
||||||
|
rtdata->record = (samplerecord_t*) vj_malloc(sizeof(samplerecord_t));
|
||||||
|
memset(rtdata->record,0,sizeof(samplerecord_t));
|
||||||
rtdata->type = type;
|
rtdata->type = type;
|
||||||
rtdata->info_port = (void*) vevo_port_new( VEVO_SAMPLE_PORT );
|
rtdata->info_port = (void*) vevo_port_new( VEVO_SAMPLE_PORT );
|
||||||
|
|
||||||
@@ -2182,6 +2202,28 @@ void sample_save_cache_data( void *info)
|
|||||||
vevo_property_set( srd->info_port, "repeat",VEVO_ATOM_TYPE_INT,1,&(sit->repeat));
|
vevo_property_set( srd->info_port, "repeat",VEVO_ATOM_TYPE_INT,1,&(sit->repeat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sample_format_status( void *sample, char *buf )
|
||||||
|
{
|
||||||
|
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||||
|
sampleinfo_t *sit = srd->info;
|
||||||
|
|
||||||
|
sprintf(buf,
|
||||||
|
"%04d:%04d:%06d:%06d:%06d:%06d:%06d:%02d:%02d:%d:%03.2g",
|
||||||
|
sample_get_key_ptr( sample ),
|
||||||
|
samplebank_size(),
|
||||||
|
sit->start_pos,
|
||||||
|
sit->end_pos,
|
||||||
|
sit->current_pos,
|
||||||
|
sit->in_point,
|
||||||
|
sit->out_point,
|
||||||
|
sit->speed,
|
||||||
|
sit->repeat,
|
||||||
|
sit->looptype,
|
||||||
|
sit->rec );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int sample_valid_speed(void *sample, int new_speed)
|
int sample_valid_speed(void *sample, int new_speed)
|
||||||
{
|
{
|
||||||
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||||
@@ -2465,3 +2507,221 @@ char *sample_sprintf_port( void *sample )
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long sample_tc_to_frames( const char *tc, float fps )
|
||||||
|
{
|
||||||
|
int h = 0;
|
||||||
|
int m = 0;
|
||||||
|
int s = 0;
|
||||||
|
int f = 0;
|
||||||
|
int n = sscanf( tc, "%d:%d:%d:%d", &h,&m,&s,&f);
|
||||||
|
long res = 0;
|
||||||
|
if( n == 4 )
|
||||||
|
{
|
||||||
|
res += f;
|
||||||
|
res += (long) (fps * s);
|
||||||
|
res += (long) (fps * 60 * m );
|
||||||
|
res += (long) (fps * 3600 * h );
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sample_configure_recorder( void *sample, int format, const char *filename, char *timecode,
|
||||||
|
sample_video_info_t *ps)
|
||||||
|
{
|
||||||
|
char fmt = 'Y'; //default uncompressed format
|
||||||
|
int max_size = 0;
|
||||||
|
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||||
|
sampleinfo_t *sit = srd->info;
|
||||||
|
samplerecord_t *rec = srd->record;
|
||||||
|
|
||||||
|
if( sit->rec )
|
||||||
|
{
|
||||||
|
veejay_msg(VEEJAY_MSG_ERROR, "Please stop the recorder first");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( format )
|
||||||
|
{
|
||||||
|
case ENCODER_DVVIDEO:
|
||||||
|
fmt = 'd';
|
||||||
|
if( ps->w == 720 && (ps->h == 480 || ps->h == 576 ) )
|
||||||
|
max_size = ( ps->h == 480 ? 120000: 144000 );
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ENCODER_MJPEG:
|
||||||
|
fmt = 'a';
|
||||||
|
max_size = 65535 * 4;
|
||||||
|
break;
|
||||||
|
case ENCODER_YUV420:
|
||||||
|
fmt = 'Y';
|
||||||
|
max_size = 2 * ps->h * ps->w;
|
||||||
|
break;
|
||||||
|
case ENCODER_YUV422:
|
||||||
|
fmt = 'P';
|
||||||
|
max_size = 3 * ps->h * ps->w;
|
||||||
|
break;
|
||||||
|
case ENCODER_MPEG4:
|
||||||
|
fmt = 'M';
|
||||||
|
max_size = 65535 * 4;
|
||||||
|
break;
|
||||||
|
case ENCODER_DIVX:
|
||||||
|
fmt = 'D';
|
||||||
|
max_size = 65545 * 4;
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
veejay_msg(VEEJAY_MSG_ERROR, "Unknown recording format");
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(timecode != NULL)
|
||||||
|
rec->tf = sample_tc_to_frames( timecode, ps->fps);
|
||||||
|
else
|
||||||
|
rec->tf = (long) (ps->fps * 60);
|
||||||
|
|
||||||
|
rec->format = fmt;
|
||||||
|
|
||||||
|
int error = vevo_property_set( sample, "filename", VEVO_ATOM_TYPE_STRING,1, &filename );
|
||||||
|
#ifdef STRICT_CHECKING
|
||||||
|
assert( error == VEVO_NO_ERROR );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rec->buf = (uint8_t*) vj_malloc(sizeof(uint8_t) * max_size );
|
||||||
|
if(!rec->buf)
|
||||||
|
{
|
||||||
|
veejay_msg(VEEJAY_MSG_ERROR, "Insufficient memory to allocate buffer for recorder");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset( rec->buf,0, max_size );
|
||||||
|
rec->con = 1;
|
||||||
|
rec->max_size = max_size;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sample_start_recorder( void *sample , sample_video_info_t *ps)
|
||||||
|
{
|
||||||
|
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||||
|
samplerecord_t *rec = srd->record;
|
||||||
|
|
||||||
|
if(!rec->con)
|
||||||
|
{
|
||||||
|
veejay_msg(VEEJAY_MSG_ERROR, "You must configure the recorder first");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(rec->rec)
|
||||||
|
{
|
||||||
|
veejay_msg(VEEJAY_MSG_ERROR, "The recorder is already active");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *destination = get_str_vevo( sample,"filename");
|
||||||
|
#ifdef STRICT_CHECKING
|
||||||
|
assert( destination != NULL );
|
||||||
|
assert( rec->tf > 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rec->fd = (void*)
|
||||||
|
lav_open_output_file( destination, rec->format,
|
||||||
|
ps->w, ps->h, ps->inter, ps->fps,
|
||||||
|
ps->bps, ps->chans, ps->rate );
|
||||||
|
|
||||||
|
if(!rec->fd )
|
||||||
|
{
|
||||||
|
veejay_msg(VEEJAY_MSG_ERROR, "Unable to record to '%s'. Please (re)configure recorder", destination );
|
||||||
|
free(rec->buf);
|
||||||
|
memset( rec, 0 , sizeof( samplerecord_t ));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rec->nf = 0;
|
||||||
|
rec->rec = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int sample_is_recording( void *sample )
|
||||||
|
{
|
||||||
|
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||||
|
samplerecord_t *rec = srd->record;
|
||||||
|
if( rec->rec )
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sample_stop_recorder( void *sample )
|
||||||
|
{
|
||||||
|
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||||
|
samplerecord_t *rec = srd->record;
|
||||||
|
sampleinfo_t *sit = srd->info;
|
||||||
|
if(!rec->rec)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
lav_close( (lav_file_t*) rec->fd );
|
||||||
|
if( rec->buf )
|
||||||
|
free(rec->buf);
|
||||||
|
|
||||||
|
memset( rec, 0, sizeof( samplerecord_t ));
|
||||||
|
|
||||||
|
rec->max_size = 0;
|
||||||
|
sit->rec = 0.0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int sample_record_frame( void *sample, VJFrame *frame, uint8_t *audio_buffer, int a_len )
|
||||||
|
{
|
||||||
|
sample_runtime_data *srd = (sample_runtime_data*) sample;
|
||||||
|
samplerecord_t *rec = srd->record;
|
||||||
|
sampleinfo_t *sit = srd->info;
|
||||||
|
|
||||||
|
int compr_len = vj_avcodec_encode_frame(
|
||||||
|
rec->nf++,
|
||||||
|
rec->format,
|
||||||
|
frame->data,
|
||||||
|
rec->buf,
|
||||||
|
rec->max_size );
|
||||||
|
|
||||||
|
if( compr_len <= 0 )
|
||||||
|
{
|
||||||
|
return sample_stop_recorder( sample );
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = lav_write_audio( (lav_file_t*) rec->fd, rec->buf, compr_len );
|
||||||
|
|
||||||
|
if( n <= 0 )
|
||||||
|
{
|
||||||
|
veejay_msg(VEEJAY_MSG_ERROR, "Writing video frame");
|
||||||
|
return sample_stop_recorder(sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sit->has_audio)
|
||||||
|
{
|
||||||
|
n = lav_write_audio( (lav_file_t*) rec->fd, audio_buffer,a_len );
|
||||||
|
if( n <= 0 )
|
||||||
|
{
|
||||||
|
veejay_msg(VEEJAY_MSG_ERROR, "Writing audio frame");
|
||||||
|
return sample_stop_recorder(sample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rec->nf >= rec->tf )
|
||||||
|
{
|
||||||
|
veejay_msg(VEEJAY_MSG_INFO, "Done recording");
|
||||||
|
sample_stop_recorder(sample);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sit->rec = (double) (1.0/rec->tf) * rec->nf;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -123,5 +123,12 @@ int sample_edl_paste_from_buffer( void *current_sample, uint64_t insert_at );
|
|||||||
|
|
||||||
int sample_edl_cut_to_buffer( void *current_sample, uint64_t start_pos, uint64_t end_pos );
|
int sample_edl_cut_to_buffer( void *current_sample, uint64_t start_pos, uint64_t end_pos );
|
||||||
|
|
||||||
|
int sample_configure_recorder( void *sample, int format, const char *filename, char *timecode, sample_video_info_t *ps );
|
||||||
|
|
||||||
|
int sample_start_recorder( void *sample, sample_video_info_t *ps );
|
||||||
|
|
||||||
|
int sample_stop_recorder( void *sample );
|
||||||
|
|
||||||
|
int sample_record_frame( void *sample, VJFrame *frame, uint8_t *audio_buffer, int a_len );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user