experiment with no ffmpeg thread
parent
c60939e824
commit
daee5b4450
|
@ -288,8 +288,10 @@ Config::~Config() {
|
|||
if ( items ) {
|
||||
for ( int i = 0; i < n_items; i++ ) {
|
||||
delete items[i];
|
||||
items[i] = NULL;
|
||||
}
|
||||
delete[] items;
|
||||
items = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,13 +115,20 @@ int FfmpegCamera::PrimeCapture() {
|
|||
mAudioStreamId = -1;
|
||||
Info( "Priming capture from %s", mPath.c_str() );
|
||||
|
||||
#if THREAD
|
||||
if ( OpenFfmpeg() != 0 ) {
|
||||
ReopenFfmpeg();
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return OpenFfmpeg();
|
||||
#endif
|
||||
}
|
||||
|
||||
int FfmpegCamera::PreCapture() {
|
||||
// If Reopen was called, then ffmpeg is closed and we need to reopen it.
|
||||
if ( ! mCanCapture )
|
||||
return OpenFfmpeg();
|
||||
// Nothing to do here
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -283,14 +290,18 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
}
|
||||
|
||||
if ( ret < 0 ) {
|
||||
Warning("Could not set rtsp_transport method '%s'\n", Method().c_str());
|
||||
Warning("Could not set rtsp_transport method '%s'\n", method.c_str());
|
||||
}
|
||||
|
||||
Debug ( 1, "Calling avformat_open_input" );
|
||||
Debug ( 1, "Calling avformat_open_input for %s", mPath.c_str() );
|
||||
|
||||
mFormatContext = avformat_alloc_context( );
|
||||
mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback;
|
||||
mFormatContext->interrupt_callback.opaque = this;
|
||||
//mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback;
|
||||
//mFormatContext->interrupt_callback.opaque = this;
|
||||
// Speed up find_stream_info
|
||||
//FIXME can speed up initial analysis but need sensible parameters...
|
||||
//mFormatContext->probesize = 32;
|
||||
//mFormatContext->max_analyze_duration = 32;
|
||||
|
||||
if ( avformat_open_input( &mFormatContext, mPath.c_str(), NULL, &opts ) != 0 )
|
||||
#endif
|
||||
|
@ -310,10 +321,6 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
|
||||
Info( "Stream open %s", mPath.c_str() );
|
||||
|
||||
//FIXME can speed up initial analysis but need sensible parameters...
|
||||
//mFormatContext->probesize = 32;
|
||||
//mFormatContext->max_analyze_duration = 32;
|
||||
// Locate stream info from avformat_open_input
|
||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 6, 0, 6, 0)
|
||||
Debug ( 1, "Calling av_find_stream_info" );
|
||||
if ( av_find_stream_info( mFormatContext ) < 0 )
|
||||
|
@ -484,11 +491,17 @@ int FfmpegCamera::ReopenFfmpeg() {
|
|||
|
||||
Debug(2, "ReopenFfmpeg called.");
|
||||
|
||||
#if THREAD
|
||||
mCanCapture = false;
|
||||
if (pthread_create( &mReopenThread, NULL, ReopenFfmpegThreadCallback, (void*) this) != 0){
|
||||
if ( pthread_create( &mReopenThread, NULL, ReopenFfmpegThreadCallback, (void*) this) != 0 ) {
|
||||
// Log a fatal error and exit the process.
|
||||
Fatal( "ReopenFfmpeg failed to create worker thread." );
|
||||
}
|
||||
#else
|
||||
CloseFfmpeg();
|
||||
OpenFfmpeg();
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -499,8 +512,14 @@ int FfmpegCamera::CloseFfmpeg() {
|
|||
|
||||
mCanCapture = false;
|
||||
|
||||
av_frame_free( &mFrame );
|
||||
av_frame_free( &mRawFrame );
|
||||
if ( mFrame ) {
|
||||
av_frame_free( &mFrame );
|
||||
mFrame = NULL;
|
||||
}
|
||||
if ( mRawFrame ) {
|
||||
av_frame_free( &mRawFrame );
|
||||
mRawFrame = NULL;
|
||||
}
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( mConvertContext ) {
|
||||
|
@ -511,12 +530,12 @@ int FfmpegCamera::CloseFfmpeg() {
|
|||
|
||||
if ( mVideoCodecContext ) {
|
||||
avcodec_close(mVideoCodecContext);
|
||||
av_free(mVideoCodecContext);
|
||||
//av_free(mVideoCodecContext);
|
||||
mVideoCodecContext = NULL; // Freed by av_close_input_file
|
||||
}
|
||||
if ( mAudioCodecContext ) {
|
||||
avcodec_close(mAudioCodecContext);
|
||||
av_free(mAudioCodecContext);
|
||||
//av_free(mAudioCodecContext);
|
||||
mAudioCodecContext = NULL; // Freed by av_close_input_file
|
||||
}
|
||||
|
||||
|
@ -533,11 +552,12 @@ int FfmpegCamera::CloseFfmpeg() {
|
|||
}
|
||||
|
||||
int FfmpegCamera::FfmpegInterruptCallback(void *ctx) {
|
||||
Debug(3,"FfmpegInteruptCallback");
|
||||
FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
|
||||
if ( camera->mIsOpening ) {
|
||||
int now = time(NULL);
|
||||
if ( (now - camera->mOpenStart) > config.ffmpeg_open_timeout ) {
|
||||
Error ( "Open video took more than %d seconds.", config.ffmpeg_open_timeout );
|
||||
Error( "Open video took more than %d seconds.", config.ffmpeg_open_timeout );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -546,11 +566,12 @@ int FfmpegCamera::FfmpegInterruptCallback(void *ctx) {
|
|||
}
|
||||
|
||||
void *FfmpegCamera::ReopenFfmpegThreadCallback(void *ctx){
|
||||
if (ctx == NULL) return NULL;
|
||||
Debug(3,"FfmpegReopenThreadtCallback");
|
||||
if ( ctx == NULL ) return NULL;
|
||||
|
||||
FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
|
||||
|
||||
while (1){
|
||||
while (1) {
|
||||
// Close current stream.
|
||||
camera->CloseFfmpeg();
|
||||
|
||||
|
|
|
@ -112,9 +112,16 @@ Logger::Logger() :
|
|||
|
||||
Logger::~Logger() {
|
||||
terminate();
|
||||
smCodes.clear();
|
||||
smSyslogPriorities.clear();
|
||||
#if 0
|
||||
for ( StringMap::iterator itr = smCodes.begin(); itr != smCodes.end(); itr ++ ) {
|
||||
smCodes.erase( itr );
|
||||
}
|
||||
for ( IntMap::iterator itr = smSyslogPriorities.begin(); itr != smSyslogPriorities.end(); itr ++ ) {
|
||||
smSyslogPriorities.erase(itr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Logger::initialise( const std::string &id, const Options &options ) {
|
||||
|
@ -417,124 +424,128 @@ void Logger::closeSyslog() {
|
|||
}
|
||||
|
||||
void Logger::logPrint( bool hex, const char * const filepath, const int line, const int level, const char *fstring, ... ) {
|
||||
if ( level <= mEffectiveLevel ) {
|
||||
char timeString[64];
|
||||
char logString[8192];
|
||||
va_list argPtr;
|
||||
struct timeval timeVal;
|
||||
if ( level > mEffectiveLevel )
|
||||
return;
|
||||
char timeString[64];
|
||||
char logString[8192];
|
||||
va_list argPtr;
|
||||
struct timeval timeVal;
|
||||
|
||||
char *filecopy = strdup(filepath);
|
||||
const char * const file = basename(filecopy);
|
||||
const char *classString = smCodes[level].c_str();
|
||||
char *filecopy = strdup(filepath);
|
||||
const char * const file = basename(filecopy);
|
||||
const char *classString = smCodes[level].c_str();
|
||||
|
||||
if ( level < PANIC || level > DEBUG9 )
|
||||
Panic( "Invalid logger level %d", level );
|
||||
if ( level < PANIC || level > DEBUG9 )
|
||||
Panic( "Invalid logger level %d", level );
|
||||
|
||||
gettimeofday( &timeVal, NULL );
|
||||
gettimeofday( &timeVal, NULL );
|
||||
|
||||
#if 0
|
||||
if ( logRuntime ) {
|
||||
static struct timeval logStart;
|
||||
if ( logRuntime ) {
|
||||
static struct timeval logStart;
|
||||
|
||||
subtractTime( &timeVal, &logStart );
|
||||
subtractTime( &timeVal, &logStart );
|
||||
|
||||
snprintf( timeString, sizeof(timeString), "%ld.%03ld", timeVal.tv_sec, timeVal.tv_usec/1000 );
|
||||
} else {
|
||||
snprintf( timeString, sizeof(timeString), "%ld.%03ld", timeVal.tv_sec, timeVal.tv_usec/1000 );
|
||||
} else {
|
||||
#endif
|
||||
char *timePtr = timeString;
|
||||
timePtr += strftime( timePtr, sizeof(timeString), "%x %H:%M:%S", localtime(&timeVal.tv_sec) );
|
||||
snprintf( timePtr, sizeof(timeString)-(timePtr-timeString), ".%06ld", timeVal.tv_usec );
|
||||
char *timePtr = timeString;
|
||||
timePtr += strftime( timePtr, sizeof(timeString), "%x %H:%M:%S", localtime(&timeVal.tv_sec) );
|
||||
snprintf( timePtr, sizeof(timeString)-(timePtr-timeString), ".%06ld", timeVal.tv_usec );
|
||||
#if 0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pid_t tid;
|
||||
pid_t tid;
|
||||
#ifdef __FreeBSD__
|
||||
long lwpid;
|
||||
thr_self(&lwpid);
|
||||
tid = lwpid;
|
||||
long lwpid;
|
||||
thr_self(&lwpid);
|
||||
tid = lwpid;
|
||||
|
||||
if (tid < 0 ) // Thread/Process id
|
||||
if (tid < 0 ) // Thread/Process id
|
||||
#else
|
||||
#ifdef HAVE_SYSCALL
|
||||
#ifdef __FreeBSD_kernel__
|
||||
if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id
|
||||
if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id
|
||||
|
||||
# else
|
||||
// SOLARIS doesn't have SYS_gettid; don't assume
|
||||
// SOLARIS doesn't have SYS_gettid; don't assume
|
||||
#ifdef SYS_gettid
|
||||
if ( (tid = syscall(SYS_gettid)) < 0 ) // Thread/Process id
|
||||
if ( (tid = syscall(SYS_gettid)) < 0 ) // Thread/Process id
|
||||
#endif // SYS_gettid
|
||||
#endif
|
||||
#endif // HAVE_SYSCALL
|
||||
#endif
|
||||
tid = getpid(); // Process id
|
||||
tid = getpid(); // Process id
|
||||
|
||||
char *logPtr = logString;
|
||||
logPtr += snprintf( logPtr, sizeof(logString), "%s %s[%d].%s-%s/%d [",
|
||||
timeString,
|
||||
mId.c_str(),
|
||||
tid,
|
||||
classString,
|
||||
file,
|
||||
line
|
||||
);
|
||||
char *syslogStart = logPtr;
|
||||
char *logPtr = logString;
|
||||
logPtr += snprintf( logPtr, sizeof(logString), "%s %s[%d].%s-%s/%d [",
|
||||
timeString,
|
||||
mId.c_str(),
|
||||
tid,
|
||||
classString,
|
||||
file,
|
||||
line
|
||||
);
|
||||
char *syslogStart = logPtr;
|
||||
|
||||
va_start( argPtr, fstring );
|
||||
if ( hex ) {
|
||||
unsigned char *data = va_arg( argPtr, unsigned char * );
|
||||
int len = va_arg( argPtr, int );
|
||||
int i;
|
||||
logPtr += snprintf( logPtr, sizeof(logString)-(logPtr-logString), "%d:", len );
|
||||
for ( i = 0; i < len; i++ ) {
|
||||
logPtr += snprintf( logPtr, sizeof(logString)-(logPtr-logString), " %02x", data[i] );
|
||||
}
|
||||
} else {
|
||||
logPtr += vsnprintf( logPtr, sizeof(logString)-(logPtr-logString), fstring, argPtr );
|
||||
va_start( argPtr, fstring );
|
||||
if ( hex ) {
|
||||
unsigned char *data = va_arg( argPtr, unsigned char * );
|
||||
int len = va_arg( argPtr, int );
|
||||
int i;
|
||||
logPtr += snprintf( logPtr, sizeof(logString)-(logPtr-logString), "%d:", len );
|
||||
for ( i = 0; i < len; i++ ) {
|
||||
logPtr += snprintf( logPtr, sizeof(logString)-(logPtr-logString), " %02x", data[i] );
|
||||
}
|
||||
va_end(argPtr);
|
||||
char *syslogEnd = logPtr;
|
||||
strncpy( logPtr, "]\n", sizeof(logString)-(logPtr-logString) );
|
||||
} else {
|
||||
logPtr += vsnprintf( logPtr, sizeof(logString)-(logPtr-logString), fstring, argPtr );
|
||||
}
|
||||
va_end(argPtr);
|
||||
char *syslogEnd = logPtr;
|
||||
strncpy( logPtr, "]\n", sizeof(logString)-(logPtr-logString) );
|
||||
|
||||
if ( level <= mTermLevel ) {
|
||||
printf( "%s", logString );
|
||||
fflush( stdout );
|
||||
}
|
||||
if ( level <= mFileLevel ) {
|
||||
fprintf( mLogFileFP, "%s", logString );
|
||||
if ( level <= mTermLevel ) {
|
||||
puts( logString );
|
||||
fflush( stdout );
|
||||
}
|
||||
if ( level <= mFileLevel ) {
|
||||
if ( mLogFileFP ) {
|
||||
fputs( logString, mLogFileFP );
|
||||
if ( mFlush )
|
||||
fflush( mLogFileFP );
|
||||
} else {
|
||||
puts("Logging to file, but file not open\n");
|
||||
}
|
||||
*syslogEnd = '\0';
|
||||
if ( level <= mDatabaseLevel ) {
|
||||
char sql[ZM_SQL_MED_BUFSIZ];
|
||||
char escapedString[(strlen(syslogStart)*2)+1];
|
||||
}
|
||||
*syslogEnd = '\0';
|
||||
if ( level <= mDatabaseLevel ) {
|
||||
char sql[ZM_SQL_MED_BUFSIZ];
|
||||
char escapedString[(strlen(syslogStart)*2)+1];
|
||||
|
||||
mysql_real_escape_string( &dbconn, escapedString, syslogStart, strlen(syslogStart) );
|
||||
mysql_real_escape_string( &dbconn, escapedString, syslogStart, strlen(syslogStart) );
|
||||
|
||||
snprintf( sql, sizeof(sql), "insert into Logs ( TimeKey, Component, ServerId, Pid, Level, Code, Message, File, Line ) values ( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )", timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString, file, line );
|
||||
if ( mysql_query( &dbconn, sql ) ) {
|
||||
Level tempDatabaseLevel = mDatabaseLevel;
|
||||
databaseLevel( NOLOG );
|
||||
Error( "Can't insert log entry: sql(%s) error(%s)", sql, mysql_error( &dbconn ) );
|
||||
databaseLevel(tempDatabaseLevel);
|
||||
}
|
||||
}
|
||||
if ( level <= mSyslogLevel ) {
|
||||
int priority = smSyslogPriorities[level];
|
||||
//priority |= LOG_DAEMON;
|
||||
syslog( priority, "%s [%s] [%s]", classString, mId.c_str(), syslogStart );
|
||||
snprintf( sql, sizeof(sql), "insert into Logs ( TimeKey, Component, ServerId, Pid, Level, Code, Message, File, Line ) values ( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )", timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString, file, line );
|
||||
if ( mysql_query( &dbconn, sql ) ) {
|
||||
Level tempDatabaseLevel = mDatabaseLevel;
|
||||
databaseLevel( NOLOG );
|
||||
Error( "Can't insert log entry: sql(%s) error(%s)", sql, mysql_error( &dbconn ) );
|
||||
databaseLevel(tempDatabaseLevel);
|
||||
}
|
||||
}
|
||||
if ( level <= mSyslogLevel ) {
|
||||
int priority = smSyslogPriorities[level];
|
||||
//priority |= LOG_DAEMON;
|
||||
syslog( priority, "%s [%s] [%s]", classString, mId.c_str(), syslogStart );
|
||||
}
|
||||
|
||||
free(filecopy);
|
||||
if ( level <= FATAL ) {
|
||||
logTerm();
|
||||
zmDbClose();
|
||||
if ( level <= PANIC )
|
||||
abort();
|
||||
exit( -1 );
|
||||
}
|
||||
free(filecopy);
|
||||
if ( level <= FATAL ) {
|
||||
logTerm();
|
||||
zmDbClose();
|
||||
if ( level <= PANIC )
|
||||
abort();
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -547,6 +558,8 @@ void logInit( const char *name, const Logger::Options &options ) {
|
|||
}
|
||||
|
||||
void logTerm() {
|
||||
if ( Logger::smInstance )
|
||||
if ( Logger::smInstance ) {
|
||||
delete Logger::smInstance;
|
||||
Logger::smInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -396,8 +396,10 @@ Monitor::Monitor(
|
|||
|
||||
if ( purpose == CAPTURE ) {
|
||||
|
||||
this->connect();
|
||||
if ( ! mem_ptr ) exit(-1);
|
||||
if ( ! this->connect() ) {
|
||||
Error("unable to connect, but doing capture");
|
||||
exit(-1);
|
||||
}
|
||||
memset( mem_ptr, 0, mem_size );
|
||||
shared_data->size = sizeof(SharedData);
|
||||
shared_data->active = enabled;
|
||||
|
@ -486,38 +488,53 @@ bool Monitor::connect() {
|
|||
#if ZM_MEM_MAPPED
|
||||
snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", staticConfig.PATH_MAP.c_str(), id );
|
||||
map_fd = open( mem_file, O_RDWR|O_CREAT, (mode_t)0600 );
|
||||
if ( map_fd < 0 )
|
||||
if ( map_fd < 0 ) {
|
||||
Fatal( "Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno) );
|
||||
} else {
|
||||
Debug(3, "Success opening mmap file at (%s)", mem_file );
|
||||
}
|
||||
|
||||
struct stat map_stat;
|
||||
if ( fstat( map_fd, &map_stat ) < 0 )
|
||||
Fatal( "Can't stat memory map file %s: %s, is the zmc process for this monitor running?", mem_file, strerror(errno) );
|
||||
if ( map_stat.st_size != mem_size && purpose == CAPTURE ) {
|
||||
// Allocate the size
|
||||
if ( ftruncate( map_fd, mem_size ) < 0 ) {
|
||||
Fatal( "Can't extend memory map file %s to %d bytes: %s", mem_file, mem_size, strerror(errno) );
|
||||
}
|
||||
} else if ( map_stat.st_size == 0 ) {
|
||||
Error( "Got empty memory map file size %ld, is the zmc process for this monitor running?", map_stat.st_size, mem_size );
|
||||
return false;
|
||||
} else if ( map_stat.st_size != mem_size ) {
|
||||
Error( "Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size );
|
||||
return false;
|
||||
} else {
|
||||
#ifdef MAP_LOCKED
|
||||
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0 );
|
||||
if ( mem_ptr == MAP_FAILED ) {
|
||||
if ( errno == EAGAIN ) {
|
||||
Debug( 1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size );
|
||||
#endif
|
||||
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 );
|
||||
Debug( 1, "Mapped file %s (%d bytes) to locked memory, unlocked", mem_file, mem_size );
|
||||
#ifdef MAP_LOCKED
|
||||
|
||||
if ( map_stat.st_size != mem_size ) {
|
||||
if ( purpose == CAPTURE ) {
|
||||
// Allocate the size
|
||||
if ( ftruncate( map_fd, mem_size ) < 0 ) {
|
||||
Fatal( "Can't extend memory map file %s to %d bytes: %s", mem_file, mem_size, strerror(errno) );
|
||||
}
|
||||
} else if ( map_stat.st_size == 0 ) {
|
||||
Error( "Got empty memory map file size %ld, is the zmc process for this monitor running?", map_stat.st_size, mem_size );
|
||||
return false;
|
||||
} else {
|
||||
Error( "Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Debug(3, "MMap file size is %ld", map_stat.st_size );
|
||||
#ifdef MAP_LOCKED
|
||||
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0 );
|
||||
if ( mem_ptr == MAP_FAILED ) {
|
||||
if ( errno == EAGAIN ) {
|
||||
Debug( 1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size );
|
||||
|
||||
#endif
|
||||
if ( mem_ptr == MAP_FAILED )
|
||||
Fatal( "Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno );
|
||||
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 );
|
||||
Debug( 1, "Mapped file %s (%d bytes) to unlocked memory", mem_file, mem_size );
|
||||
#ifdef MAP_LOCKED
|
||||
} else {
|
||||
Error( "Unable to map file %s (%d bytes) to locked memory (%s)", mem_file, mem_size , strerror(errno) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ( mem_ptr == MAP_FAILED )
|
||||
Fatal( "Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno );
|
||||
if ( mem_ptr == NULL ) {
|
||||
Error( "mmap gave a null address:" );
|
||||
} else {
|
||||
Debug(3, "mmapped to %p", mem_ptr );
|
||||
}
|
||||
#else // ZM_MEM_MAPPED
|
||||
shm_id = shmget( (config.shm_key&0xffff0000)|id, mem_size, IPC_CREAT|0700 );
|
||||
|
@ -536,26 +553,28 @@ bool Monitor::connect() {
|
|||
video_store_data = (VideoStoreData *)((char *)trigger_data + sizeof(TriggerData));
|
||||
struct timeval *shared_timestamps = (struct timeval *)((char *)video_store_data + sizeof(VideoStoreData));
|
||||
unsigned char *shared_images = (unsigned char *)((char *)shared_timestamps + (image_buffer_count*sizeof(struct timeval)));
|
||||
|
||||
|
||||
if(((unsigned long)shared_images % 64) != 0) {
|
||||
if ( ((unsigned long)shared_images % 64) != 0 ) {
|
||||
/* Align images buffer to nearest 64 byte boundary */
|
||||
Debug(3,"Aligning shared memory images to the next 64 byte boundary");
|
||||
shared_images = (uint8_t*)((unsigned long)shared_images + (64 - ((unsigned long)shared_images % 64)));
|
||||
}
|
||||
Debug(3, "Allocating %d image buffers", image_buffer_count );
|
||||
image_buffer = new Snapshot[image_buffer_count];
|
||||
for ( int i = 0; i < image_buffer_count; i++ ) {
|
||||
image_buffer[i].timestamp = &(shared_timestamps[i]);
|
||||
image_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder(), &(shared_images[i*camera->ImageSize()]) );
|
||||
image_buffer[i].image->HoldBuffer(true); /* Don't release the internal buffer or replace it with another */
|
||||
if ( purpose == CAPTURE ) {
|
||||
Debug(3, "Allocating %d image buffers", image_buffer_count );
|
||||
image_buffer = new Snapshot[image_buffer_count];
|
||||
for ( int i = 0; i < image_buffer_count; i++ ) {
|
||||
image_buffer[i].timestamp = &(shared_timestamps[i]);
|
||||
image_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder(), &(shared_images[i*camera->ImageSize()]) );
|
||||
image_buffer[i].image->HoldBuffer(true); /* Don't release the internal buffer or replace it with another */
|
||||
}
|
||||
if ( (deinterlacing & 0xff) == 4) {
|
||||
/* Four field motion adaptive deinterlacing in use */
|
||||
/* Allocate a buffer for the next image */
|
||||
next_buffer.image = new Image( width, height, camera->Colours(), camera->SubpixelOrder());
|
||||
next_buffer.timestamp = new struct timeval;
|
||||
}
|
||||
}
|
||||
if ( (deinterlacing & 0xff) == 4) {
|
||||
/* Four field motion adaptive deinterlacing in use */
|
||||
/* Allocate a buffer for the next image */
|
||||
next_buffer.image = new Image( width, height, camera->Colours(), camera->SubpixelOrder());
|
||||
next_buffer.timestamp = new struct timeval;
|
||||
}
|
||||
|
||||
if ( ( purpose == ANALYSIS ) && analysis_fps ) {
|
||||
// Size of pre event buffer must be greater than pre_event_count
|
||||
// if alarm_frame_count > 1, because in this case the buffer contains
|
||||
|
@ -567,7 +586,7 @@ bool Monitor::connect() {
|
|||
pre_event_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder());
|
||||
}
|
||||
}
|
||||
|
||||
Debug(3, "Success connecting");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -228,11 +228,11 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
|||
audio_output_context = avcodec_alloc_context3( audio_output_codec );
|
||||
// Copy params from inputstream to context
|
||||
ret = avcodec_parameters_to_context( audio_output_context, audio_input_stream->codecpar );
|
||||
if (ret < 0) {
|
||||
if ( ret < 0 ) {
|
||||
Error("Unable to copy audio params to context %s\n", av_make_error_string(ret).c_str());
|
||||
}
|
||||
ret = avcodec_parameters_from_context( audio_output_stream->codecpar, audio_output_context );
|
||||
if (ret < 0) {
|
||||
if ( ret < 0 ) {
|
||||
Error("Unable to copy audio params to stream %s\n", av_make_error_string(ret).c_str());
|
||||
}
|
||||
|
||||
|
@ -324,11 +324,13 @@ VideoStore::~VideoStore(){
|
|||
|
||||
while ( 1 ) {
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||
#if 0
|
||||
ret = avcodec_send_frame( audio_output_context, NULL );
|
||||
if ( ret < 0 ) {
|
||||
Error("Error sending flush to encoder (%d) (%s)", ret, av_err2str( ret ));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
ret = avcodec_receive_packet( audio_output_context, &pkt );
|
||||
if ( ret < 0 ) {
|
||||
Error("ERror encoding audio while flushing (%d) (%s)", ret, av_err2str( ret ));
|
||||
|
@ -377,18 +379,24 @@ VideoStore::~VideoStore(){
|
|||
// What if we were only doing audio recording?
|
||||
if ( video_output_stream ) {
|
||||
avcodec_close(video_output_context);
|
||||
//av_free(video_output_context);
|
||||
video_output_context = NULL;
|
||||
}
|
||||
if (audio_output_stream) {
|
||||
avcodec_close(audio_output_context);
|
||||
//av_free(audio_output_context);
|
||||
audio_output_context = NULL;
|
||||
#ifdef HAVE_LIBAVRESAMPLE
|
||||
if ( resample_context ) {
|
||||
avresample_close( resample_context );
|
||||
avresample_free( &resample_context );
|
||||
}
|
||||
if ( input_frame ) {
|
||||
av_frame_free( &input_frame );
|
||||
input_frame = NULL;
|
||||
}
|
||||
if ( output_frame ) {
|
||||
av_frame_free( &output_frame );
|
||||
output_frame = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -404,15 +412,6 @@ VideoStore::~VideoStore(){
|
|||
|
||||
/* free the stream */
|
||||
avformat_free_context(oc);
|
||||
|
||||
if ( input_frame ) {
|
||||
av_frame_free( &input_frame );
|
||||
input_frame = NULL;
|
||||
}
|
||||
if ( output_frame ) {
|
||||
av_frame_free( &output_frame );
|
||||
output_frame = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool VideoStore::setup_resampler() {
|
||||
|
@ -803,8 +802,8 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
|||
* If we are at the end of the file, pass an empty packet to the decoder
|
||||
* to flush it.
|
||||
*/
|
||||
if ((ret = avcodec_decode_audio4(audio_input_context, input_frame,
|
||||
&data_present, ipkt)) < 0) {
|
||||
if ( (ret = avcodec_decode_audio4(audio_input_context, input_frame,
|
||||
&data_present, ipkt)) < 0 ) {
|
||||
Error( "Could not decode frame (error '%s')\n",
|
||||
av_make_error_string(ret).c_str());
|
||||
dumpPacket( ipkt );
|
||||
|
@ -829,8 +828,10 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
|||
input_frame->nb_samples )) < 0 ) {
|
||||
Error( "Could not resample frame (error '%s')\n",
|
||||
av_make_error_string(ret).c_str());
|
||||
av_frame_unref( input_frame );
|
||||
return 0;
|
||||
}
|
||||
av_frame_unref( input_frame );
|
||||
|
||||
if ( avresample_available( resample_context ) < output_frame->nb_samples ) {
|
||||
Debug(1, "No enough samples yet");
|
||||
|
@ -864,15 +865,22 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
|||
zm_av_packet_unref(&opkt);
|
||||
return 0;
|
||||
}
|
||||
av_frame_unref( output_frame );
|
||||
|
||||
if (( ret = avcodec_receive_packet( audio_output_context, &opkt )) < 0 ) {
|
||||
if ( EAGAIN == ret ) {
|
||||
// THe codec may need more samples than it has, perfectly valid
|
||||
Debug( 3, "Could not recieve packet (error '%s')",
|
||||
av_make_error_string(ret).c_str());
|
||||
} else {
|
||||
Error( "Could not recieve packet (error '%s')",
|
||||
av_make_error_string(ret).c_str());
|
||||
}
|
||||
zm_av_packet_unref(&opkt);
|
||||
av_frame_unref( input_frame );
|
||||
av_frame_unref( output_frame );
|
||||
return 0;
|
||||
}
|
||||
av_frame_unref( input_frame );
|
||||
av_frame_unref( output_frame );
|
||||
#else
|
||||
if (( ret = avcodec_encode_audio2( audio_output_context, &opkt, output_frame, &data_present )) < 0) {
|
||||
Error( "Could not encode frame (error '%s')",
|
||||
|
|
Loading…
Reference in New Issue