2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FMedia_RecorderUtil.cpp
20 * @brief This file contains the utility of camcorder.
25 #include <FBaseSysLog.h>
26 #include "FMedia_RecorderUtil.h"
28 using namespace Tizen::Io;
30 namespace Tizen { namespace Media
35 Tizen::Media::CodecType audioCodec;
36 Tizen::Media::CodecType videoCodec;
37 Tizen::Media::MediaContainerType container;
38 } _CodecContainerTable;
40 const static _CodecContainerTable _SUPPORTED_CODEC_CONTAINER[] =
43 { CODEC_LPCM, CODEC_NONE, MEDIA_CONTAINER_WAV},
44 { CODEC_AMR_NB, CODEC_NONE, MEDIA_CONTAINER_AMR},
45 { CODEC_AMR_NB, CODEC_NONE, MEDIA_CONTAINER_3GP},
46 // { CODEC_AMR_NB, CODEC_NONE, MEDIA_CONTAINER_MP4},
47 { CODEC_AAC, CODEC_NONE, MEDIA_CONTAINER_AAC},
48 { CODEC_AAC, CODEC_NONE, MEDIA_CONTAINER_3GP},
49 { CODEC_AAC, CODEC_NONE, MEDIA_CONTAINER_MP4},
52 { CODEC_AMR_NB, CODEC_MPEG4, MEDIA_CONTAINER_3GP},
53 { CODEC_AMR_NB, CODEC_H263, MEDIA_CONTAINER_3GP},
54 { CODEC_AMR_NB, CODEC_H264, MEDIA_CONTAINER_3GP},
55 // { CODEC_AMR_NB, CODEC_MPEG4, MEDIA_CONTAINER_MP4},
56 // { CODEC_AMR_NB, CODEC_H263, MEDIA_CONTAINER_MP4},
57 // { CODEC_AMR_NB, CODEC_H264, MEDIA_CONTAINER_MP4},
59 { CODEC_AAC, CODEC_MPEG4, MEDIA_CONTAINER_3GP},
60 { CODEC_AAC, CODEC_H263, MEDIA_CONTAINER_3GP},
61 { CODEC_AAC, CODEC_H264, MEDIA_CONTAINER_3GP},
62 { CODEC_AAC, CODEC_MPEG4, MEDIA_CONTAINER_MP4},
63 // { CODEC_AAC, CODEC_H263, MEDIA_CONTAINER_MP4},
64 { CODEC_AAC, CODEC_H264, MEDIA_CONTAINER_MP4},
66 { CODEC_NONE, CODEC_MPEG4, MEDIA_CONTAINER_3GP},
67 { CODEC_NONE, CODEC_H263, MEDIA_CONTAINER_3GP},
68 { CODEC_NONE, CODEC_H264, MEDIA_CONTAINER_3GP},
69 { CODEC_NONE, CODEC_MPEG4, MEDIA_CONTAINER_MP4},
70 // { CODEC_NONE, CODEC_H263, MEDIA_CONTAINER_MP4},
71 { CODEC_NONE, CODEC_H264, MEDIA_CONTAINER_MP4},
77 recorder_audio_codec_e mmAttr;
81 static const _AudioCodecTable _AUDIO_CODEC[] =
83 {::RECORDER_AUDIO_CODEC_DISABLE, CODEC_NONE},
84 {::RECORDER_AUDIO_CODEC_AMR, CODEC_AMR_NB},
85 {::RECORDER_AUDIO_CODEC_AAC, CODEC_AAC},
86 // {::RECORDER_AUDIO_CODEC_VORBIS, CODEC_VORBIS},//We do not supported VORBIS CODEC TYPE
87 {::RECORDER_AUDIO_CODEC_PCM, CODEC_LPCM},
91 _RecorderUtil::GetMmAudioCodec(CodecType value, recorder_audio_codec_e& mmAttr)
93 bool findFlag = false;
94 int size = sizeof(_AUDIO_CODEC)/sizeof(_AUDIO_CODEC[0]);
96 for (int i = 0; i < size; i++)
98 if (_AUDIO_CODEC[i].value == value)
100 mmAttr = _AUDIO_CODEC[i].mmAttr;
105 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
109 _RecorderUtil::GetOspAudioCodec(recorder_audio_codec_e mmAttr, CodecType& value)
111 bool findFlag = false;
112 int size = sizeof(_AUDIO_CODEC)/sizeof(_AUDIO_CODEC[0]);
114 for (int i = 0; i < size; i++)
116 if (_AUDIO_CODEC[i].mmAttr == mmAttr)
118 value = _AUDIO_CODEC[i].value;
123 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
128 recorder_video_codec_e mmAttr;
132 static const _VideoCodecTable _VIDEO_CODEC[] =
134 {::RECORDER_VIDEO_CODEC_H263, CODEC_H263},
135 {::RECORDER_VIDEO_CODEC_H264, CODEC_H264},
136 {::RECORDER_VIDEO_CODEC_MPEG4, CODEC_MPEG4},
137 // {::RECORDER_VIDEO_CODEC_THEORA, CODEC_THEORA},
141 _RecorderUtil::GetMmVideoCodec(CodecType value, recorder_video_codec_e& mmAttr)
143 bool findFlag = false;
144 int size = sizeof(_VIDEO_CODEC)/sizeof(_VIDEO_CODEC[0]);
146 for (int i = 0; i < size; i++)
148 if (_VIDEO_CODEC[i].value == value)
150 mmAttr = _VIDEO_CODEC[i].mmAttr;
155 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
159 _RecorderUtil::GetOspVideoCodec(recorder_video_codec_e mmAttr, CodecType& value)
161 bool findFlag = false;
162 int size = sizeof(_VIDEO_CODEC)/sizeof(_VIDEO_CODEC[0]);
164 for (int i = 0; i < size; i++)
166 if (_VIDEO_CODEC[i].mmAttr == mmAttr)
168 value = _VIDEO_CODEC[i].value;
173 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
178 recorder_file_format_e mmAttr;
179 MediaContainerType value;
182 static const _ContainerTable _CONTAINER[] =
184 {::RECORDER_FILE_FORMAT_3GP, MEDIA_CONTAINER_3GP},
185 {::RECORDER_FILE_FORMAT_MP4, MEDIA_CONTAINER_MP4},
186 {::RECORDER_FILE_FORMAT_AMR, MEDIA_CONTAINER_AMR},
187 {::RECORDER_FILE_FORMAT_ADTS, MEDIA_CONTAINER_AAC},
188 {::RECORDER_FILE_FORMAT_WAV, MEDIA_CONTAINER_WAV},
194 recorder_file_format_e mmAttr;
195 MediaContainerType value;
196 }_VideoContainerTable;
198 static const _VideoContainerTable _VIDEO_CONTAINER[] =
200 {::RECORDER_FILE_FORMAT_3GP, MEDIA_CONTAINER_3GP},
201 {::RECORDER_FILE_FORMAT_MP4, MEDIA_CONTAINER_MP4},
206 recorder_file_format_e mmAttr;
207 MediaContainerType value;
208 }_ContainerVideoTable;
211 _RecorderUtil::GetMmFileFormat(MediaContainerType value, recorder_file_format_e& mmAttr)
213 bool findFlag = false;
214 int size = sizeof(_CONTAINER)/sizeof(_CONTAINER[0]);
216 for (int i = 0; i < size; i++)
218 if (_CONTAINER[i].value == value)
220 mmAttr = _CONTAINER[i].mmAttr;
225 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
229 _RecorderUtil::GetOspVideoContainer(recorder_file_format_e mmAttr, MediaContainerType& value)
231 bool findFlag = false;
232 int size = sizeof(_VIDEO_CONTAINER)/sizeof(_VIDEO_CONTAINER[0]);
234 for (int i = 0; i < size; i++)
236 if (_VIDEO_CONTAINER[i].mmAttr == mmAttr)
238 value = _VIDEO_CONTAINER[i].value;
243 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
247 _RecorderUtil::GetOspAudioContainer(recorder_file_format_e mmAttr, MediaContainerType& value)
249 bool findFlag = false;
250 int size = sizeof(_CONTAINER)/sizeof(_CONTAINER[0]);
252 for (int i = 0; i < size; i++)
254 if (_CONTAINER[i].mmAttr == mmAttr)
256 value = _CONTAINER[i].value;
261 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
266 int mmAttrSamplerate;
269 CodecType audioCodec;
270 RecordingQuality quality;
273 static const _AudioQualityTable _AUDIO_QUALITY[] =
275 {8000, 1, 256000, CODEC_LPCM, RECORDING_QUALITY_LOW},
276 {22050, 2, 706000, CODEC_LPCM, RECORDING_QUALITY_MEDIUM},
277 {44100, 2, 1411000, CODEC_LPCM, RECORDING_QUALITY_HIGH},
278 {8000, 1, 4750, CODEC_AMR_NB, RECORDING_QUALITY_LOW},
279 {8000, 1, 7950, CODEC_AMR_NB, RECORDING_QUALITY_MEDIUM},
280 {8000, 1, 12200, CODEC_AMR_NB, RECORDING_QUALITY_HIGH},
281 {22050, 2, 120000, CODEC_AAC, RECORDING_QUALITY_LOW},
282 {44100, 2, 220000, CODEC_AAC, RECORDING_QUALITY_MEDIUM},
283 {44100, 2, 320000, CODEC_AAC, RECORDING_QUALITY_HIGH},
287 _RecorderUtil::GetMmAudioQuality(CodecType audioCodec, RecordingQuality quality, int& mmAttrSamplerate, int& mmAttrChannel, int& mmAttrBitrate)
289 bool findFlag = false;
290 int size = sizeof(_AUDIO_QUALITY)/sizeof(_AUDIO_QUALITY[0]);
292 for (int i = 0; i < size; i++)
294 if (_AUDIO_QUALITY[i].audioCodec == audioCodec && _AUDIO_QUALITY[i].quality == quality)
296 mmAttrSamplerate = _AUDIO_QUALITY[i].mmAttrSamplerate;
297 mmAttrChannel = _AUDIO_QUALITY[i].mmAttrChannel;
298 mmAttrBitrate = _AUDIO_QUALITY[i].mmAttrBitrate;
303 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
309 _ResolutionType resolution;
310 RecordingQuality quality;
313 static const _VideoQualityTable _VIDEO_QUALITY[] =
315 {48000, _RES_128X96, RECORDING_QUALITY_LOW},
316 {64000, _RES_128X96, RECORDING_QUALITY_MEDIUM},
317 {80000, _RES_128X96, RECORDING_QUALITY_HIGH},
318 {72000, _RES_160X120, RECORDING_QUALITY_LOW},
319 {97000, _RES_160X120, RECORDING_QUALITY_MEDIUM},
320 {120000, _RES_160X120, RECORDING_QUALITY_HIGH},
321 {96000, _RES_176X144, RECORDING_QUALITY_LOW},
322 {128000, _RES_176X144, RECORDING_QUALITY_MEDIUM},
323 {160000, _RES_176X144, RECORDING_QUALITY_HIGH},
324 {96000, _RES_176X176, RECORDING_QUALITY_LOW},
325 {128000, _RES_176X176, RECORDING_QUALITY_MEDIUM},
326 {160000, _RES_176X176, RECORDING_QUALITY_HIGH},
327 {96000, _RES_240X320, RECORDING_QUALITY_LOW},
328 {128000, _RES_240X320, RECORDING_QUALITY_MEDIUM},
329 {160000, _RES_240X320, RECORDING_QUALITY_HIGH},
330 {96000, _RES_320X240, RECORDING_QUALITY_LOW},
331 {128000, _RES_320X240, RECORDING_QUALITY_MEDIUM},
332 {160000, _RES_320X240, RECORDING_QUALITY_HIGH},
333 {96000, _RES_240X400, RECORDING_QUALITY_LOW},
334 {128000, _RES_240X400, RECORDING_QUALITY_MEDIUM},
335 {160000, _RES_240X400, RECORDING_QUALITY_HIGH},
336 {96000, _RES_400X240, RECORDING_QUALITY_LOW},
337 {128000, _RES_400X240, RECORDING_QUALITY_MEDIUM},
338 {160000, _RES_400X240, RECORDING_QUALITY_HIGH},
339 {96000, _RES_352X288, RECORDING_QUALITY_LOW},
340 {128000, _RES_352X288, RECORDING_QUALITY_MEDIUM},
341 {160000, _RES_352X288, RECORDING_QUALITY_HIGH},
342 {96000, _RES_480X360, RECORDING_QUALITY_LOW},
343 {128000, _RES_480X360, RECORDING_QUALITY_MEDIUM},
344 {160000, _RES_480X360, RECORDING_QUALITY_HIGH},
345 {96000, _RES_640X360, RECORDING_QUALITY_LOW},
346 {128000, _RES_640X360, RECORDING_QUALITY_MEDIUM},
347 {160000, _RES_640X360, RECORDING_QUALITY_HIGH},
349 {2000000, _RES_640X480, RECORDING_QUALITY_LOW},
350 {2500000, _RES_640X480, RECORDING_QUALITY_MEDIUM},
351 {3000000, _RES_640X480, RECORDING_QUALITY_HIGH},
352 {2200000, _RES_720X480, RECORDING_QUALITY_LOW},
353 {2800000, _RES_720X480, RECORDING_QUALITY_MEDIUM},
354 {3300000, _RES_720X480, RECORDING_QUALITY_HIGH},
356 {96000, _RES_800X480, RECORDING_QUALITY_LOW},
357 {128000, _RES_800X480, RECORDING_QUALITY_MEDIUM},
358 {160000, _RES_800X480, RECORDING_QUALITY_HIGH},
359 {96000, _RES_800X600, RECORDING_QUALITY_LOW},
360 {128000, _RES_800X600, RECORDING_QUALITY_MEDIUM},
361 {160000, _RES_800X600, RECORDING_QUALITY_HIGH},
363 {2000000, _RES_960X720, RECORDING_QUALITY_LOW},
364 {2500000, _RES_960X720, RECORDING_QUALITY_MEDIUM},
365 {3000000, _RES_960X720, RECORDING_QUALITY_HIGH},
367 {2000000, _RES_1280X720, RECORDING_QUALITY_LOW},
368 {2500000, _RES_1280X720, RECORDING_QUALITY_MEDIUM},
369 {3000000, _RES_1280X720, RECORDING_QUALITY_HIGH},
371 {2000000, _RES_1280X960, RECORDING_QUALITY_LOW},
372 {2500000, _RES_1280X960, RECORDING_QUALITY_MEDIUM},
373 {3000000, _RES_1280X960, RECORDING_QUALITY_HIGH},
375 {2000000, _RES_1392X1392, RECORDING_QUALITY_LOW},
376 {2500000, _RES_1392X1392, RECORDING_QUALITY_MEDIUM},
377 {3000000, _RES_1392X1392, RECORDING_QUALITY_HIGH},
379 {2200000, _RES_1600X1200, RECORDING_QUALITY_LOW},
380 {2800000, _RES_1600X1200, RECORDING_QUALITY_MEDIUM},
381 {3300000, _RES_1600X1200, RECORDING_QUALITY_HIGH},
382 {2200000, _RES_1920X1080, RECORDING_QUALITY_LOW},
383 {2800000, _RES_1920X1080, RECORDING_QUALITY_MEDIUM},
384 {3300000, _RES_1920X1080, RECORDING_QUALITY_HIGH},
388 _RecorderUtil::GetMmVideoQuality(_ResolutionType resolution, RecordingQuality quality, int& mmAttrBitrate)
390 bool findFlag = false;
391 int size = sizeof(_VIDEO_QUALITY)/sizeof(_VIDEO_QUALITY[0]);
393 for (int i = 0; i < size; i++)
395 if (_VIDEO_QUALITY[i].resolution == resolution && _VIDEO_QUALITY[i].quality == quality)
397 mmAttrBitrate = _VIDEO_QUALITY[i].mmAttrBitrate;
402 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
407 recorder_rotation_e mmAttr;
408 RecordingRotation value;
411 static const _RotationTable _ROTATION[] =
413 {RECORDER_ROTATION_NONE, RECORDING_ROTATION_NONE},
414 {RECORDER_ROTATION_90, RECORDING_ROTATION_90},
415 {RECORDER_ROTATION_180, RECORDING_ROTATION_180},
416 {RECORDER_ROTATION_270, RECORDING_ROTATION_270},
420 _RecorderUtil::GetMmRotation(RecordingRotation value, recorder_rotation_e& mmAttr)
422 bool findFlag = false;
423 int size = sizeof(_ROTATION)/sizeof(_ROTATION[0]);
425 for (int i = 0; i < size; i++)
427 if (_ROTATION[i].value == value)
429 mmAttr = _ROTATION[i].mmAttr;
434 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
438 _RecorderUtil::GetOspRotation(recorder_rotation_e mmAttr, RecordingRotation& value)
440 bool findFlag = false;
441 int size = sizeof(_ROTATION)/sizeof(_ROTATION[0]);
443 for (int i = 0; i < size; i++)
445 if (_ROTATION[i].mmAttr == mmAttr)
447 value = _ROTATION[i].value;
452 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
457 CameraRotation cameraRotation;
458 RecordingRotation recorderRotation;
459 }CameraRecorderRotationTable;
461 static const CameraRecorderRotationTable _CAM_REC_ROTATION[] =
463 {CAMERA_ROTATION_NONE, RECORDING_ROTATION_NONE},
464 {CAMERA_ROTATION_90, RECORDING_ROTATION_90},
465 {CAMERA_ROTATION_180, RECORDING_ROTATION_180},
466 {CAMERA_ROTATION_270, RECORDING_ROTATION_270},
470 _RecorderUtil::GetRecorderRotation(CameraRotation cameraRotation, RecordingRotation& recorderRotation)
472 bool findFlag = false;
473 int size = sizeof(_CAM_REC_ROTATION)/sizeof(_CAM_REC_ROTATION[0]);
475 for (int i = 0; i < size; i++)
477 if (_CAM_REC_ROTATION[i].cameraRotation == cameraRotation)
479 recorderRotation = _CAM_REC_ROTATION[i].recorderRotation;
484 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
488 _RecorderUtil::GetCameraRotation(RecordingRotation recorderRotation, CameraRotation& cameraRotation)
490 bool findFlag = false;
491 int size = sizeof(_CAM_REC_ROTATION)/sizeof(_CAM_REC_ROTATION[0]);
493 for (int i = 0; i < size; i++)
495 if (_CAM_REC_ROTATION[i].recorderRotation == recorderRotation)
497 cameraRotation = _CAM_REC_ROTATION[i].cameraRotation;
502 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
506 _RecorderUtil::CheckFormat(CodecType audioCodec, CodecType videoCodec, MediaContainerType container)
508 bool supported = false;
510 tableCount = sizeof(_SUPPORTED_CODEC_CONTAINER) / sizeof(_SUPPORTED_CODEC_CONTAINER[0]);
512 for (int i = 0; i < tableCount; i++)
514 if (audioCodec == _SUPPORTED_CODEC_CONTAINER[i].audioCodec && videoCodec == _SUPPORTED_CODEC_CONTAINER[i].videoCodec && container == _SUPPORTED_CODEC_CONTAINER[i].container)
524 _RecorderUtil::PrepareFile(const Tizen::Base::String& path, bool overwrite)
526 result r = E_SUCCESS;
528 if (File::IsFileExist(path))
532 r = File::Remove(path);
533 SysSecureTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] camcorder remove existing file failed. path:%ls", GetErrorMessage(r), path.GetPointer());
537 r = E_FILE_ALREADY_EXIST;
538 SysSecureLogException(NID_MEDIA, r, "[E_FILE_ALREADY_EXIST] The file already exists and overwrite is false. path:%ls", path.GetPointer());
545 r = file.Construct(path, L"w");
546 SysSecureTryCatch(NID_MEDIA, r == E_SUCCESS, r = E_RESOURCE_UNAVAILABLE, E_RESOURCE_UNAVAILABLE, "[E_RESOURCE_UNAVAILABLE] The file path is not available. path:%ls", path.GetPointer());
547 r = File::Remove(path);
548 SysSecureTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] camcorder remove temp file failed. path:%ls", GetErrorMessage(r), path.GetPointer());
558 _RecorderUtil::GetOspSampleType(audio_sample_type_e audioSampleType)
560 switch (audioSampleType)
562 case AUDIO_SAMPLE_TYPE_U8:
563 return AUDIO_TYPE_PCM_U8;
566 case AUDIO_SAMPLE_TYPE_S16_LE:
567 return AUDIO_TYPE_PCM_S16_LE;
571 return AUDIO_TYPE_PCM_S16_LE;
577 _RecorderUtil::GetOspChannelType(int audioChannelType)
579 switch (audioChannelType)
582 return AUDIO_CHANNEL_TYPE_MONO;
586 return AUDIO_CHANNEL_TYPE_STEREO;
590 return AUDIO_CHANNEL_TYPE_NONE;
596 _RecorderUtil::ConvertAudioSampleTypeToInt(AudioSampleType sampleType)
601 case AUDIO_TYPE_NONE:
604 case AUDIO_TYPE_PCM_S8:
606 case AUDIO_TYPE_PCM_U8:
609 case AUDIO_TYPE_PCM_U16_LE:
611 case AUDIO_TYPE_PCM_S16_LE:
613 case AUDIO_TYPE_PCM_S16_BE:
615 case AUDIO_TYPE_PCM_U16_BE:
626 _RecorderUtil::CalculateSampleRate(int size, int channel, int timeStamp, AudioSampleType sampleType)
628 //bitRate = sample Rate * bitDepth * No of Channel;
630 SysTryReturn(NID_MEDIA, timeStamp != 0, 0, E_INVALID_DATA, "[E_INVALID_DATA] Sampling rate cannot be calculated");
636 bitRate = (size * 1000 * 8)/timeStamp; // convert from bytes to bits for "Packet duration" mili sec of data
638 bitDepth = ConvertAudioSampleTypeToInt(sampleType);
639 sampleRate = (bitRate / (bitDepth * channel));