Windows Port: Fix a rare and intermittent bug that could cause the AVI recording to accidentally stop in between AVI segments. (Regression from commit db1a19a.)

This commit is contained in:
rogerman 2018-03-02 15:59:37 -08:00
parent b8c006b0b5
commit e825cddbe5
2 changed files with 59 additions and 42 deletions

View File

@ -193,9 +193,14 @@ HRESULT AVIFileStream::Open()
error = AVIFileOpen(&this->_file, workingFileName, OF_CREATE | OF_WRITE, NULL); error = AVIFileOpen(&this->_file, workingFileName, OF_CREATE | OF_WRITE, NULL);
if (FAILED(error)) if (FAILED(error))
{ {
this->_file = NULL;
return error; return error;
} }
this->_writtenVideoFrameCount = 0;
this->_writtenAudioSampleCount = 0;
this->_writtenBytes = 0;
if (this->_streamInfo[VIDEO_STREAM].dwSuggestedBufferSize > 0) if (this->_streamInfo[VIDEO_STREAM].dwSuggestedBufferSize > 0)
{ {
error = AVIFileCreateStream(this->_file, &this->_stream[VIDEO_STREAM], &this->_streamInfo[VIDEO_STREAM]); error = AVIFileCreateStream(this->_file, &this->_stream[VIDEO_STREAM], &this->_streamInfo[VIDEO_STREAM]);
@ -256,13 +261,31 @@ HRESULT AVIFileStream::Open()
return error; return error;
} }
void AVIFileStream::Close(FileStreamCloseAction theAction) void AVIFileStream::_CloseStreams()
{ {
if (this->_file == NULL) // _compressedStream[AUDIO_STREAM] is just a copy of _stream[AUDIO_STREAM]
if (this->_compressedStream[AUDIO_STREAM])
{ {
return; AVIStreamClose(this->_compressedStream[AUDIO_STREAM]);
this->_compressedStream[AUDIO_STREAM] = NULL;
this->_stream[AUDIO_STREAM] = NULL;
} }
if (this->_compressedStream[VIDEO_STREAM])
{
AVIStreamClose(this->_compressedStream[VIDEO_STREAM]);
this->_compressedStream[VIDEO_STREAM] = NULL;
}
if (this->_stream[VIDEO_STREAM])
{
AVIStreamClose(this->_stream[VIDEO_STREAM]);
this->_stream[VIDEO_STREAM] = NULL;
}
}
void AVIFileStream::Close(FileStreamCloseAction theAction)
{
switch (theAction) switch (theAction)
{ {
case FSCA_PurgeQueue: case FSCA_PurgeQueue:
@ -283,57 +306,45 @@ void AVIFileStream::Close(FileStreamCloseAction theAction)
case FSCA_WriteRemainingInQueue: case FSCA_WriteRemainingInQueue:
{ {
do if (this->_file != NULL)
{ {
slock_lock(this->_mutexQueue); do
if (this->_writeQueue.empty())
{ {
slock_lock(this->_mutexQueue);
if (this->_writeQueue.empty())
{
slock_unlock(this->_mutexQueue);
break;
}
const AVIFileWriteParam param = this->_writeQueue.front();
slock_unlock(this->_mutexQueue); slock_unlock(this->_mutexQueue);
break;
}
const AVIFileWriteParam param = this->_writeQueue.front(); this->WriteOneFrame(param);
slock_unlock(this->_mutexQueue);
this->WriteOneFrame(param); slock_lock(this->_mutexQueue);
this->_writeQueue.pop();
slock_unlock(this->_mutexQueue);
slock_lock(this->_mutexQueue); ssem_signal(this->_semQueue);
this->_writeQueue.pop();
slock_unlock(this->_mutexQueue);
ssem_signal(this->_semQueue); } while (true);
}
} while (true);
break; break;
} }
case FSCA_DoNothing:
default:
break;
} }
// _compressedStream[AUDIO_STREAM] is just a copy of _stream[AUDIO_STREAM] this->_CloseStreams();
if (this->_compressedStream[AUDIO_STREAM])
if (this->_file != NULL)
{ {
AVIStreamClose(this->_compressedStream[AUDIO_STREAM]); AVIFileClose(this->_file);
this->_compressedStream[AUDIO_STREAM] = NULL; this->_file = NULL;
this->_stream[AUDIO_STREAM] = NULL;
} }
if (this->_compressedStream[VIDEO_STREAM])
{
AVIStreamClose(this->_compressedStream[VIDEO_STREAM]);
this->_compressedStream[VIDEO_STREAM] = NULL;
}
if (this->_stream[VIDEO_STREAM])
{
AVIStreamClose(this->_stream[VIDEO_STREAM]);
this->_stream[VIDEO_STREAM] = NULL;
}
AVIFileClose(this->_file);
this->_file = NULL;
this->_writtenVideoFrameCount = 0;
this->_writtenAudioSampleCount = 0;
this->_writtenBytes = 0;
} }
bool AVIFileStream::IsValid() bool AVIFileStream::IsValid()
@ -451,10 +462,14 @@ HRESULT AVIFileStream::WriteOneFrame(const AVIFileWriteParam &param)
const size_t futureFrameSize = this->_writtenBytes + this->_expectedFrameSize; const size_t futureFrameSize = this->_writtenBytes + this->_expectedFrameSize;
if (futureFrameSize >= MAX_AVI_FILE_SIZE) if (futureFrameSize >= MAX_AVI_FILE_SIZE)
{ {
this->Close(FSCA_DoNothing); PAVIFILE oldFile = this->_file;
this->_CloseStreams();
this->_segmentNumber++; this->_segmentNumber++;
error = this->Open(); error = this->Open();
AVIFileClose(oldFile);
if (FAILED(error)) if (FAILED(error))
{ {
EMU_PrintError("Error creating new AVI segment."); EMU_PrintError("Error creating new AVI segment.");

View File

@ -104,6 +104,8 @@ protected:
slock_t *_mutexQueue; slock_t *_mutexQueue;
AVIWriteQueue _writeQueue; AVIWriteQueue _writeQueue;
void _CloseStreams();
public: public:
AVIFileStream(); AVIFileStream();
~AVIFileStream(); ~AVIFileStream();