experiment with no ffmpeg thread

pull/2077/head
Isaac Connor 2017-08-11 12:03:37 -04:00
parent c60939e824
commit daee5b4450
5 changed files with 222 additions and 159 deletions

View File

@ -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;
}
}

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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')",