blob: 88310a5ef6d0ed01f1bf013325939a92cf4575de [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
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000013#include "webrtc/base/format_macros.h"
Henrik Kjellander0b9e29c2015-11-16 11:12:24 +010014#include "webrtc/modules/media_file/media_file_impl.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010015#include "webrtc/system_wrappers/include/file_wrapper.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010016#include "webrtc/system_wrappers/include/trace.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{
46 WEBRTC_TRACE(kTraceMemory, kTraceFile, id, "Created");
47
48 codec_info_.plname[0] = '\0';
49 _fileName[0] = '\0';
50}
51
52
53MediaFileImpl::~MediaFileImpl()
54{
55 WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, "~MediaFileImpl()");
56 {
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{
83 WEBRTC_TRACE(
84 kTraceWarning,
85 kTraceFile,
86 _id,
87 "TimeUntilNextProcess: This method is not used by MediaFile class.");
88 return -1;
89}
90
pbosa26ac922016-02-25 04:50:01 -080091void MediaFileImpl::Process()
niklase@google.com470e71d2011-07-07 08:21:25 +000092{
93 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
94 "Process: This method is not used by MediaFile class.");
niklase@google.com470e71d2011-07-07 08:21:25 +000095}
96
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +000097int32_t MediaFileImpl::PlayoutAudioData(int8_t* buffer,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000098 size_t& dataLengthInBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +000099{
niklase@google.com470e71d2011-07-07 08:21:25 +0000100 WEBRTC_TRACE(kTraceStream, kTraceFile, _id,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000101 "MediaFileImpl::PlayoutData(buffer= 0x%x, bufLen= %" PRIuS ")",
niklase@google.com470e71d2011-07-07 08:21:25 +0000102 buffer, dataLengthInBytes);
103
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000104 const size_t bufferLengthInBytes = dataLengthInBytes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000105 dataLengthInBytes = 0;
106
107 if(buffer == NULL || bufferLengthInBytes == 0)
108 {
109 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
110 "Buffer pointer or length is NULL!");
111 return -1;
112 }
113
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000114 int32_t bytesRead = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000115 {
kthelgason6bfe49c2017-03-30 01:14:41 -0700116 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000117
118 if(!_playingActive)
119 {
120 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
121 "Not currently playing!");
122 return -1;
123 }
124
125 if(!_ptrFileUtilityObj)
126 {
127 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
128 "Playing, but no FileUtility object!");
129 StopPlaying();
130 return -1;
131 }
132
133 switch(_fileFormat)
134 {
minyue5f937092017-03-31 12:27:09 -0700135 case kFileFormatPcm48kHzFile:
niklase@google.com470e71d2011-07-07 08:21:25 +0000136 case kFileFormatPcm32kHzFile:
137 case kFileFormatPcm16kHzFile:
138 case kFileFormatPcm8kHzFile:
139 bytesRead = _ptrFileUtilityObj->ReadPCMData(
140 *_ptrInStream,
141 buffer,
142 bufferLengthInBytes);
143 break;
144 case kFileFormatCompressedFile:
145 bytesRead = _ptrFileUtilityObj->ReadCompressedData(
146 *_ptrInStream,
147 buffer,
148 bufferLengthInBytes);
149 break;
150 case kFileFormatWavFile:
151 bytesRead = _ptrFileUtilityObj->ReadWavDataAsMono(
152 *_ptrInStream,
153 buffer,
154 bufferLengthInBytes);
155 break;
156 case kFileFormatPreencodedFile:
157 bytesRead = _ptrFileUtilityObj->ReadPreEncodedData(
158 *_ptrInStream,
159 buffer,
160 bufferLengthInBytes);
161 if(bytesRead > 0)
162 {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000163 dataLengthInBytes = static_cast<size_t>(bytesRead);
niklase@google.com470e71d2011-07-07 08:21:25 +0000164 return 0;
165 }
166 break;
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000167 default:
niklase@google.com470e71d2011-07-07 08:21:25 +0000168 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000169 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000170 "Invalid file format: %d", _fileFormat);
niklase@google.com470e71d2011-07-07 08:21:25 +0000171 assert(false);
172 break;
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +0000173 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000174 }
175
176 if( bytesRead > 0)
177 {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000178 dataLengthInBytes = static_cast<size_t>(bytesRead);
niklase@google.com470e71d2011-07-07 08:21:25 +0000179 }
180 }
181 HandlePlayCallbacks(bytesRead);
182 return 0;
183}
184
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000185void MediaFileImpl::HandlePlayCallbacks(int32_t bytesRead)
niklase@google.com470e71d2011-07-07 08:21:25 +0000186{
187 bool playEnded = false;
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000188 uint32_t callbackNotifyMs = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000189
190 if(bytesRead > 0)
191 {
192 // Check if it's time for PlayNotification(..).
193 _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
194 if(_notificationMs)
195 {
196 if(_playoutPositionMs >= _notificationMs)
197 {
198 _notificationMs = 0;
199 callbackNotifyMs = _playoutPositionMs;
200 }
201 }
202 }
203 else
204 {
205 // If no bytes were read assume end of file.
206 StopPlaying();
207 playEnded = true;
208 }
209
210 // Only _callbackCrit may and should be taken when making callbacks.
kthelgason6bfe49c2017-03-30 01:14:41 -0700211 rtc::CritScope lock(&_callbackCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000212 if(_ptrCallback)
213 {
214 if(callbackNotifyMs)
215 {
216 _ptrCallback->PlayNotification(_id, callbackNotifyMs);
217 }
218 if(playEnded)
219 {
220 _ptrCallback->PlayFileEnded(_id);
221 }
222 }
223}
224
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000225int32_t MediaFileImpl::PlayoutStereoData(
226 int8_t* bufferLeft,
227 int8_t* bufferRight,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000228 size_t& dataLengthInBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000229{
230 WEBRTC_TRACE(kTraceStream, kTraceFile, _id,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000231 "MediaFileImpl::PlayoutStereoData(Left = 0x%x, Right = 0x%x,"
232 " Len= %" PRIuS ")",
niklase@google.com470e71d2011-07-07 08:21:25 +0000233 bufferLeft,
234 bufferRight,
235 dataLengthInBytes);
236
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000237 const size_t bufferLengthInBytes = dataLengthInBytes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000238 dataLengthInBytes = 0;
239
240 if(bufferLeft == NULL || bufferRight == NULL || bufferLengthInBytes == 0)
241 {
242 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
243 "A buffer pointer or the length is NULL!");
244 return -1;
245 }
246
247 bool playEnded = false;
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000248 uint32_t callbackNotifyMs = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000249 {
kthelgason6bfe49c2017-03-30 01:14:41 -0700250 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000251
252 if(!_playingActive || !_isStereo)
253 {
254 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
255 "Not currently playing stereo!");
256 return -1;
257 }
258
259 if(!_ptrFileUtilityObj)
260 {
261 WEBRTC_TRACE(
262 kTraceError,
263 kTraceFile,
264 _id,
265 "Playing stereo, but the FileUtility objects is NULL!");
266 StopPlaying();
267 return -1;
268 }
269
270 // Stereo playout only supported for WAV files.
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000271 int32_t bytesRead = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000272 switch(_fileFormat)
273 {
274 case kFileFormatWavFile:
275 bytesRead = _ptrFileUtilityObj->ReadWavDataAsStereo(
276 *_ptrInStream,
277 bufferLeft,
278 bufferRight,
279 bufferLengthInBytes);
280 break;
281 default:
282 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
283 "Trying to read non-WAV as stereo audio\
284 (not supported)");
285 break;
286 }
287
288 if(bytesRead > 0)
289 {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000290 dataLengthInBytes = static_cast<size_t>(bytesRead);
niklase@google.com470e71d2011-07-07 08:21:25 +0000291
292 // Check if it's time for PlayNotification(..).
293 _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
294 if(_notificationMs)
295 {
296 if(_playoutPositionMs >= _notificationMs)
297 {
298 _notificationMs = 0;
299 callbackNotifyMs = _playoutPositionMs;
300 }
301 }
302 }
303 else
304 {
305 // If no bytes were read assume end of file.
306 StopPlaying();
307 playEnded = true;
308 }
309 }
310
kthelgason6bfe49c2017-03-30 01:14:41 -0700311 rtc::CritScope lock(&_callbackCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000312 if(_ptrCallback)
313 {
314 if(callbackNotifyMs)
315 {
316 _ptrCallback->PlayNotification(_id, callbackNotifyMs);
317 }
318 if(playEnded)
319 {
320 _ptrCallback->PlayFileEnded(_id);
321 }
322 }
323 return 0;
324}
325
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000326int32_t MediaFileImpl::StartPlayingAudioFile(
leozwang@webrtc.org09e77192012-03-01 18:35:54 +0000327 const char* fileName,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000328 const uint32_t notificationTimeMs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000329 const bool loop,
330 const FileFormats format,
331 const CodecInst* codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000332 const uint32_t startPointMs,
333 const uint32_t stopPointMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000334{
niklase@google.com470e71d2011-07-07 08:21:25 +0000335 if(!ValidFileName(fileName))
336 {
337 return -1;
338 }
339 if(!ValidFileFormat(format,codecInst))
340 {
341 return -1;
342 }
343 if(!ValidFilePositions(startPointMs,stopPointMs))
344 {
345 return -1;
346 }
347
348 // Check that the file will play longer than notificationTimeMs ms.
349 if((startPointMs && stopPointMs && !loop) &&
350 (notificationTimeMs > (stopPointMs - startPointMs)))
351 {
352 WEBRTC_TRACE(
353 kTraceError,
354 kTraceFile,
355 _id,
356 "specified notification time is longer than amount of ms that will\
357 be played");
358 return -1;
359 }
360
361 FileWrapper* inputStream = FileWrapper::Create();
362 if(inputStream == NULL)
363 {
364 WEBRTC_TRACE(kTraceMemory, kTraceFile, _id,
365 "Failed to allocate input stream for file %s", fileName);
366 return -1;
367 }
368
tommia6219cc2016-06-15 10:30:14 -0700369 if (!inputStream->OpenFile(fileName, true)) {
370 delete inputStream;
371 WEBRTC_TRACE(kTraceError, kTraceFile, _id, "Could not open input file %s",
372 fileName);
373 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000374 }
375
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000376 if(StartPlayingStream(*inputStream, loop, notificationTimeMs,
377 format, codecInst, startPointMs, stopPointMs) == -1)
niklase@google.com470e71d2011-07-07 08:21:25 +0000378 {
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000379 inputStream->CloseFile();
niklase@google.com470e71d2011-07-07 08:21:25 +0000380 delete inputStream;
381 return -1;
382 }
383
kthelgason6bfe49c2017-03-30 01:14:41 -0700384 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000385 _openFile = true;
386 strncpy(_fileName, fileName, sizeof(_fileName));
387 _fileName[sizeof(_fileName) - 1] = '\0';
388 return 0;
389}
390
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000391int32_t MediaFileImpl::StartPlayingAudioStream(
niklase@google.com470e71d2011-07-07 08:21:25 +0000392 InStream& stream,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000393 const uint32_t notificationTimeMs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000394 const FileFormats format,
395 const CodecInst* codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000396 const uint32_t startPointMs,
397 const uint32_t stopPointMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000398{
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000399 return StartPlayingStream(stream, false, notificationTimeMs, format,
niklase@google.com470e71d2011-07-07 08:21:25 +0000400 codecInst, startPointMs, stopPointMs);
401}
402
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000403int32_t MediaFileImpl::StartPlayingStream(
niklase@google.com470e71d2011-07-07 08:21:25 +0000404 InStream& stream,
niklase@google.com470e71d2011-07-07 08:21:25 +0000405 bool loop,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000406 const uint32_t notificationTimeMs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000407 const FileFormats format,
408 const CodecInst* codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000409 const uint32_t startPointMs,
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000410 const uint32_t stopPointMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000411{
niklase@google.com470e71d2011-07-07 08:21:25 +0000412 if(!ValidFileFormat(format,codecInst))
413 {
414 return -1;
415 }
416
417 if(!ValidFilePositions(startPointMs,stopPointMs))
418 {
419 return -1;
420 }
421
kthelgason6bfe49c2017-03-30 01:14:41 -0700422 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000423 if(_playingActive || _recordingActive)
424 {
425 WEBRTC_TRACE(
426 kTraceError,
427 kTraceFile,
428 _id,
429 "StartPlaying called, but already playing or recording file %s",
henrike@webrtc.org26085e12012-02-27 21:50:40 +0000430 (_fileName[0] == '\0') ? "(name not set)" : _fileName);
niklase@google.com470e71d2011-07-07 08:21:25 +0000431 return -1;
432 }
433
434 if(_ptrFileUtilityObj != NULL)
435 {
436 WEBRTC_TRACE(kTraceError,
437 kTraceFile,
438 _id,
439 "StartPlaying called, but FileUtilityObj already exists!");
440 StopPlaying();
441 return -1;
442 }
443
444 _ptrFileUtilityObj = new ModuleFileUtility(_id);
445 if(_ptrFileUtilityObj == NULL)
446 {
447 WEBRTC_TRACE(kTraceMemory, kTraceFile, _id,
448 "Failed to create FileUtilityObj!");
449 return -1;
450 }
451
452 switch(format)
453 {
454 case kFileFormatWavFile:
455 {
456 if(_ptrFileUtilityObj->InitWavReading(stream, startPointMs,
457 stopPointMs) == -1)
458 {
459 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
460 "Not a valid WAV file!");
461 StopPlaying();
462 return -1;
463 }
464 _fileFormat = kFileFormatWavFile;
465 break;
466 }
467 case kFileFormatCompressedFile:
468 {
469 if(_ptrFileUtilityObj->InitCompressedReading(stream, startPointMs,
470 stopPointMs) == -1)
471 {
472 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
473 "Not a valid Compressed file!");
474 StopPlaying();
475 return -1;
476 }
477 _fileFormat = kFileFormatCompressedFile;
478 break;
479 }
480 case kFileFormatPcm8kHzFile:
481 case kFileFormatPcm16kHzFile:
482 case kFileFormatPcm32kHzFile:
minyue5f937092017-03-31 12:27:09 -0700483 case kFileFormatPcm48kHzFile:
niklase@google.com470e71d2011-07-07 08:21:25 +0000484 {
henrike@webrtc.org26085e12012-02-27 21:50:40 +0000485 // ValidFileFormat() called in the beginneing of this function
486 // prevents codecInst from being NULL here.
487 assert(codecInst != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000488 if(!ValidFrequency(codecInst->plfreq) ||
489 _ptrFileUtilityObj->InitPCMReading(stream, startPointMs,
490 stopPointMs,
491 codecInst->plfreq) == -1)
492 {
493 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
494 "Not a valid raw 8 or 16 KHz PCM file!");
495 StopPlaying();
496 return -1;
497 }
498
499 _fileFormat = format;
500 break;
501 }
502 case kFileFormatPreencodedFile:
503 {
henrike@webrtc.org26085e12012-02-27 21:50:40 +0000504 // ValidFileFormat() called in the beginneing of this function
505 // prevents codecInst from being NULL here.
506 assert(codecInst != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000507 if(_ptrFileUtilityObj->InitPreEncodedReading(stream, *codecInst) ==
508 -1)
509 {
510 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
511 "Not a valid PreEncoded file!");
512 StopPlaying();
513 return -1;
514 }
515
516 _fileFormat = kFileFormatPreencodedFile;
517 break;
518 }
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000519 default:
niklase@google.com470e71d2011-07-07 08:21:25 +0000520 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000521 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000522 "Invalid file format: %d", format);
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +0000523 assert(false);
524 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000525 }
526 }
527 if(_ptrFileUtilityObj->codec_info(codec_info_) == -1)
528 {
529 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
530 "Failed to retrieve codec info!");
531 StopPlaying();
532 return -1;
533 }
534
535 _isStereo = (codec_info_.channels == 2);
536 if(_isStereo && (_fileFormat != kFileFormatWavFile))
537 {
538 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
539 "Stereo is only allowed for WAV files");
540 StopPlaying();
541 return -1;
542 }
543 _playingActive = true;
544 _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
545 _ptrInStream = &stream;
546 _notificationMs = notificationTimeMs;
547
548 return 0;
549}
550
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000551int32_t MediaFileImpl::StopPlaying()
niklase@google.com470e71d2011-07-07 08:21:25 +0000552{
niklase@google.com470e71d2011-07-07 08:21:25 +0000553
kthelgason6bfe49c2017-03-30 01:14:41 -0700554 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000555 _isStereo = false;
556 if(_ptrFileUtilityObj)
557 {
558 delete _ptrFileUtilityObj;
559 _ptrFileUtilityObj = NULL;
560 }
561 if(_ptrInStream)
562 {
563 // If MediaFileImpl opened the InStream it must be reclaimed here.
564 if(_openFile)
565 {
566 delete _ptrInStream;
567 _openFile = false;
568 }
569 _ptrInStream = NULL;
570 }
571
572 codec_info_.pltype = 0;
573 codec_info_.plname[0] = '\0';
574
575 if(!_playingActive)
576 {
577 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
578 "playing is not active!");
579 return -1;
580 }
581
582 _playingActive = false;
583 return 0;
584}
585
586bool MediaFileImpl::IsPlaying()
587{
588 WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsPlaying()");
kthelgason6bfe49c2017-03-30 01:14:41 -0700589 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000590 return _playingActive;
591}
592
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000593int32_t MediaFileImpl::IncomingAudioData(
594 const int8_t* buffer,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000595 const size_t bufferLengthInBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000596{
niklase@google.com470e71d2011-07-07 08:21:25 +0000597 WEBRTC_TRACE(kTraceStream, kTraceFile, _id,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000598 "MediaFile::IncomingData(buffer= 0x%x, bufLen= %" PRIuS,
niklase@google.com470e71d2011-07-07 08:21:25 +0000599 buffer, bufferLengthInBytes);
600
601 if(buffer == NULL || bufferLengthInBytes == 0)
602 {
603 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
604 "Buffer pointer or length is NULL!");
605 return -1;
606 }
607
608 bool recordingEnded = false;
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000609 uint32_t callbackNotifyMs = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000610 {
kthelgason6bfe49c2017-03-30 01:14:41 -0700611 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000612
613 if(!_recordingActive)
614 {
615 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
616 "Not currently recording!");
617 return -1;
618 }
619 if(_ptrOutStream == NULL)
620 {
621 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
622 "Recording is active, but output stream is NULL!");
623 assert(false);
624 return -1;
625 }
626
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000627 int32_t bytesWritten = 0;
628 uint32_t samplesWritten = codec_info_.pacsize;
niklase@google.com470e71d2011-07-07 08:21:25 +0000629 if(_ptrFileUtilityObj)
630 {
631 switch(_fileFormat)
632 {
633 case kFileFormatPcm8kHzFile:
634 case kFileFormatPcm16kHzFile:
635 case kFileFormatPcm32kHzFile:
minyue5f937092017-03-31 12:27:09 -0700636 case kFileFormatPcm48kHzFile:
niklase@google.com470e71d2011-07-07 08:21:25 +0000637 bytesWritten = _ptrFileUtilityObj->WritePCMData(
638 *_ptrOutStream,
639 buffer,
640 bufferLengthInBytes);
641
642 // Sample size is 2 bytes.
643 if(bytesWritten > 0)
644 {
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000645 samplesWritten = bytesWritten/sizeof(int16_t);
niklase@google.com470e71d2011-07-07 08:21:25 +0000646 }
647 break;
648 case kFileFormatCompressedFile:
649 bytesWritten = _ptrFileUtilityObj->WriteCompressedData(
650 *_ptrOutStream, buffer, bufferLengthInBytes);
651 break;
652 case kFileFormatWavFile:
653 bytesWritten = _ptrFileUtilityObj->WriteWavData(
654 *_ptrOutStream,
655 buffer,
656 bufferLengthInBytes);
657 if(bytesWritten > 0 && STR_NCASE_CMP(codec_info_.plname,
658 "L16", 4) == 0)
659 {
660 // Sample size is 2 bytes.
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000661 samplesWritten = bytesWritten/sizeof(int16_t);
niklase@google.com470e71d2011-07-07 08:21:25 +0000662 }
663 break;
664 case kFileFormatPreencodedFile:
665 bytesWritten = _ptrFileUtilityObj->WritePreEncodedData(
666 *_ptrOutStream, buffer, bufferLengthInBytes);
667 break;
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000668 default:
niklase@google.com470e71d2011-07-07 08:21:25 +0000669 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000670 "Invalid file format: %d", _fileFormat);
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +0000671 assert(false);
niklase@google.com470e71d2011-07-07 08:21:25 +0000672 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000673 }
674 } else {
675 // TODO (hellner): quick look at the code makes me think that this
676 // code is never executed. Remove?
677 if(_ptrOutStream)
678 {
679 if(_ptrOutStream->Write(buffer, bufferLengthInBytes))
680 {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000681 bytesWritten = static_cast<int32_t>(bufferLengthInBytes);
niklase@google.com470e71d2011-07-07 08:21:25 +0000682 }
683 }
684 }
685
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000686 _recordDurationMs += samplesWritten / (codec_info_.plfreq / 1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000687
688 // Check if it's time for RecordNotification(..).
689 if(_notificationMs)
690 {
691 if(_recordDurationMs >= _notificationMs)
692 {
693 _notificationMs = 0;
694 callbackNotifyMs = _recordDurationMs;
695 }
696 }
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000697 if(bytesWritten < (int32_t)bufferLengthInBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000698 {
699 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
700 "Failed to write all requested bytes!");
701 StopRecording();
702 recordingEnded = true;
703 }
704 }
705
706 // Only _callbackCrit may and should be taken when making callbacks.
kthelgason6bfe49c2017-03-30 01:14:41 -0700707 rtc::CritScope lock(&_callbackCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000708 if(_ptrCallback)
709 {
710 if(callbackNotifyMs)
711 {
712 _ptrCallback->RecordNotification(_id, callbackNotifyMs);
713 }
714 if(recordingEnded)
715 {
716 _ptrCallback->RecordFileEnded(_id);
717 return -1;
718 }
719 }
720 return 0;
721}
722
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000723int32_t MediaFileImpl::StartRecordingAudioFile(
leozwang@webrtc.org09e77192012-03-01 18:35:54 +0000724 const char* fileName,
niklase@google.com470e71d2011-07-07 08:21:25 +0000725 const FileFormats format,
726 const CodecInst& codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000727 const uint32_t notificationTimeMs,
728 const uint32_t maxSizeBytes)
niklase@google.com470e71d2011-07-07 08:21:25 +0000729{
niklase@google.com470e71d2011-07-07 08:21:25 +0000730 if(!ValidFileName(fileName))
731 {
732 return -1;
733 }
734 if(!ValidFileFormat(format,&codecInst))
735 {
736 return -1;
737 }
738
739 FileWrapper* outputStream = FileWrapper::Create();
740 if(outputStream == NULL)
741 {
742 WEBRTC_TRACE(kTraceMemory, kTraceFile, _id,
743 "Failed to allocate memory for output stream");
744 return -1;
745 }
746
tommia6219cc2016-06-15 10:30:14 -0700747 if (!outputStream->OpenFile(fileName, false)) {
748 delete outputStream;
749 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
750 "Could not open output file '%s' for writing!", fileName);
751 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000752 }
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000753
niklase@google.com470e71d2011-07-07 08:21:25 +0000754 if(maxSizeBytes)
755 {
756 outputStream->SetMaxFileSize(maxSizeBytes);
757 }
758
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000759 if(StartRecordingAudioStream(*outputStream, format, codecInst,
760 notificationTimeMs) == -1)
niklase@google.com470e71d2011-07-07 08:21:25 +0000761 {
andresp@webrtc.orge8f50df2015-03-02 13:07:02 +0000762 outputStream->CloseFile();
niklase@google.com470e71d2011-07-07 08:21:25 +0000763 delete outputStream;
764 return -1;
765 }
766
kthelgason6bfe49c2017-03-30 01:14:41 -0700767 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000768 _openFile = true;
769 strncpy(_fileName, fileName, sizeof(_fileName));
770 _fileName[sizeof(_fileName) - 1] = '\0';
771 return 0;
772}
773
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000774int32_t MediaFileImpl::StartRecordingAudioStream(
niklase@google.com470e71d2011-07-07 08:21:25 +0000775 OutStream& stream,
776 const FileFormats format,
777 const CodecInst& codecInst,
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000778 const uint32_t notificationTimeMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000779{
niklase@google.com470e71d2011-07-07 08:21:25 +0000780 // Check codec info
781 if(!ValidFileFormat(format,&codecInst))
782 {
783 return -1;
784 }
785
kthelgason6bfe49c2017-03-30 01:14:41 -0700786 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000787 if(_recordingActive || _playingActive)
788 {
789 WEBRTC_TRACE(
790 kTraceError,
791 kTraceFile,
792 _id,
793 "StartRecording called, but already recording or playing file %s!",
794 _fileName);
795 return -1;
796 }
797
798 if(_ptrFileUtilityObj != NULL)
799 {
800 WEBRTC_TRACE(
801 kTraceError,
802 kTraceFile,
803 _id,
804 "StartRecording called, but fileUtilityObj already exists!");
805 StopRecording();
806 return -1;
807 }
808
809 _ptrFileUtilityObj = new ModuleFileUtility(_id);
810 if(_ptrFileUtilityObj == NULL)
811 {
812 WEBRTC_TRACE(kTraceMemory, kTraceFile, _id,
813 "Cannot allocate fileUtilityObj!");
814 return -1;
815 }
816
817 CodecInst tmpAudioCodec;
818 memcpy(&tmpAudioCodec, &codecInst, sizeof(CodecInst));
819 switch(format)
820 {
821 case kFileFormatWavFile:
822 {
823 if(_ptrFileUtilityObj->InitWavWriting(stream, codecInst) == -1)
824 {
825 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
826 "Failed to initialize WAV file!");
827 delete _ptrFileUtilityObj;
828 _ptrFileUtilityObj = NULL;
829 return -1;
830 }
831 _fileFormat = kFileFormatWavFile;
832 break;
833 }
834 case kFileFormatCompressedFile:
835 {
836 // Write compression codec name at beginning of file
837 if(_ptrFileUtilityObj->InitCompressedWriting(stream, codecInst) ==
838 -1)
839 {
840 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
841 "Failed to initialize Compressed file!");
842 delete _ptrFileUtilityObj;
843 _ptrFileUtilityObj = NULL;
844 return -1;
845 }
846 _fileFormat = kFileFormatCompressedFile;
847 break;
848 }
849 case kFileFormatPcm8kHzFile:
850 case kFileFormatPcm16kHzFile:
minyue5f937092017-03-31 12:27:09 -0700851 case kFileFormatPcm32kHzFile:
852 case kFileFormatPcm48kHzFile:
niklase@google.com470e71d2011-07-07 08:21:25 +0000853 {
854 if(!ValidFrequency(codecInst.plfreq) ||
855 _ptrFileUtilityObj->InitPCMWriting(stream, codecInst.plfreq) ==
856 -1)
857 {
858 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
minyue5f937092017-03-31 12:27:09 -0700859 "Failed to initialize PCM file!");
niklase@google.com470e71d2011-07-07 08:21:25 +0000860 delete _ptrFileUtilityObj;
861 _ptrFileUtilityObj = NULL;
862 return -1;
863 }
864 _fileFormat = format;
865 break;
866 }
867 case kFileFormatPreencodedFile:
868 {
869 if(_ptrFileUtilityObj->InitPreEncodedWriting(stream, codecInst) ==
870 -1)
871 {
872 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
873 "Failed to initialize Pre-Encoded file!");
874 delete _ptrFileUtilityObj;
875 _ptrFileUtilityObj = NULL;
876 return -1;
877 }
878
879 _fileFormat = kFileFormatPreencodedFile;
880 break;
881 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000882 default:
883 {
884 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
885 "Invalid file format %d specified!", format);
886 delete _ptrFileUtilityObj;
887 _ptrFileUtilityObj = NULL;
888 return -1;
889 }
890 }
891 _isStereo = (tmpAudioCodec.channels == 2);
892 if(_isStereo)
893 {
894 if(_fileFormat != kFileFormatWavFile)
895 {
896 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
897 "Stereo is only allowed for WAV files");
898 StopRecording();
899 return -1;
900 }
niklas.enbom@webrtc.org87885e82012-02-07 14:48:59 +0000901 if((STR_NCASE_CMP(tmpAudioCodec.plname, "L16", 4) != 0) &&
902 (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMU", 5) != 0) &&
903 (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMA", 5) != 0))
niklase@google.com470e71d2011-07-07 08:21:25 +0000904 {
905 WEBRTC_TRACE(
906 kTraceWarning,
907 kTraceFile,
908 _id,
909 "Stereo is only allowed for codec PCMU, PCMA and L16 ");
910 StopRecording();
911 return -1;
912 }
913 }
914 memcpy(&codec_info_, &tmpAudioCodec, sizeof(CodecInst));
915 _recordingActive = true;
916 _ptrOutStream = &stream;
917 _notificationMs = notificationTimeMs;
918 _recordDurationMs = 0;
919 return 0;
920}
921
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000922int32_t MediaFileImpl::StopRecording()
niklase@google.com470e71d2011-07-07 08:21:25 +0000923{
niklase@google.com470e71d2011-07-07 08:21:25 +0000924
kthelgason6bfe49c2017-03-30 01:14:41 -0700925 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000926 if(!_recordingActive)
927 {
928 WEBRTC_TRACE(kTraceWarning, kTraceFile, _id,
929 "recording is not active!");
930 return -1;
931 }
932
933 _isStereo = false;
934
935 if(_ptrFileUtilityObj != NULL)
936 {
937 // Both AVI and WAV header has to be updated before closing the stream
938 // because they contain size information.
939 if((_fileFormat == kFileFormatWavFile) &&
940 (_ptrOutStream != NULL))
941 {
942 _ptrFileUtilityObj->UpdateWavHeader(*_ptrOutStream);
943 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000944 delete _ptrFileUtilityObj;
945 _ptrFileUtilityObj = NULL;
946 }
947
948 if(_ptrOutStream != NULL)
949 {
950 // If MediaFileImpl opened the OutStream it must be reclaimed here.
951 if(_openFile)
952 {
953 delete _ptrOutStream;
954 _openFile = false;
955 }
956 _ptrOutStream = NULL;
957 }
958
959 _recordingActive = false;
960 codec_info_.pltype = 0;
961 codec_info_.plname[0] = '\0';
962
963 return 0;
964}
965
966bool MediaFileImpl::IsRecording()
967{
968 WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsRecording()");
kthelgason6bfe49c2017-03-30 01:14:41 -0700969 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000970 return _recordingActive;
971}
972
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000973int32_t MediaFileImpl::RecordDurationMs(uint32_t& durationMs)
niklase@google.com470e71d2011-07-07 08:21:25 +0000974{
niklase@google.com470e71d2011-07-07 08:21:25 +0000975
kthelgason6bfe49c2017-03-30 01:14:41 -0700976 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000977 if(!_recordingActive)
978 {
979 durationMs = 0;
980 return -1;
981 }
982 durationMs = _recordDurationMs;
983 return 0;
984}
985
986bool MediaFileImpl::IsStereo()
987{
988 WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsStereo()");
kthelgason6bfe49c2017-03-30 01:14:41 -0700989 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000990 return _isStereo;
991}
992
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +0000993int32_t MediaFileImpl::SetModuleFileCallback(FileCallback* callback)
niklase@google.com470e71d2011-07-07 08:21:25 +0000994{
niklase@google.com470e71d2011-07-07 08:21:25 +0000995
kthelgason6bfe49c2017-03-30 01:14:41 -0700996 rtc::CritScope lock(&_callbackCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000997
998 _ptrCallback = callback;
999 return 0;
1000}
1001
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +00001002int32_t MediaFileImpl::FileDurationMs(const char* fileName,
1003 uint32_t& durationMs,
1004 const FileFormats format,
1005 const uint32_t freqInHz)
niklase@google.com470e71d2011-07-07 08:21:25 +00001006{
niklase@google.com470e71d2011-07-07 08:21:25 +00001007
1008 if(!ValidFileName(fileName))
1009 {
1010 return -1;
1011 }
1012 if(!ValidFrequency(freqInHz))
1013 {
1014 return -1;
1015 }
1016
1017 ModuleFileUtility* utilityObj = new ModuleFileUtility(_id);
1018 if(utilityObj == NULL)
1019 {
1020 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
1021 "failed to allocate utility object!");
1022 return -1;
1023 }
1024
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +00001025 const int32_t duration = utilityObj->FileDurationMs(fileName, format,
1026 freqInHz);
niklase@google.com470e71d2011-07-07 08:21:25 +00001027 delete utilityObj;
1028 if(duration == -1)
1029 {
1030 durationMs = 0;
1031 return -1;
1032 }
1033
1034 durationMs = duration;
1035 return 0;
1036}
1037
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +00001038int32_t MediaFileImpl::PlayoutPositionMs(uint32_t& positionMs) const
niklase@google.com470e71d2011-07-07 08:21:25 +00001039{
kthelgason6bfe49c2017-03-30 01:14:41 -07001040 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +00001041 if(!_playingActive)
1042 {
1043 positionMs = 0;
1044 return -1;
1045 }
1046 positionMs = _playoutPositionMs;
1047 return 0;
1048}
1049
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +00001050int32_t MediaFileImpl::codec_info(CodecInst& codecInst) const
niklase@google.com470e71d2011-07-07 08:21:25 +00001051{
kthelgason6bfe49c2017-03-30 01:14:41 -07001052 rtc::CritScope lock(&_crit);
niklase@google.com470e71d2011-07-07 08:21:25 +00001053 if(!_playingActive && !_recordingActive)
1054 {
1055 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
1056 "Neither playout nor recording has been initialized!");
1057 return -1;
1058 }
1059 if (codec_info_.pltype == 0 && codec_info_.plname[0] == '\0')
1060 {
1061 WEBRTC_TRACE(kTraceError, kTraceFile, _id,
1062 "The CodecInst for %s is unknown!",
1063 _playingActive ? "Playback" : "Recording");
1064 return -1;
1065 }
1066 memcpy(&codecInst,&codec_info_,sizeof(CodecInst));
1067 return 0;
1068}
1069
niklase@google.com470e71d2011-07-07 08:21:25 +00001070bool MediaFileImpl::ValidFileFormat(const FileFormats format,
1071 const CodecInst* codecInst)
1072{
1073 if(codecInst == NULL)
1074 {
1075 if(format == kFileFormatPreencodedFile ||
1076 format == kFileFormatPcm8kHzFile ||
1077 format == kFileFormatPcm16kHzFile ||
minyue5f937092017-03-31 12:27:09 -07001078 format == kFileFormatPcm32kHzFile ||
1079 format == kFileFormatPcm48kHzFile)
niklase@google.com470e71d2011-07-07 08:21:25 +00001080 {
1081 WEBRTC_TRACE(kTraceError, kTraceFile, -1,
1082 "Codec info required for file format specified!");
1083 return false;
1084 }
1085 }
1086 return true;
1087}
1088
leozwang@webrtc.org09e77192012-03-01 18:35:54 +00001089bool MediaFileImpl::ValidFileName(const char* fileName)
niklase@google.com470e71d2011-07-07 08:21:25 +00001090{
1091 if((fileName == NULL) ||(fileName[0] == '\0'))
1092 {
1093 WEBRTC_TRACE(kTraceError, kTraceFile, -1, "FileName not specified!");
1094 return false;
1095 }
1096 return true;
1097}
1098
1099
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +00001100bool MediaFileImpl::ValidFilePositions(const uint32_t startPointMs,
1101 const uint32_t stopPointMs)
niklase@google.com470e71d2011-07-07 08:21:25 +00001102{
1103 if(startPointMs == 0 && stopPointMs == 0) // Default values
1104 {
1105 return true;
1106 }
1107 if(stopPointMs &&(startPointMs >= stopPointMs))
1108 {
1109 WEBRTC_TRACE(kTraceError, kTraceFile, -1,
1110 "startPointMs must be less than stopPointMs!");
1111 return false;
1112 }
1113 if(stopPointMs &&((stopPointMs - startPointMs) < 20))
1114 {
1115 WEBRTC_TRACE(kTraceError, kTraceFile, -1,
1116 "minimum play duration for files is 20 ms!");
1117 return false;
1118 }
1119 return true;
1120}
1121
pbos@webrtc.org0ea11c12013-04-09 13:31:37 +00001122bool MediaFileImpl::ValidFrequency(const uint32_t frequency)
niklase@google.com470e71d2011-07-07 08:21:25 +00001123{
minyue5f937092017-03-31 12:27:09 -07001124 if((frequency == 8000) || (frequency == 16000)|| (frequency == 32000) || (frequency == 48000))
niklase@google.com470e71d2011-07-07 08:21:25 +00001125 {
1126 return true;
1127 }
1128 WEBRTC_TRACE(kTraceError, kTraceFile, -1,
minyue5f937092017-03-31 12:27:09 -07001129 "Frequency should be 8000, 16000, 32000, or 48000 (Hz)");
niklase@google.com470e71d2011-07-07 08:21:25 +00001130 return false;
1131}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001132} // namespace webrtc