Index: webrtc/modules/media_file/source/media_file_impl.cc |
diff --git a/webrtc/modules/media_file/source/media_file_impl.cc b/webrtc/modules/media_file/source/media_file_impl.cc |
deleted file mode 100644 |
index 50175b86d550d76a5bf546f551a833f120189edf..0000000000000000000000000000000000000000 |
--- a/webrtc/modules/media_file/source/media_file_impl.cc |
+++ /dev/null |
@@ -1,1137 +0,0 @@ |
-/* |
- * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
-#include <assert.h> |
- |
-#include "webrtc/base/format_macros.h" |
-#include "webrtc/modules/media_file/source/media_file_impl.h" |
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
-#include "webrtc/system_wrappers/include/file_wrapper.h" |
-#include "webrtc/system_wrappers/include/tick_util.h" |
-#include "webrtc/system_wrappers/include/trace.h" |
- |
-namespace webrtc { |
-MediaFile* MediaFile::CreateMediaFile(const int32_t id) |
-{ |
- return new MediaFileImpl(id); |
-} |
- |
-void MediaFile::DestroyMediaFile(MediaFile* module) |
-{ |
- delete static_cast<MediaFileImpl*>(module); |
-} |
- |
-MediaFileImpl::MediaFileImpl(const int32_t id) |
- : _id(id), |
- _crit(CriticalSectionWrapper::CreateCriticalSection()), |
- _callbackCrit(CriticalSectionWrapper::CreateCriticalSection()), |
- _ptrFileUtilityObj(NULL), |
- codec_info_(), |
- _ptrInStream(NULL), |
- _ptrOutStream(NULL), |
- _fileFormat((FileFormats)-1), |
- _recordDurationMs(0), |
- _playoutPositionMs(0), |
- _notificationMs(0), |
- _playingActive(false), |
- _recordingActive(false), |
- _isStereo(false), |
- _openFile(false), |
- _fileName(), |
- _ptrCallback(NULL) |
-{ |
- WEBRTC_TRACE(kTraceMemory, kTraceFile, id, "Created"); |
- |
- codec_info_.plname[0] = '\0'; |
- _fileName[0] = '\0'; |
-} |
- |
- |
-MediaFileImpl::~MediaFileImpl() |
-{ |
- WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, "~MediaFileImpl()"); |
- { |
- CriticalSectionScoped lock(_crit); |
- |
- if(_playingActive) |
- { |
- StopPlaying(); |
- } |
- |
- if(_recordingActive) |
- { |
- StopRecording(); |
- } |
- |
- delete _ptrFileUtilityObj; |
- |
- if(_openFile) |
- { |
- delete _ptrInStream; |
- _ptrInStream = NULL; |
- delete _ptrOutStream; |
- _ptrOutStream = NULL; |
- } |
- } |
- |
- delete _crit; |
- delete _callbackCrit; |
-} |
- |
-int64_t MediaFileImpl::TimeUntilNextProcess() |
-{ |
- WEBRTC_TRACE( |
- kTraceWarning, |
- kTraceFile, |
- _id, |
- "TimeUntilNextProcess: This method is not used by MediaFile class."); |
- return -1; |
-} |
- |
-int32_t MediaFileImpl::Process() |
-{ |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "Process: This method is not used by MediaFile class."); |
- return -1; |
-} |
- |
-int32_t MediaFileImpl::PlayoutAudioData(int8_t* buffer, |
- size_t& dataLengthInBytes) |
-{ |
- WEBRTC_TRACE(kTraceStream, kTraceFile, _id, |
- "MediaFileImpl::PlayoutData(buffer= 0x%x, bufLen= %" PRIuS ")", |
- buffer, dataLengthInBytes); |
- |
- const size_t bufferLengthInBytes = dataLengthInBytes; |
- dataLengthInBytes = 0; |
- |
- if(buffer == NULL || bufferLengthInBytes == 0) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Buffer pointer or length is NULL!"); |
- return -1; |
- } |
- |
- int32_t bytesRead = 0; |
- { |
- CriticalSectionScoped lock(_crit); |
- |
- if(!_playingActive) |
- { |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "Not currently playing!"); |
- return -1; |
- } |
- |
- if(!_ptrFileUtilityObj) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Playing, but no FileUtility object!"); |
- StopPlaying(); |
- return -1; |
- } |
- |
- switch(_fileFormat) |
- { |
- case kFileFormatPcm32kHzFile: |
- case kFileFormatPcm16kHzFile: |
- case kFileFormatPcm8kHzFile: |
- bytesRead = _ptrFileUtilityObj->ReadPCMData( |
- *_ptrInStream, |
- buffer, |
- bufferLengthInBytes); |
- break; |
- case kFileFormatCompressedFile: |
- bytesRead = _ptrFileUtilityObj->ReadCompressedData( |
- *_ptrInStream, |
- buffer, |
- bufferLengthInBytes); |
- break; |
- case kFileFormatWavFile: |
- bytesRead = _ptrFileUtilityObj->ReadWavDataAsMono( |
- *_ptrInStream, |
- buffer, |
- bufferLengthInBytes); |
- break; |
- case kFileFormatPreencodedFile: |
- bytesRead = _ptrFileUtilityObj->ReadPreEncodedData( |
- *_ptrInStream, |
- buffer, |
- bufferLengthInBytes); |
- if(bytesRead > 0) |
- { |
- dataLengthInBytes = static_cast<size_t>(bytesRead); |
- return 0; |
- } |
- break; |
- default: |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Invalid file format: %d", _fileFormat); |
- assert(false); |
- break; |
- } |
- } |
- |
- if( bytesRead > 0) |
- { |
- dataLengthInBytes = static_cast<size_t>(bytesRead); |
- } |
- } |
- HandlePlayCallbacks(bytesRead); |
- return 0; |
-} |
- |
-void MediaFileImpl::HandlePlayCallbacks(int32_t bytesRead) |
-{ |
- bool playEnded = false; |
- uint32_t callbackNotifyMs = 0; |
- |
- if(bytesRead > 0) |
- { |
- // Check if it's time for PlayNotification(..). |
- _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs(); |
- if(_notificationMs) |
- { |
- if(_playoutPositionMs >= _notificationMs) |
- { |
- _notificationMs = 0; |
- callbackNotifyMs = _playoutPositionMs; |
- } |
- } |
- } |
- else |
- { |
- // If no bytes were read assume end of file. |
- StopPlaying(); |
- playEnded = true; |
- } |
- |
- // Only _callbackCrit may and should be taken when making callbacks. |
- CriticalSectionScoped lock(_callbackCrit); |
- if(_ptrCallback) |
- { |
- if(callbackNotifyMs) |
- { |
- _ptrCallback->PlayNotification(_id, callbackNotifyMs); |
- } |
- if(playEnded) |
- { |
- _ptrCallback->PlayFileEnded(_id); |
- } |
- } |
-} |
- |
-int32_t MediaFileImpl::PlayoutStereoData( |
- int8_t* bufferLeft, |
- int8_t* bufferRight, |
- size_t& dataLengthInBytes) |
-{ |
- WEBRTC_TRACE(kTraceStream, kTraceFile, _id, |
- "MediaFileImpl::PlayoutStereoData(Left = 0x%x, Right = 0x%x," |
- " Len= %" PRIuS ")", |
- bufferLeft, |
- bufferRight, |
- dataLengthInBytes); |
- |
- const size_t bufferLengthInBytes = dataLengthInBytes; |
- dataLengthInBytes = 0; |
- |
- if(bufferLeft == NULL || bufferRight == NULL || bufferLengthInBytes == 0) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "A buffer pointer or the length is NULL!"); |
- return -1; |
- } |
- |
- bool playEnded = false; |
- uint32_t callbackNotifyMs = 0; |
- { |
- CriticalSectionScoped lock(_crit); |
- |
- if(!_playingActive || !_isStereo) |
- { |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "Not currently playing stereo!"); |
- return -1; |
- } |
- |
- if(!_ptrFileUtilityObj) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceFile, |
- _id, |
- "Playing stereo, but the FileUtility objects is NULL!"); |
- StopPlaying(); |
- return -1; |
- } |
- |
- // Stereo playout only supported for WAV files. |
- int32_t bytesRead = 0; |
- switch(_fileFormat) |
- { |
- case kFileFormatWavFile: |
- bytesRead = _ptrFileUtilityObj->ReadWavDataAsStereo( |
- *_ptrInStream, |
- bufferLeft, |
- bufferRight, |
- bufferLengthInBytes); |
- break; |
- default: |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Trying to read non-WAV as stereo audio\ |
- (not supported)"); |
- break; |
- } |
- |
- if(bytesRead > 0) |
- { |
- dataLengthInBytes = static_cast<size_t>(bytesRead); |
- |
- // Check if it's time for PlayNotification(..). |
- _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs(); |
- if(_notificationMs) |
- { |
- if(_playoutPositionMs >= _notificationMs) |
- { |
- _notificationMs = 0; |
- callbackNotifyMs = _playoutPositionMs; |
- } |
- } |
- } |
- else |
- { |
- // If no bytes were read assume end of file. |
- StopPlaying(); |
- playEnded = true; |
- } |
- } |
- |
- CriticalSectionScoped lock(_callbackCrit); |
- if(_ptrCallback) |
- { |
- if(callbackNotifyMs) |
- { |
- _ptrCallback->PlayNotification(_id, callbackNotifyMs); |
- } |
- if(playEnded) |
- { |
- _ptrCallback->PlayFileEnded(_id); |
- } |
- } |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::StartPlayingAudioFile( |
- const char* fileName, |
- const uint32_t notificationTimeMs, |
- const bool loop, |
- const FileFormats format, |
- const CodecInst* codecInst, |
- const uint32_t startPointMs, |
- const uint32_t stopPointMs) |
-{ |
- if(!ValidFileName(fileName)) |
- { |
- return -1; |
- } |
- if(!ValidFileFormat(format,codecInst)) |
- { |
- return -1; |
- } |
- if(!ValidFilePositions(startPointMs,stopPointMs)) |
- { |
- return -1; |
- } |
- |
- // Check that the file will play longer than notificationTimeMs ms. |
- if((startPointMs && stopPointMs && !loop) && |
- (notificationTimeMs > (stopPointMs - startPointMs))) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceFile, |
- _id, |
- "specified notification time is longer than amount of ms that will\ |
- be played"); |
- return -1; |
- } |
- |
- FileWrapper* inputStream = FileWrapper::Create(); |
- if(inputStream == NULL) |
- { |
- WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, |
- "Failed to allocate input stream for file %s", fileName); |
- return -1; |
- } |
- |
- if(inputStream->OpenFile(fileName, true, loop) != 0) |
- { |
- delete inputStream; |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Could not open input file %s", fileName); |
- return -1; |
- } |
- |
- if(StartPlayingStream(*inputStream, loop, notificationTimeMs, |
- format, codecInst, startPointMs, stopPointMs) == -1) |
- { |
- inputStream->CloseFile(); |
- delete inputStream; |
- return -1; |
- } |
- |
- CriticalSectionScoped lock(_crit); |
- _openFile = true; |
- strncpy(_fileName, fileName, sizeof(_fileName)); |
- _fileName[sizeof(_fileName) - 1] = '\0'; |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::StartPlayingAudioStream( |
- InStream& stream, |
- const uint32_t notificationTimeMs, |
- const FileFormats format, |
- const CodecInst* codecInst, |
- const uint32_t startPointMs, |
- const uint32_t stopPointMs) |
-{ |
- return StartPlayingStream(stream, false, notificationTimeMs, format, |
- codecInst, startPointMs, stopPointMs); |
-} |
- |
-int32_t MediaFileImpl::StartPlayingStream( |
- InStream& stream, |
- bool loop, |
- const uint32_t notificationTimeMs, |
- const FileFormats format, |
- const CodecInst* codecInst, |
- const uint32_t startPointMs, |
- const uint32_t stopPointMs) |
-{ |
- if(!ValidFileFormat(format,codecInst)) |
- { |
- return -1; |
- } |
- |
- if(!ValidFilePositions(startPointMs,stopPointMs)) |
- { |
- return -1; |
- } |
- |
- CriticalSectionScoped lock(_crit); |
- if(_playingActive || _recordingActive) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceFile, |
- _id, |
- "StartPlaying called, but already playing or recording file %s", |
- (_fileName[0] == '\0') ? "(name not set)" : _fileName); |
- return -1; |
- } |
- |
- if(_ptrFileUtilityObj != NULL) |
- { |
- WEBRTC_TRACE(kTraceError, |
- kTraceFile, |
- _id, |
- "StartPlaying called, but FileUtilityObj already exists!"); |
- StopPlaying(); |
- return -1; |
- } |
- |
- _ptrFileUtilityObj = new ModuleFileUtility(_id); |
- if(_ptrFileUtilityObj == NULL) |
- { |
- WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, |
- "Failed to create FileUtilityObj!"); |
- return -1; |
- } |
- |
- switch(format) |
- { |
- case kFileFormatWavFile: |
- { |
- if(_ptrFileUtilityObj->InitWavReading(stream, startPointMs, |
- stopPointMs) == -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Not a valid WAV file!"); |
- StopPlaying(); |
- return -1; |
- } |
- _fileFormat = kFileFormatWavFile; |
- break; |
- } |
- case kFileFormatCompressedFile: |
- { |
- if(_ptrFileUtilityObj->InitCompressedReading(stream, startPointMs, |
- stopPointMs) == -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Not a valid Compressed file!"); |
- StopPlaying(); |
- return -1; |
- } |
- _fileFormat = kFileFormatCompressedFile; |
- break; |
- } |
- case kFileFormatPcm8kHzFile: |
- case kFileFormatPcm16kHzFile: |
- case kFileFormatPcm32kHzFile: |
- { |
- // ValidFileFormat() called in the beginneing of this function |
- // prevents codecInst from being NULL here. |
- assert(codecInst != NULL); |
- if(!ValidFrequency(codecInst->plfreq) || |
- _ptrFileUtilityObj->InitPCMReading(stream, startPointMs, |
- stopPointMs, |
- codecInst->plfreq) == -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Not a valid raw 8 or 16 KHz PCM file!"); |
- StopPlaying(); |
- return -1; |
- } |
- |
- _fileFormat = format; |
- break; |
- } |
- case kFileFormatPreencodedFile: |
- { |
- // ValidFileFormat() called in the beginneing of this function |
- // prevents codecInst from being NULL here. |
- assert(codecInst != NULL); |
- if(_ptrFileUtilityObj->InitPreEncodedReading(stream, *codecInst) == |
- -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Not a valid PreEncoded file!"); |
- StopPlaying(); |
- return -1; |
- } |
- |
- _fileFormat = kFileFormatPreencodedFile; |
- break; |
- } |
- default: |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Invalid file format: %d", format); |
- assert(false); |
- break; |
- } |
- } |
- if(_ptrFileUtilityObj->codec_info(codec_info_) == -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Failed to retrieve codec info!"); |
- StopPlaying(); |
- return -1; |
- } |
- |
- _isStereo = (codec_info_.channels == 2); |
- if(_isStereo && (_fileFormat != kFileFormatWavFile)) |
- { |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "Stereo is only allowed for WAV files"); |
- StopPlaying(); |
- return -1; |
- } |
- _playingActive = true; |
- _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs(); |
- _ptrInStream = &stream; |
- _notificationMs = notificationTimeMs; |
- |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::StopPlaying() |
-{ |
- |
- CriticalSectionScoped lock(_crit); |
- _isStereo = false; |
- if(_ptrFileUtilityObj) |
- { |
- delete _ptrFileUtilityObj; |
- _ptrFileUtilityObj = NULL; |
- } |
- if(_ptrInStream) |
- { |
- // If MediaFileImpl opened the InStream it must be reclaimed here. |
- if(_openFile) |
- { |
- delete _ptrInStream; |
- _openFile = false; |
- } |
- _ptrInStream = NULL; |
- } |
- |
- codec_info_.pltype = 0; |
- codec_info_.plname[0] = '\0'; |
- |
- if(!_playingActive) |
- { |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "playing is not active!"); |
- return -1; |
- } |
- |
- _playingActive = false; |
- return 0; |
-} |
- |
-bool MediaFileImpl::IsPlaying() |
-{ |
- WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsPlaying()"); |
- CriticalSectionScoped lock(_crit); |
- return _playingActive; |
-} |
- |
-int32_t MediaFileImpl::IncomingAudioData( |
- const int8_t* buffer, |
- const size_t bufferLengthInBytes) |
-{ |
- WEBRTC_TRACE(kTraceStream, kTraceFile, _id, |
- "MediaFile::IncomingData(buffer= 0x%x, bufLen= %" PRIuS, |
- buffer, bufferLengthInBytes); |
- |
- if(buffer == NULL || bufferLengthInBytes == 0) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Buffer pointer or length is NULL!"); |
- return -1; |
- } |
- |
- bool recordingEnded = false; |
- uint32_t callbackNotifyMs = 0; |
- { |
- CriticalSectionScoped lock(_crit); |
- |
- if(!_recordingActive) |
- { |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "Not currently recording!"); |
- return -1; |
- } |
- if(_ptrOutStream == NULL) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Recording is active, but output stream is NULL!"); |
- assert(false); |
- return -1; |
- } |
- |
- int32_t bytesWritten = 0; |
- uint32_t samplesWritten = codec_info_.pacsize; |
- if(_ptrFileUtilityObj) |
- { |
- switch(_fileFormat) |
- { |
- case kFileFormatPcm8kHzFile: |
- case kFileFormatPcm16kHzFile: |
- case kFileFormatPcm32kHzFile: |
- bytesWritten = _ptrFileUtilityObj->WritePCMData( |
- *_ptrOutStream, |
- buffer, |
- bufferLengthInBytes); |
- |
- // Sample size is 2 bytes. |
- if(bytesWritten > 0) |
- { |
- samplesWritten = bytesWritten/sizeof(int16_t); |
- } |
- break; |
- case kFileFormatCompressedFile: |
- bytesWritten = _ptrFileUtilityObj->WriteCompressedData( |
- *_ptrOutStream, buffer, bufferLengthInBytes); |
- break; |
- case kFileFormatWavFile: |
- bytesWritten = _ptrFileUtilityObj->WriteWavData( |
- *_ptrOutStream, |
- buffer, |
- bufferLengthInBytes); |
- if(bytesWritten > 0 && STR_NCASE_CMP(codec_info_.plname, |
- "L16", 4) == 0) |
- { |
- // Sample size is 2 bytes. |
- samplesWritten = bytesWritten/sizeof(int16_t); |
- } |
- break; |
- case kFileFormatPreencodedFile: |
- bytesWritten = _ptrFileUtilityObj->WritePreEncodedData( |
- *_ptrOutStream, buffer, bufferLengthInBytes); |
- break; |
- default: |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Invalid file format: %d", _fileFormat); |
- assert(false); |
- break; |
- } |
- } else { |
- // TODO (hellner): quick look at the code makes me think that this |
- // code is never executed. Remove? |
- if(_ptrOutStream) |
- { |
- if(_ptrOutStream->Write(buffer, bufferLengthInBytes)) |
- { |
- bytesWritten = static_cast<int32_t>(bufferLengthInBytes); |
- } |
- } |
- } |
- |
- _recordDurationMs += samplesWritten / (codec_info_.plfreq / 1000); |
- |
- // Check if it's time for RecordNotification(..). |
- if(_notificationMs) |
- { |
- if(_recordDurationMs >= _notificationMs) |
- { |
- _notificationMs = 0; |
- callbackNotifyMs = _recordDurationMs; |
- } |
- } |
- if(bytesWritten < (int32_t)bufferLengthInBytes) |
- { |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "Failed to write all requested bytes!"); |
- StopRecording(); |
- recordingEnded = true; |
- } |
- } |
- |
- // Only _callbackCrit may and should be taken when making callbacks. |
- CriticalSectionScoped lock(_callbackCrit); |
- if(_ptrCallback) |
- { |
- if(callbackNotifyMs) |
- { |
- _ptrCallback->RecordNotification(_id, callbackNotifyMs); |
- } |
- if(recordingEnded) |
- { |
- _ptrCallback->RecordFileEnded(_id); |
- return -1; |
- } |
- } |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::StartRecordingAudioFile( |
- const char* fileName, |
- const FileFormats format, |
- const CodecInst& codecInst, |
- const uint32_t notificationTimeMs, |
- const uint32_t maxSizeBytes) |
-{ |
- if(!ValidFileName(fileName)) |
- { |
- return -1; |
- } |
- if(!ValidFileFormat(format,&codecInst)) |
- { |
- return -1; |
- } |
- |
- FileWrapper* outputStream = FileWrapper::Create(); |
- if(outputStream == NULL) |
- { |
- WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, |
- "Failed to allocate memory for output stream"); |
- return -1; |
- } |
- |
- if(outputStream->OpenFile(fileName, false) != 0) |
- { |
- delete outputStream; |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Could not open output file '%s' for writing!", |
- fileName); |
- return -1; |
- } |
- |
- if(maxSizeBytes) |
- { |
- outputStream->SetMaxFileSize(maxSizeBytes); |
- } |
- |
- if(StartRecordingAudioStream(*outputStream, format, codecInst, |
- notificationTimeMs) == -1) |
- { |
- outputStream->CloseFile(); |
- delete outputStream; |
- return -1; |
- } |
- |
- CriticalSectionScoped lock(_crit); |
- _openFile = true; |
- strncpy(_fileName, fileName, sizeof(_fileName)); |
- _fileName[sizeof(_fileName) - 1] = '\0'; |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::StartRecordingAudioStream( |
- OutStream& stream, |
- const FileFormats format, |
- const CodecInst& codecInst, |
- const uint32_t notificationTimeMs) |
-{ |
- // Check codec info |
- if(!ValidFileFormat(format,&codecInst)) |
- { |
- return -1; |
- } |
- |
- CriticalSectionScoped lock(_crit); |
- if(_recordingActive || _playingActive) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceFile, |
- _id, |
- "StartRecording called, but already recording or playing file %s!", |
- _fileName); |
- return -1; |
- } |
- |
- if(_ptrFileUtilityObj != NULL) |
- { |
- WEBRTC_TRACE( |
- kTraceError, |
- kTraceFile, |
- _id, |
- "StartRecording called, but fileUtilityObj already exists!"); |
- StopRecording(); |
- return -1; |
- } |
- |
- _ptrFileUtilityObj = new ModuleFileUtility(_id); |
- if(_ptrFileUtilityObj == NULL) |
- { |
- WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, |
- "Cannot allocate fileUtilityObj!"); |
- return -1; |
- } |
- |
- CodecInst tmpAudioCodec; |
- memcpy(&tmpAudioCodec, &codecInst, sizeof(CodecInst)); |
- switch(format) |
- { |
- case kFileFormatWavFile: |
- { |
- if(_ptrFileUtilityObj->InitWavWriting(stream, codecInst) == -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Failed to initialize WAV file!"); |
- delete _ptrFileUtilityObj; |
- _ptrFileUtilityObj = NULL; |
- return -1; |
- } |
- _fileFormat = kFileFormatWavFile; |
- break; |
- } |
- case kFileFormatCompressedFile: |
- { |
- // Write compression codec name at beginning of file |
- if(_ptrFileUtilityObj->InitCompressedWriting(stream, codecInst) == |
- -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Failed to initialize Compressed file!"); |
- delete _ptrFileUtilityObj; |
- _ptrFileUtilityObj = NULL; |
- return -1; |
- } |
- _fileFormat = kFileFormatCompressedFile; |
- break; |
- } |
- case kFileFormatPcm8kHzFile: |
- case kFileFormatPcm16kHzFile: |
- { |
- if(!ValidFrequency(codecInst.plfreq) || |
- _ptrFileUtilityObj->InitPCMWriting(stream, codecInst.plfreq) == |
- -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Failed to initialize 8 or 16KHz PCM file!"); |
- delete _ptrFileUtilityObj; |
- _ptrFileUtilityObj = NULL; |
- return -1; |
- } |
- _fileFormat = format; |
- break; |
- } |
- case kFileFormatPreencodedFile: |
- { |
- if(_ptrFileUtilityObj->InitPreEncodedWriting(stream, codecInst) == |
- -1) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Failed to initialize Pre-Encoded file!"); |
- delete _ptrFileUtilityObj; |
- _ptrFileUtilityObj = NULL; |
- return -1; |
- } |
- |
- _fileFormat = kFileFormatPreencodedFile; |
- break; |
- } |
- default: |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Invalid file format %d specified!", format); |
- delete _ptrFileUtilityObj; |
- _ptrFileUtilityObj = NULL; |
- return -1; |
- } |
- } |
- _isStereo = (tmpAudioCodec.channels == 2); |
- if(_isStereo) |
- { |
- if(_fileFormat != kFileFormatWavFile) |
- { |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "Stereo is only allowed for WAV files"); |
- StopRecording(); |
- return -1; |
- } |
- if((STR_NCASE_CMP(tmpAudioCodec.plname, "L16", 4) != 0) && |
- (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMU", 5) != 0) && |
- (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMA", 5) != 0)) |
- { |
- WEBRTC_TRACE( |
- kTraceWarning, |
- kTraceFile, |
- _id, |
- "Stereo is only allowed for codec PCMU, PCMA and L16 "); |
- StopRecording(); |
- return -1; |
- } |
- } |
- memcpy(&codec_info_, &tmpAudioCodec, sizeof(CodecInst)); |
- _recordingActive = true; |
- _ptrOutStream = &stream; |
- _notificationMs = notificationTimeMs; |
- _recordDurationMs = 0; |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::StopRecording() |
-{ |
- |
- CriticalSectionScoped lock(_crit); |
- if(!_recordingActive) |
- { |
- WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, |
- "recording is not active!"); |
- return -1; |
- } |
- |
- _isStereo = false; |
- |
- if(_ptrFileUtilityObj != NULL) |
- { |
- // Both AVI and WAV header has to be updated before closing the stream |
- // because they contain size information. |
- if((_fileFormat == kFileFormatWavFile) && |
- (_ptrOutStream != NULL)) |
- { |
- _ptrFileUtilityObj->UpdateWavHeader(*_ptrOutStream); |
- } |
- delete _ptrFileUtilityObj; |
- _ptrFileUtilityObj = NULL; |
- } |
- |
- if(_ptrOutStream != NULL) |
- { |
- // If MediaFileImpl opened the OutStream it must be reclaimed here. |
- if(_openFile) |
- { |
- delete _ptrOutStream; |
- _openFile = false; |
- } |
- _ptrOutStream = NULL; |
- } |
- |
- _recordingActive = false; |
- codec_info_.pltype = 0; |
- codec_info_.plname[0] = '\0'; |
- |
- return 0; |
-} |
- |
-bool MediaFileImpl::IsRecording() |
-{ |
- WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsRecording()"); |
- CriticalSectionScoped lock(_crit); |
- return _recordingActive; |
-} |
- |
-int32_t MediaFileImpl::RecordDurationMs(uint32_t& durationMs) |
-{ |
- |
- CriticalSectionScoped lock(_crit); |
- if(!_recordingActive) |
- { |
- durationMs = 0; |
- return -1; |
- } |
- durationMs = _recordDurationMs; |
- return 0; |
-} |
- |
-bool MediaFileImpl::IsStereo() |
-{ |
- WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsStereo()"); |
- CriticalSectionScoped lock(_crit); |
- return _isStereo; |
-} |
- |
-int32_t MediaFileImpl::SetModuleFileCallback(FileCallback* callback) |
-{ |
- |
- CriticalSectionScoped lock(_callbackCrit); |
- |
- _ptrCallback = callback; |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::FileDurationMs(const char* fileName, |
- uint32_t& durationMs, |
- const FileFormats format, |
- const uint32_t freqInHz) |
-{ |
- |
- if(!ValidFileName(fileName)) |
- { |
- return -1; |
- } |
- if(!ValidFrequency(freqInHz)) |
- { |
- return -1; |
- } |
- |
- ModuleFileUtility* utilityObj = new ModuleFileUtility(_id); |
- if(utilityObj == NULL) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "failed to allocate utility object!"); |
- return -1; |
- } |
- |
- const int32_t duration = utilityObj->FileDurationMs(fileName, format, |
- freqInHz); |
- delete utilityObj; |
- if(duration == -1) |
- { |
- durationMs = 0; |
- return -1; |
- } |
- |
- durationMs = duration; |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::PlayoutPositionMs(uint32_t& positionMs) const |
-{ |
- CriticalSectionScoped lock(_crit); |
- if(!_playingActive) |
- { |
- positionMs = 0; |
- return -1; |
- } |
- positionMs = _playoutPositionMs; |
- return 0; |
-} |
- |
-int32_t MediaFileImpl::codec_info(CodecInst& codecInst) const |
-{ |
- CriticalSectionScoped lock(_crit); |
- if(!_playingActive && !_recordingActive) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "Neither playout nor recording has been initialized!"); |
- return -1; |
- } |
- if (codec_info_.pltype == 0 && codec_info_.plname[0] == '\0') |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, _id, |
- "The CodecInst for %s is unknown!", |
- _playingActive ? "Playback" : "Recording"); |
- return -1; |
- } |
- memcpy(&codecInst,&codec_info_,sizeof(CodecInst)); |
- return 0; |
-} |
- |
-bool MediaFileImpl::ValidFileFormat(const FileFormats format, |
- const CodecInst* codecInst) |
-{ |
- if(codecInst == NULL) |
- { |
- if(format == kFileFormatPreencodedFile || |
- format == kFileFormatPcm8kHzFile || |
- format == kFileFormatPcm16kHzFile || |
- format == kFileFormatPcm32kHzFile) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, -1, |
- "Codec info required for file format specified!"); |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool MediaFileImpl::ValidFileName(const char* fileName) |
-{ |
- if((fileName == NULL) ||(fileName[0] == '\0')) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, -1, "FileName not specified!"); |
- return false; |
- } |
- return true; |
-} |
- |
- |
-bool MediaFileImpl::ValidFilePositions(const uint32_t startPointMs, |
- const uint32_t stopPointMs) |
-{ |
- if(startPointMs == 0 && stopPointMs == 0) // Default values |
- { |
- return true; |
- } |
- if(stopPointMs &&(startPointMs >= stopPointMs)) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, -1, |
- "startPointMs must be less than stopPointMs!"); |
- return false; |
- } |
- if(stopPointMs &&((stopPointMs - startPointMs) < 20)) |
- { |
- WEBRTC_TRACE(kTraceError, kTraceFile, -1, |
- "minimum play duration for files is 20 ms!"); |
- return false; |
- } |
- return true; |
-} |
- |
-bool MediaFileImpl::ValidFrequency(const uint32_t frequency) |
-{ |
- if((frequency == 8000) || (frequency == 16000)|| (frequency == 32000)) |
- { |
- return true; |
- } |
- WEBRTC_TRACE(kTraceError, kTraceFile, -1, |
- "Frequency should be 8000, 16000 or 32000 (Hz)"); |
- return false; |
-} |
-} // namespace webrtc |