blob: 80b407dd115ed45269275b3521b420fc758e189c [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <assert.h>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/media_file/media_file_impl.h"
14#include "rtc_base/format_macros.h"
15#include "rtc_base/logging.h"
16#include "system_wrappers/include/file_wrapper.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000017
niklase@google.com470e71d2011-07-07 08:21:25 +000018namespace webrtc {
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +000019MediaFile* MediaFile::CreateMediaFile(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000020{
niklase@google.com470e71d2011-07-07 08:21:25 +000021 return new MediaFileImpl(id);
22}
23
24void MediaFile::DestroyMediaFile(MediaFile* module)
25{
niklase@google.com470e71d2011-07-07 08:21:25 +000026 delete static_cast<MediaFileImpl*>(module);
27}
28
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +000029MediaFileImpl::MediaFileImpl(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000030 : _id(id),
niklase@google.com470e71d2011-07-07 08:21:25 +000031 _ptrFileUtilityObj(NULL),
32 codec_info_(),
33 _ptrInStream(NULL),
34 _ptrOutStream(NULL),
35 _fileFormat((FileFormats)-1),
36 _recordDurationMs(0),
37 _playoutPositionMs(0),
38 _notificationMs(0),
39 _playingActive(false),
40 _recordingActive(false),
41 _isStereo(false),
42 _openFile(false),
43 _fileName(),
44 _ptrCallback(NULL)
45{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +020046 LOG(LS_INFO) << "MediaFileImpl()";
niklase@google.com470e71d2011-07-07 08:21:25 +000047
48 codec_info_.plname[0] = '\0';
49 _fileName[0] = '\0';
50}
51
52
53MediaFileImpl::~MediaFileImpl()
54{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +020055 LOG(LS_INFO) << "~MediaFileImpl()";
niklase@google.com470e71d2011-07-07 08:21:25 +000056 {
kthelgason6bfe49c2017-03-30 01:14:41 -070057 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +000058
59 if(_playingActive)
60 {
61 StopPlaying();
62 }
63
64 if(_recordingActive)
65 {
66 StopRecording();
67 }
68
69 delete _ptrFileUtilityObj;
70
71 if(_openFile)
72 {
73 delete _ptrInStream;
74 _ptrInStream = NULL;
75 delete _ptrOutStream;
76 _ptrOutStream = NULL;
77 }
78 }
niklase@google.com470e71d2011-07-07 08:21:25 +000079}
80
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +000081int64_t MediaFileImpl::TimeUntilNextProcess()
niklase@google.com470e71d2011-07-07 08:21:25 +000082{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +020083 LOG(LS_WARNING)
84 << "TimeUntilNextProcess: This method is not used by MediaFile class.";
niklase@google.com470e71d2011-07-07 08:21:25 +000085 return -1;
86}
87
pbosa26ac922016-02-25 04:50:01 -080088void MediaFileImpl::Process()
niklase@google.com470e71d2011-07-07 08:21:25 +000089{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +020090 LOG(LS_WARNING) << "Process: This method is not used by MediaFile class.";
niklase@google.com470e71d2011-07-07 08:21:25 +000091}
92
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +000093int32_t MediaFileImpl::PlayoutAudioData(int8_t* buffer,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000094 size_t& dataLengthInBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +000095{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +020096 LOG(LS_INFO) << "MediaFileImpl::PlayoutData(buffer= "
97 << static_cast<void*>(buffer)
98 << ", bufLen= " << dataLengthInBytes << ")";
niklase@google.com470e71d2011-07-07 08:21:25 +000099
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000100 const size_t bufferLengthInBytes = dataLengthInBytes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000101 dataLengthInBytes = 0;
102
103 if(buffer == NULL || bufferLengthInBytes == 0)
104 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200105 LOG(LS_ERROR) << "Buffer pointer or length is NULL!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000106 return -1;
107 }
108
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000109 int32_t bytesRead = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000110 {
kthelgason6bfe49c2017-03-30 01:14:41 -0700111 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000112
113 if(!_playingActive)
114 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200115 LOG(LS_WARNING) << "Not currently playing!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000116 return -1;
117 }
118
119 if(!_ptrFileUtilityObj)
120 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200121 LOG(LS_ERROR) << "Playing, but no FileUtility object!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000122 StopPlaying();
123 return -1;
124 }
125
126 switch(_fileFormat)
127 {
Minyue Li85a3b6b2017-09-01 14:36:33 +0200128 case kFileFormatPcm48kHzFile:
niklase@google.com470e71d2011-07-07 08:21:25 +0000129 case kFileFormatPcm32kHzFile:
130 case kFileFormatPcm16kHzFile:
131 case kFileFormatPcm8kHzFile:
132 bytesRead = _ptrFileUtilityObj->ReadPCMData(
133 *_ptrInStream,
134 buffer,
135 bufferLengthInBytes);
136 break;
137 case kFileFormatCompressedFile:
138 bytesRead = _ptrFileUtilityObj->ReadCompressedData(
139 *_ptrInStream,
140 buffer,
141 bufferLengthInBytes);
142 break;
143 case kFileFormatWavFile:
144 bytesRead = _ptrFileUtilityObj->ReadWavDataAsMono(
145 *_ptrInStream,
146 buffer,
147 bufferLengthInBytes);
148 break;
149 case kFileFormatPreencodedFile:
150 bytesRead = _ptrFileUtilityObj->ReadPreEncodedData(
151 *_ptrInStream,
152 buffer,
153 bufferLengthInBytes);
154 if(bytesRead > 0)
155 {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000156 dataLengthInBytes = static_cast<size_t>(bytesRead);
niklase@google.com470e71d2011-07-07 08:21:25 +0000157 return 0;
158 }
159 break;
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000160 default:
niklase@google.com470e71d2011-07-07 08:21:25 +0000161 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200162 LOG(LS_ERROR) << "Invalid file format: " << _fileFormat;
niklase@google.com470e71d2011-07-07 08:21:25 +0000163 assert(false);
164 break;
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +0000165 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000166 }
167
168 if( bytesRead > 0)
169 {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000170 dataLengthInBytes = static_cast<size_t>(bytesRead);
niklase@google.com470e71d2011-07-07 08:21:25 +0000171 }
172 }
173 HandlePlayCallbacks(bytesRead);
174 return 0;
175}
176
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000177void MediaFileImpl::HandlePlayCallbacks(int32_t bytesRead)
niklase@google.com470e71d2011-07-07 08:21:25 +0000178{
179 bool playEnded = false;
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000180 uint32_t callbackNotifyMs = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000181
182 if(bytesRead > 0)
183 {
184 // Check if it's time for PlayNotification(..).
185 _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
186 if(_notificationMs)
187 {
188 if(_playoutPositionMs >= _notificationMs)
189 {
190 _notificationMs = 0;
191 callbackNotifyMs = _playoutPositionMs;
192 }
193 }
194 }
195 else
196 {
197 // If no bytes were read assume end of file.
198 StopPlaying();
199 playEnded = true;
200 }
201
202 // Only _callbackCrit may and should be taken when making callbacks.
kthelgason6bfe49c2017-03-30 01:14:41 -0700203 rtc::CritScope lock(&_callbackCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000204 if(_ptrCallback)
205 {
206 if(callbackNotifyMs)
207 {
208 _ptrCallback->PlayNotification(_id, callbackNotifyMs);
209 }
210 if(playEnded)
211 {
212 _ptrCallback->PlayFileEnded(_id);
213 }
214 }
215}
216
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000217int32_t MediaFileImpl::PlayoutStereoData(
218 int8_t* bufferLeft,
219 int8_t* bufferRight,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000220 size_t& dataLengthInBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000221{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200222 LOG(LS_INFO)
223 << "MediaFileImpl::PlayoutStereoData(Left = "
224 << static_cast<void*>(bufferLeft) << ", Right = "
225 << static_cast<void*>(bufferRight) << ", Len= " << dataLengthInBytes
226 << ")";
niklase@google.com470e71d2011-07-07 08:21:25 +0000227
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000228 const size_t bufferLengthInBytes = dataLengthInBytes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000229 dataLengthInBytes = 0;
230
231 if(bufferLeft == NULL || bufferRight == NULL || bufferLengthInBytes == 0)
232 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200233 LOG(LS_ERROR) << "A buffer pointer or the length is NULL!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000234 return -1;
235 }
236
237 bool playEnded = false;
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000238 uint32_t callbackNotifyMs = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000239 {
kthelgason6bfe49c2017-03-30 01:14:41 -0700240 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000241
242 if(!_playingActive || !_isStereo)
243 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200244 LOG(LS_WARNING) << "Not currently playing stereo!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000245 return -1;
246 }
247
248 if(!_ptrFileUtilityObj)
249 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200250 LOG(LS_ERROR)
251 << "Playing stereo, but the FileUtility objects is NULL!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000252 StopPlaying();
253 return -1;
254 }
255
256 // Stereo playout only supported for WAV files.
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000257 int32_t bytesRead = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000258 switch(_fileFormat)
259 {
260 case kFileFormatWavFile:
261 bytesRead = _ptrFileUtilityObj->ReadWavDataAsStereo(
262 *_ptrInStream,
263 bufferLeft,
264 bufferRight,
265 bufferLengthInBytes);
266 break;
267 default:
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200268 LOG(LS_ERROR)
269 << "Trying to read non-WAV as stereo audio (not supported)";
niklase@google.com470e71d2011-07-07 08:21:25 +0000270 break;
271 }
272
273 if(bytesRead > 0)
274 {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000275 dataLengthInBytes = static_cast<size_t>(bytesRead);
niklase@google.com470e71d2011-07-07 08:21:25 +0000276
277 // Check if it's time for PlayNotification(..).
278 _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
279 if(_notificationMs)
280 {
281 if(_playoutPositionMs >= _notificationMs)
282 {
283 _notificationMs = 0;
284 callbackNotifyMs = _playoutPositionMs;
285 }
286 }
287 }
288 else
289 {
290 // If no bytes were read assume end of file.
291 StopPlaying();
292 playEnded = true;
293 }
294 }
295
kthelgason6bfe49c2017-03-30 01:14:41 -0700296 rtc::CritScope lock(&_callbackCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000297 if(_ptrCallback)
298 {
299 if(callbackNotifyMs)
300 {
301 _ptrCallback->PlayNotification(_id, callbackNotifyMs);
302 }
303 if(playEnded)
304 {
305 _ptrCallback->PlayFileEnded(_id);
306 }
307 }
308 return 0;
309}
310
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000311int32_t MediaFileImpl::StartPlayingAudioFile(
leozwang@webrtc.org09e77192012-03-01 18:35:54 +0000312 const char* fileName,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000313 const uint32_t notificationTimeMs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000314 const bool loop,
315 const FileFormats format,
316 const CodecInst* codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000317 const uint32_t startPointMs,
318 const uint32_t stopPointMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000319{
niklase@google.com470e71d2011-07-07 08:21:25 +0000320 if(!ValidFileName(fileName))
321 {
322 return -1;
323 }
324 if(!ValidFileFormat(format,codecInst))
325 {
326 return -1;
327 }
328 if(!ValidFilePositions(startPointMs,stopPointMs))
329 {
330 return -1;
331 }
332
333 // Check that the file will play longer than notificationTimeMs ms.
334 if((startPointMs && stopPointMs && !loop) &&
335 (notificationTimeMs > (stopPointMs - startPointMs)))
336 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200337 LOG(LS_ERROR) << "specified notification time is longer than amount of"
338 << " ms that will be played";
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 return -1;
340 }
341
342 FileWrapper* inputStream = FileWrapper::Create();
343 if(inputStream == NULL)
344 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200345 LOG(LS_INFO) << "Failed to allocate input stream for file " << fileName;
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 return -1;
347 }
348
tommia6219cc2016-06-15 10:30:14 -0700349 if (!inputStream->OpenFile(fileName, true)) {
350 delete inputStream;
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200351 LOG(LS_ERROR) << "Could not open input file " << fileName;
tommia6219cc2016-06-15 10:30:14 -0700352 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 }
354
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000355 if(StartPlayingStream(*inputStream, loop, notificationTimeMs,
356 format, codecInst, startPointMs, stopPointMs) == -1)
niklase@google.com470e71d2011-07-07 08:21:25 +0000357 {
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000358 inputStream->CloseFile();
niklase@google.com470e71d2011-07-07 08:21:25 +0000359 delete inputStream;
360 return -1;
361 }
362
kthelgason6bfe49c2017-03-30 01:14:41 -0700363 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000364 _openFile = true;
365 strncpy(_fileName, fileName, sizeof(_fileName));
366 _fileName[sizeof(_fileName) - 1] = '\0';
367 return 0;
368}
369
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000370int32_t MediaFileImpl::StartPlayingAudioStream(
niklase@google.com470e71d2011-07-07 08:21:25 +0000371 InStream& stream,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000372 const uint32_t notificationTimeMs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000373 const FileFormats format,
374 const CodecInst* codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000375 const uint32_t startPointMs,
376 const uint32_t stopPointMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000377{
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000378 return StartPlayingStream(stream, false, notificationTimeMs, format,
niklase@google.com470e71d2011-07-07 08:21:25 +0000379 codecInst, startPointMs, stopPointMs);
380}
381
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000382int32_t MediaFileImpl::StartPlayingStream(
niklase@google.com470e71d2011-07-07 08:21:25 +0000383 InStream& stream,
niklase@google.com470e71d2011-07-07 08:21:25 +0000384 bool loop,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000385 const uint32_t notificationTimeMs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000386 const FileFormats format,
387 const CodecInst* codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000388 const uint32_t startPointMs,
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000389 const uint32_t stopPointMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000390{
niklase@google.com470e71d2011-07-07 08:21:25 +0000391 if(!ValidFileFormat(format,codecInst))
392 {
393 return -1;
394 }
395
396 if(!ValidFilePositions(startPointMs,stopPointMs))
397 {
398 return -1;
399 }
400
kthelgason6bfe49c2017-03-30 01:14:41 -0700401 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000402 if(_playingActive || _recordingActive)
403 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200404 LOG(LS_ERROR)
405 << "StartPlaying called, but already playing or recording file "
406 << ((_fileName[0] == '\0') ? "(name not set)" : _fileName);
niklase@google.com470e71d2011-07-07 08:21:25 +0000407 return -1;
408 }
409
410 if(_ptrFileUtilityObj != NULL)
411 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200412 LOG(LS_ERROR)
413 << "StartPlaying called, but FileUtilityObj already exists!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000414 StopPlaying();
415 return -1;
416 }
417
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200418 _ptrFileUtilityObj = new ModuleFileUtility();
niklase@google.com470e71d2011-07-07 08:21:25 +0000419 if(_ptrFileUtilityObj == NULL)
420 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200421 LOG(LS_INFO) << "Failed to create FileUtilityObj!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000422 return -1;
423 }
424
425 switch(format)
426 {
427 case kFileFormatWavFile:
428 {
429 if(_ptrFileUtilityObj->InitWavReading(stream, startPointMs,
430 stopPointMs) == -1)
431 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200432 LOG(LS_ERROR) << "Not a valid WAV file!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000433 StopPlaying();
434 return -1;
435 }
436 _fileFormat = kFileFormatWavFile;
437 break;
438 }
439 case kFileFormatCompressedFile:
440 {
441 if(_ptrFileUtilityObj->InitCompressedReading(stream, startPointMs,
442 stopPointMs) == -1)
443 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200444 LOG(LS_ERROR) << "Not a valid Compressed file!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000445 StopPlaying();
446 return -1;
447 }
448 _fileFormat = kFileFormatCompressedFile;
449 break;
450 }
451 case kFileFormatPcm8kHzFile:
452 case kFileFormatPcm16kHzFile:
453 case kFileFormatPcm32kHzFile:
Minyue Li85a3b6b2017-09-01 14:36:33 +0200454 case kFileFormatPcm48kHzFile:
niklase@google.com470e71d2011-07-07 08:21:25 +0000455 {
henrike@webrtc.org26085e12012-02-27 21:50:40 +0000456 // ValidFileFormat() called in the beginneing of this function
457 // prevents codecInst from being NULL here.
458 assert(codecInst != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000459 if(!ValidFrequency(codecInst->plfreq) ||
460 _ptrFileUtilityObj->InitPCMReading(stream, startPointMs,
461 stopPointMs,
462 codecInst->plfreq) == -1)
463 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200464 LOG(LS_ERROR) << "Not a valid raw 8 or 16 KHz PCM file!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000465 StopPlaying();
466 return -1;
467 }
468
469 _fileFormat = format;
470 break;
471 }
472 case kFileFormatPreencodedFile:
473 {
henrike@webrtc.org26085e12012-02-27 21:50:40 +0000474 // ValidFileFormat() called in the beginneing of this function
475 // prevents codecInst from being NULL here.
476 assert(codecInst != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000477 if(_ptrFileUtilityObj->InitPreEncodedReading(stream, *codecInst) ==
478 -1)
479 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200480 LOG(LS_ERROR) << "Not a valid PreEncoded file!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000481 StopPlaying();
482 return -1;
483 }
484
485 _fileFormat = kFileFormatPreencodedFile;
486 break;
487 }
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000488 default:
niklase@google.com470e71d2011-07-07 08:21:25 +0000489 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200490 LOG(LS_ERROR) << "Invalid file format: " << format;
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +0000491 assert(false);
492 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000493 }
494 }
495 if(_ptrFileUtilityObj->codec_info(codec_info_) == -1)
496 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200497 LOG(LS_ERROR) << "Failed to retrieve codec info!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000498 StopPlaying();
499 return -1;
500 }
501
502 _isStereo = (codec_info_.channels == 2);
503 if(_isStereo && (_fileFormat != kFileFormatWavFile))
504 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200505 LOG(LS_WARNING) << "Stereo is only allowed for WAV files";
niklase@google.com470e71d2011-07-07 08:21:25 +0000506 StopPlaying();
507 return -1;
508 }
509 _playingActive = true;
510 _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
511 _ptrInStream = &stream;
512 _notificationMs = notificationTimeMs;
513
514 return 0;
515}
516
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000517int32_t MediaFileImpl::StopPlaying()
niklase@google.com470e71d2011-07-07 08:21:25 +0000518{
niklase@google.com470e71d2011-07-07 08:21:25 +0000519
kthelgason6bfe49c2017-03-30 01:14:41 -0700520 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000521 _isStereo = false;
522 if(_ptrFileUtilityObj)
523 {
524 delete _ptrFileUtilityObj;
525 _ptrFileUtilityObj = NULL;
526 }
527 if(_ptrInStream)
528 {
529 // If MediaFileImpl opened the InStream it must be reclaimed here.
530 if(_openFile)
531 {
532 delete _ptrInStream;
533 _openFile = false;
534 }
535 _ptrInStream = NULL;
536 }
537
538 codec_info_.pltype = 0;
539 codec_info_.plname[0] = '\0';
540
541 if(!_playingActive)
542 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200543 LOG(LS_WARNING) << "playing is not active!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000544 return -1;
545 }
546
547 _playingActive = false;
548 return 0;
549}
550
551bool MediaFileImpl::IsPlaying()
552{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200553 LOG(LS_VERBOSE) << "MediaFileImpl::IsPlaying()";
kthelgason6bfe49c2017-03-30 01:14:41 -0700554 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000555 return _playingActive;
556}
557
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000558int32_t MediaFileImpl::IncomingAudioData(
559 const int8_t* buffer,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000560 const size_t bufferLengthInBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000561{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200562 LOG(LS_INFO) << "MediaFile::IncomingData(buffer= "
563 << static_cast<const void*>(buffer) << ", bufLen= "
564 << bufferLengthInBytes << ")";
niklase@google.com470e71d2011-07-07 08:21:25 +0000565
566 if(buffer == NULL || bufferLengthInBytes == 0)
567 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200568 LOG(LS_ERROR) << "Buffer pointer or length is NULL!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000569 return -1;
570 }
571
572 bool recordingEnded = false;
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000573 uint32_t callbackNotifyMs = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000574 {
kthelgason6bfe49c2017-03-30 01:14:41 -0700575 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000576
577 if(!_recordingActive)
578 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200579 LOG(LS_WARNING) << "Not currently recording!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000580 return -1;
581 }
582 if(_ptrOutStream == NULL)
583 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200584 LOG(LS_ERROR) << "Recording is active, but output stream is NULL!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000585 assert(false);
586 return -1;
587 }
588
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000589 int32_t bytesWritten = 0;
590 uint32_t samplesWritten = codec_info_.pacsize;
niklase@google.com470e71d2011-07-07 08:21:25 +0000591 if(_ptrFileUtilityObj)
592 {
593 switch(_fileFormat)
594 {
595 case kFileFormatPcm8kHzFile:
596 case kFileFormatPcm16kHzFile:
597 case kFileFormatPcm32kHzFile:
Minyue Li85a3b6b2017-09-01 14:36:33 +0200598 case kFileFormatPcm48kHzFile:
niklase@google.com470e71d2011-07-07 08:21:25 +0000599 bytesWritten = _ptrFileUtilityObj->WritePCMData(
600 *_ptrOutStream,
601 buffer,
602 bufferLengthInBytes);
603
604 // Sample size is 2 bytes.
605 if(bytesWritten > 0)
606 {
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000607 samplesWritten = bytesWritten/sizeof(int16_t);
niklase@google.com470e71d2011-07-07 08:21:25 +0000608 }
609 break;
610 case kFileFormatCompressedFile:
611 bytesWritten = _ptrFileUtilityObj->WriteCompressedData(
612 *_ptrOutStream, buffer, bufferLengthInBytes);
613 break;
614 case kFileFormatWavFile:
615 bytesWritten = _ptrFileUtilityObj->WriteWavData(
616 *_ptrOutStream,
617 buffer,
618 bufferLengthInBytes);
619 if(bytesWritten > 0 && STR_NCASE_CMP(codec_info_.plname,
620 "L16", 4) == 0)
621 {
622 // Sample size is 2 bytes.
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000623 samplesWritten = bytesWritten/sizeof(int16_t);
niklase@google.com470e71d2011-07-07 08:21:25 +0000624 }
625 break;
626 case kFileFormatPreencodedFile:
627 bytesWritten = _ptrFileUtilityObj->WritePreEncodedData(
628 *_ptrOutStream, buffer, bufferLengthInBytes);
629 break;
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000630 default:
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200631 LOG(LS_ERROR) << "Invalid file format: " << _fileFormat;
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +0000632 assert(false);
niklase@google.com470e71d2011-07-07 08:21:25 +0000633 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000634 }
635 } else {
636 // TODO (hellner): quick look at the code makes me think that this
637 // code is never executed. Remove?
638 if(_ptrOutStream)
639 {
640 if(_ptrOutStream->Write(buffer, bufferLengthInBytes))
641 {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000642 bytesWritten = static_cast<int32_t>(bufferLengthInBytes);
niklase@google.com470e71d2011-07-07 08:21:25 +0000643 }
644 }
645 }
646
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000647 _recordDurationMs += samplesWritten / (codec_info_.plfreq / 1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000648
649 // Check if it's time for RecordNotification(..).
650 if(_notificationMs)
651 {
652 if(_recordDurationMs >= _notificationMs)
653 {
654 _notificationMs = 0;
655 callbackNotifyMs = _recordDurationMs;
656 }
657 }
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000658 if(bytesWritten < (int32_t)bufferLengthInBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000659 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200660 LOG(LS_WARNING) << "Failed to write all requested bytes!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000661 StopRecording();
662 recordingEnded = true;
663 }
664 }
665
666 // Only _callbackCrit may and should be taken when making callbacks.
kthelgason6bfe49c2017-03-30 01:14:41 -0700667 rtc::CritScope lock(&_callbackCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000668 if(_ptrCallback)
669 {
670 if(callbackNotifyMs)
671 {
672 _ptrCallback->RecordNotification(_id, callbackNotifyMs);
673 }
674 if(recordingEnded)
675 {
676 _ptrCallback->RecordFileEnded(_id);
677 return -1;
678 }
679 }
680 return 0;
681}
682
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000683int32_t MediaFileImpl::StartRecordingAudioFile(
leozwang@webrtc.org09e77192012-03-01 18:35:54 +0000684 const char* fileName,
niklase@google.com470e71d2011-07-07 08:21:25 +0000685 const FileFormats format,
686 const CodecInst& codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000687 const uint32_t notificationTimeMs,
688 const uint32_t maxSizeBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000689{
niklase@google.com470e71d2011-07-07 08:21:25 +0000690 if(!ValidFileName(fileName))
691 {
692 return -1;
693 }
694 if(!ValidFileFormat(format,&codecInst))
695 {
696 return -1;
697 }
698
699 FileWrapper* outputStream = FileWrapper::Create();
700 if(outputStream == NULL)
701 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200702 LOG(LS_INFO) << "Failed to allocate memory for output stream";
niklase@google.com470e71d2011-07-07 08:21:25 +0000703 return -1;
704 }
705
tommia6219cc2016-06-15 10:30:14 -0700706 if (!outputStream->OpenFile(fileName, false)) {
707 delete outputStream;
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200708 LOG(LS_ERROR) << "Could not open output file '" << fileName
709 << "' for writing!";
tommia6219cc2016-06-15 10:30:14 -0700710 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000711 }
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000712
niklase@google.com470e71d2011-07-07 08:21:25 +0000713 if(maxSizeBytes)
714 {
715 outputStream->SetMaxFileSize(maxSizeBytes);
716 }
717
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000718 if(StartRecordingAudioStream(*outputStream, format, codecInst,
719 notificationTimeMs) == -1)
niklase@google.com470e71d2011-07-07 08:21:25 +0000720 {
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000721 outputStream->CloseFile();
niklase@google.com470e71d2011-07-07 08:21:25 +0000722 delete outputStream;
723 return -1;
724 }
725
kthelgason6bfe49c2017-03-30 01:14:41 -0700726 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000727 _openFile = true;
728 strncpy(_fileName, fileName, sizeof(_fileName));
729 _fileName[sizeof(_fileName) - 1] = '\0';
730 return 0;
731}
732
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000733int32_t MediaFileImpl::StartRecordingAudioStream(
niklase@google.com470e71d2011-07-07 08:21:25 +0000734 OutStream& stream,
735 const FileFormats format,
736 const CodecInst& codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000737 const uint32_t notificationTimeMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000738{
niklase@google.com470e71d2011-07-07 08:21:25 +0000739 // Check codec info
740 if(!ValidFileFormat(format,&codecInst))
741 {
742 return -1;
743 }
744
kthelgason6bfe49c2017-03-30 01:14:41 -0700745 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000746 if(_recordingActive || _playingActive)
747 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200748 LOG(LS_ERROR)
749 << "StartRecording called, but already recording or playing file "
750 << _fileName << "!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000751 return -1;
752 }
753
754 if(_ptrFileUtilityObj != NULL)
755 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200756 LOG(LS_ERROR)
757 << "StartRecording called, but fileUtilityObj already exists!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000758 StopRecording();
759 return -1;
760 }
761
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200762 _ptrFileUtilityObj = new ModuleFileUtility();
niklase@google.com470e71d2011-07-07 08:21:25 +0000763 if(_ptrFileUtilityObj == NULL)
764 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200765 LOG(LS_INFO) << "Cannot allocate fileUtilityObj!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000766 return -1;
767 }
768
769 CodecInst tmpAudioCodec;
770 memcpy(&tmpAudioCodec, &codecInst, sizeof(CodecInst));
771 switch(format)
772 {
773 case kFileFormatWavFile:
774 {
775 if(_ptrFileUtilityObj->InitWavWriting(stream, codecInst) == -1)
776 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200777 LOG(LS_ERROR) << "Failed to initialize WAV file!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000778 delete _ptrFileUtilityObj;
779 _ptrFileUtilityObj = NULL;
780 return -1;
781 }
782 _fileFormat = kFileFormatWavFile;
783 break;
784 }
785 case kFileFormatCompressedFile:
786 {
787 // Write compression codec name at beginning of file
788 if(_ptrFileUtilityObj->InitCompressedWriting(stream, codecInst) ==
789 -1)
790 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200791 LOG(LS_ERROR) << "Failed to initialize Compressed file!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000792 delete _ptrFileUtilityObj;
793 _ptrFileUtilityObj = NULL;
794 return -1;
795 }
796 _fileFormat = kFileFormatCompressedFile;
797 break;
798 }
799 case kFileFormatPcm8kHzFile:
800 case kFileFormatPcm16kHzFile:
Minyue Li85a3b6b2017-09-01 14:36:33 +0200801 case kFileFormatPcm32kHzFile:
802 case kFileFormatPcm48kHzFile:
niklase@google.com470e71d2011-07-07 08:21:25 +0000803 {
804 if(!ValidFrequency(codecInst.plfreq) ||
805 _ptrFileUtilityObj->InitPCMWriting(stream, codecInst.plfreq) ==
806 -1)
807 {
Minyue Li85a3b6b2017-09-01 14:36:33 +0200808 LOG(LS_ERROR) << "Failed to initialize PCM file!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000809 delete _ptrFileUtilityObj;
810 _ptrFileUtilityObj = NULL;
811 return -1;
812 }
813 _fileFormat = format;
814 break;
815 }
816 case kFileFormatPreencodedFile:
817 {
818 if(_ptrFileUtilityObj->InitPreEncodedWriting(stream, codecInst) ==
819 -1)
820 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200821 LOG(LS_ERROR) << "Failed to initialize Pre-Encoded file!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000822 delete _ptrFileUtilityObj;
823 _ptrFileUtilityObj = NULL;
824 return -1;
825 }
826
827 _fileFormat = kFileFormatPreencodedFile;
828 break;
829 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000830 default:
831 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200832 LOG(LS_ERROR) << "Invalid file format " << format << " specified!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000833 delete _ptrFileUtilityObj;
834 _ptrFileUtilityObj = NULL;
835 return -1;
836 }
837 }
838 _isStereo = (tmpAudioCodec.channels == 2);
839 if(_isStereo)
840 {
841 if(_fileFormat != kFileFormatWavFile)
842 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200843 LOG(LS_WARNING) << "Stereo is only allowed for WAV files";
niklase@google.com470e71d2011-07-07 08:21:25 +0000844 StopRecording();
845 return -1;
846 }
niklas.enbom@webrtc.org87885e82012-02-07 14:48:59 +0000847 if((STR_NCASE_CMP(tmpAudioCodec.plname, "L16", 4) != 0) &&
848 (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMU", 5) != 0) &&
849 (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMA", 5) != 0))
niklase@google.com470e71d2011-07-07 08:21:25 +0000850 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200851 LOG(LS_WARNING)
852 << "Stereo is only allowed for codec PCMU, PCMA and L16 ";
niklase@google.com470e71d2011-07-07 08:21:25 +0000853 StopRecording();
854 return -1;
855 }
856 }
857 memcpy(&codec_info_, &tmpAudioCodec, sizeof(CodecInst));
858 _recordingActive = true;
859 _ptrOutStream = &stream;
860 _notificationMs = notificationTimeMs;
861 _recordDurationMs = 0;
862 return 0;
863}
864
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000865int32_t MediaFileImpl::StopRecording()
niklase@google.com470e71d2011-07-07 08:21:25 +0000866{
niklase@google.com470e71d2011-07-07 08:21:25 +0000867
kthelgason6bfe49c2017-03-30 01:14:41 -0700868 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000869 if(!_recordingActive)
870 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200871 LOG(LS_WARNING) << "recording is not active!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000872 return -1;
873 }
874
875 _isStereo = false;
876
877 if(_ptrFileUtilityObj != NULL)
878 {
879 // Both AVI and WAV header has to be updated before closing the stream
880 // because they contain size information.
881 if((_fileFormat == kFileFormatWavFile) &&
882 (_ptrOutStream != NULL))
883 {
884 _ptrFileUtilityObj->UpdateWavHeader(*_ptrOutStream);
885 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000886 delete _ptrFileUtilityObj;
887 _ptrFileUtilityObj = NULL;
888 }
889
890 if(_ptrOutStream != NULL)
891 {
892 // If MediaFileImpl opened the OutStream it must be reclaimed here.
893 if(_openFile)
894 {
895 delete _ptrOutStream;
896 _openFile = false;
897 }
898 _ptrOutStream = NULL;
899 }
900
901 _recordingActive = false;
902 codec_info_.pltype = 0;
903 codec_info_.plname[0] = '\0';
904
905 return 0;
906}
907
908bool MediaFileImpl::IsRecording()
909{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200910 LOG(LS_VERBOSE) << "MediaFileImpl::IsRecording()";
kthelgason6bfe49c2017-03-30 01:14:41 -0700911 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000912 return _recordingActive;
913}
914
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000915int32_t MediaFileImpl::RecordDurationMs(uint32_t& durationMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000916{
niklase@google.com470e71d2011-07-07 08:21:25 +0000917
kthelgason6bfe49c2017-03-30 01:14:41 -0700918 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000919 if(!_recordingActive)
920 {
921 durationMs = 0;
922 return -1;
923 }
924 durationMs = _recordDurationMs;
925 return 0;
926}
927
928bool MediaFileImpl::IsStereo()
929{
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200930 LOG(LS_VERBOSE) << "MediaFileImpl::IsStereo()";
kthelgason6bfe49c2017-03-30 01:14:41 -0700931 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000932 return _isStereo;
933}
934
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000935int32_t MediaFileImpl::SetModuleFileCallback(FileCallback* callback)
niklase@google.com470e71d2011-07-07 08:21:25 +0000936{
niklase@google.com470e71d2011-07-07 08:21:25 +0000937
kthelgason6bfe49c2017-03-30 01:14:41 -0700938 rtc::CritScope lock(&_callbackCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000939
940 _ptrCallback = callback;
941 return 0;
942}
943
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000944int32_t MediaFileImpl::FileDurationMs(const char* fileName,
945 uint32_t& durationMs,
946 const FileFormats format,
947 const uint32_t freqInHz)
niklase@google.com470e71d2011-07-07 08:21:25 +0000948{
niklase@google.com470e71d2011-07-07 08:21:25 +0000949
950 if(!ValidFileName(fileName))
951 {
952 return -1;
953 }
954 if(!ValidFrequency(freqInHz))
955 {
956 return -1;
957 }
958
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200959 ModuleFileUtility* utilityObj = new ModuleFileUtility();
niklase@google.com470e71d2011-07-07 08:21:25 +0000960 if(utilityObj == NULL)
961 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200962 LOG(LS_ERROR) << "failed to allocate utility object!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000963 return -1;
964 }
965
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000966 const int32_t duration = utilityObj->FileDurationMs(fileName, format,
967 freqInHz);
niklase@google.com470e71d2011-07-07 08:21:25 +0000968 delete utilityObj;
969 if(duration == -1)
970 {
971 durationMs = 0;
972 return -1;
973 }
974
975 durationMs = duration;
976 return 0;
977}
978
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000979int32_t MediaFileImpl::PlayoutPositionMs(uint32_t& positionMs) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000980{
kthelgason6bfe49c2017-03-30 01:14:41 -0700981 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000982 if(!_playingActive)
983 {
984 positionMs = 0;
985 return -1;
986 }
987 positionMs = _playoutPositionMs;
988 return 0;
989}
990
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000991int32_t MediaFileImpl::codec_info(CodecInst& codecInst) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000992{
kthelgason6bfe49c2017-03-30 01:14:41 -0700993 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000994 if(!_playingActive && !_recordingActive)
995 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +0200996 LOG(LS_ERROR) << "Neither playout nor recording has been initialized!";
niklase@google.com470e71d2011-07-07 08:21:25 +0000997 return -1;
998 }
999 if (codec_info_.pltype == 0 && codec_info_.plname[0] == '\0')
1000 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +02001001 LOG(LS_ERROR) << "The CodecInst for "
1002 << (_playingActive ? "Playback" : "Recording")
1003 << " is unknown!";
niklase@google.com470e71d2011-07-07 08:21:25 +00001004 return -1;
1005 }
1006 memcpy(&codecInst,&codec_info_,sizeof(CodecInst));
1007 return 0;
1008}
1009
niklase@google.com470e71d2011-07-07 08:21:25 +00001010bool MediaFileImpl::ValidFileFormat(const FileFormats format,
1011 const CodecInst* codecInst)
1012{
1013 if(codecInst == NULL)
1014 {
1015 if(format == kFileFormatPreencodedFile ||
1016 format == kFileFormatPcm8kHzFile ||
1017 format == kFileFormatPcm16kHzFile ||
Minyue Li85a3b6b2017-09-01 14:36:33 +02001018 format == kFileFormatPcm32kHzFile ||
1019 format == kFileFormatPcm48kHzFile)
niklase@google.com470e71d2011-07-07 08:21:25 +00001020 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +02001021 LOG(LS_ERROR) << "Codec info required for file format specified!";
niklase@google.com470e71d2011-07-07 08:21:25 +00001022 return false;
1023 }
1024 }
1025 return true;
1026}
1027
leozwang@webrtc.org09e77192012-03-01 18:35:54 +00001028bool MediaFileImpl::ValidFileName(const char* fileName)
niklase@google.com470e71d2011-07-07 08:21:25 +00001029{
1030 if((fileName == NULL) ||(fileName[0] == '\0'))
1031 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +02001032 LOG(LS_ERROR) << "FileName not specified!";
niklase@google.com470e71d2011-07-07 08:21:25 +00001033 return false;
1034 }
1035 return true;
1036}
1037
1038
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +00001039bool MediaFileImpl::ValidFilePositions(const uint32_t startPointMs,
1040 const uint32_t stopPointMs)
niklase@google.com470e71d2011-07-07 08:21:25 +00001041{
1042 if(startPointMs == 0 && stopPointMs == 0) // Default values
1043 {
1044 return true;
1045 }
1046 if(stopPointMs &&(startPointMs >= stopPointMs))
1047 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +02001048 LOG(LS_ERROR) << "startPointMs must be less than stopPointMs!";
niklase@google.com470e71d2011-07-07 08:21:25 +00001049 return false;
1050 }
1051 if(stopPointMs &&((stopPointMs - startPointMs) < 20))
1052 {
Sam Zackrisson45ca37c2017-08-22 13:44:09 +02001053 LOG(LS_ERROR) << "minimum play duration for files is 20 ms!";
niklase@google.com470e71d2011-07-07 08:21:25 +00001054 return false;
1055 }
1056 return true;
1057}
1058
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +00001059bool MediaFileImpl::ValidFrequency(const uint32_t frequency)
niklase@google.com470e71d2011-07-07 08:21:25 +00001060{
Minyue Li85a3b6b2017-09-01 14:36:33 +02001061 if((frequency == 8000) || (frequency == 16000)|| (frequency == 32000) ||
1062 (frequency == 48000))
niklase@google.com470e71d2011-07-07 08:21:25 +00001063 {
1064 return true;
1065 }
Minyue Li85a3b6b2017-09-01 14:36:33 +02001066 LOG(LS_ERROR) << "Frequency should be 8000, 16000, 32000, or 48000 (Hz)";
niklase@google.com470e71d2011-07-07 08:21:25 +00001067 return false;
1068}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001069} // namespace webrtc