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 int width; //max boundary
310 int height; // min boundary
311 RecordingQuality quality;
314 static const _VideoQualityTable _VIDEO_QUALITY[] =
316 {48000, 128, 96, RECORDING_QUALITY_LOW},
317 {64000, 128, 96, RECORDING_QUALITY_MEDIUM},
318 {80000, 128, 96, RECORDING_QUALITY_HIGH},
320 {72000, 162, 120, RECORDING_QUALITY_LOW},
321 {97000, 160, 120, RECORDING_QUALITY_MEDIUM},
322 {120000, 160, 120, RECORDING_QUALITY_HIGH},
324 {96000, 800, 600, RECORDING_QUALITY_LOW},
325 {128000, 800, 600, RECORDING_QUALITY_MEDIUM},
326 {160000, 800, 600, RECORDING_QUALITY_HIGH},
328 {96000, 0xfffe, 0xfffe, RECORDING_QUALITY_LOW},
329 {160000, 0xfffe, 0xfffe, RECORDING_QUALITY_MEDIUM},
330 {4000000, 0xfffe, 0xfffe, RECORDING_QUALITY_HIGH},
334 _RecorderUtil::GetMmVideoQuality(const Tizen::Graphics::Dimension& dim, RecordingQuality quality, int& mmAttrBitrate)
336 bool findFlag = false;
337 int size = sizeof(_VIDEO_QUALITY)/sizeof(_VIDEO_QUALITY[0]);
339 for (int i = 0; i < size; i++)
341 if (_VIDEO_QUALITY[i].width >= dim.width && _VIDEO_QUALITY[i].height >= dim.height && _VIDEO_QUALITY[i].quality == quality)
343 mmAttrBitrate = _VIDEO_QUALITY[i].mmAttrBitrate;
348 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
353 recorder_rotation_e mmAttr;
354 RecordingRotation value;
357 static const _RotationTable _ROTATION[] =
359 {RECORDER_ROTATION_NONE, RECORDING_ROTATION_NONE},
360 {RECORDER_ROTATION_90, RECORDING_ROTATION_90},
361 {RECORDER_ROTATION_180, RECORDING_ROTATION_180},
362 {RECORDER_ROTATION_270, RECORDING_ROTATION_270},
366 _RecorderUtil::GetMmRotation(RecordingRotation value, recorder_rotation_e& mmAttr)
368 bool findFlag = false;
369 int size = sizeof(_ROTATION)/sizeof(_ROTATION[0]);
371 for (int i = 0; i < size; i++)
373 if (_ROTATION[i].value == value)
375 mmAttr = _ROTATION[i].mmAttr;
380 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
384 _RecorderUtil::GetOspRotation(recorder_rotation_e mmAttr, RecordingRotation& value)
386 bool findFlag = false;
387 int size = sizeof(_ROTATION)/sizeof(_ROTATION[0]);
389 for (int i = 0; i < size; i++)
391 if (_ROTATION[i].mmAttr == mmAttr)
393 value = _ROTATION[i].value;
398 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
403 CameraRotation cameraRotation;
404 RecordingRotation recorderRotation;
405 }CameraRecorderRotationTable;
407 static const CameraRecorderRotationTable _CAM_REC_ROTATION[] =
409 {CAMERA_ROTATION_NONE, RECORDING_ROTATION_NONE},
410 {CAMERA_ROTATION_90, RECORDING_ROTATION_90},
411 {CAMERA_ROTATION_180, RECORDING_ROTATION_180},
412 {CAMERA_ROTATION_270, RECORDING_ROTATION_270},
416 _RecorderUtil::GetRecorderRotation(CameraRotation cameraRotation, RecordingRotation& recorderRotation)
418 bool findFlag = false;
419 int size = sizeof(_CAM_REC_ROTATION)/sizeof(_CAM_REC_ROTATION[0]);
421 for (int i = 0; i < size; i++)
423 if (_CAM_REC_ROTATION[i].cameraRotation == cameraRotation)
425 recorderRotation = _CAM_REC_ROTATION[i].recorderRotation;
430 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
434 _RecorderUtil::GetCameraRotation(RecordingRotation recorderRotation, CameraRotation& cameraRotation)
436 bool findFlag = false;
437 int size = sizeof(_CAM_REC_ROTATION)/sizeof(_CAM_REC_ROTATION[0]);
439 for (int i = 0; i < size; i++)
441 if (_CAM_REC_ROTATION[i].recorderRotation == recorderRotation)
443 cameraRotation = _CAM_REC_ROTATION[i].cameraRotation;
448 return findFlag ? E_SUCCESS : E_UNSUPPORTED_TYPE;
452 _RecorderUtil::CheckFormat(CodecType audioCodec, CodecType videoCodec, MediaContainerType container)
454 bool supported = false;
456 tableCount = sizeof(_SUPPORTED_CODEC_CONTAINER) / sizeof(_SUPPORTED_CODEC_CONTAINER[0]);
458 for (int i = 0; i < tableCount; i++)
460 if (audioCodec == _SUPPORTED_CODEC_CONTAINER[i].audioCodec && videoCodec == _SUPPORTED_CODEC_CONTAINER[i].videoCodec && container == _SUPPORTED_CODEC_CONTAINER[i].container)
470 _RecorderUtil::PrepareFile(const Tizen::Base::String& path, bool overwrite)
472 result r = E_SUCCESS;
474 if (File::IsFileExist(path))
478 r = File::Remove(path);
479 SysSecureTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] camcorder remove existing file failed. path:%ls", GetErrorMessage(r), path.GetPointer());
483 r = E_FILE_ALREADY_EXIST;
484 SysSecureLogException(NID_MEDIA, r, "[E_FILE_ALREADY_EXIST] The file already exists and overwrite is false. path:%ls", path.GetPointer());
491 r = file.Construct(path, L"w");
492 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());
493 r = File::Remove(path);
494 SysSecureTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] camcorder remove temp file failed. path:%ls", GetErrorMessage(r), path.GetPointer());
504 _RecorderUtil::GetOspSampleType(audio_sample_type_e audioSampleType)
506 switch (audioSampleType)
508 case AUDIO_SAMPLE_TYPE_U8:
509 return AUDIO_TYPE_PCM_U8;
512 case AUDIO_SAMPLE_TYPE_S16_LE:
513 return AUDIO_TYPE_PCM_S16_LE;
517 return AUDIO_TYPE_PCM_S16_LE;
523 _RecorderUtil::GetOspChannelType(int audioChannelType)
525 switch (audioChannelType)
528 return AUDIO_CHANNEL_TYPE_MONO;
532 return AUDIO_CHANNEL_TYPE_STEREO;
536 return AUDIO_CHANNEL_TYPE_NONE;
542 _RecorderUtil::ConvertAudioSampleTypeToInt(AudioSampleType sampleType)
547 case AUDIO_TYPE_NONE:
550 case AUDIO_TYPE_PCM_S8:
552 case AUDIO_TYPE_PCM_U8:
555 case AUDIO_TYPE_PCM_U16_LE:
557 case AUDIO_TYPE_PCM_S16_LE:
559 case AUDIO_TYPE_PCM_S16_BE:
561 case AUDIO_TYPE_PCM_U16_BE:
572 _RecorderUtil::CalculateSampleRate(int size, int channel, int timeStamp, AudioSampleType sampleType)
574 //bitRate = sample Rate * bitDepth * No of Channel;
576 SysTryReturn(NID_MEDIA, timeStamp != 0, 0, E_INVALID_DATA, "[E_INVALID_DATA] Sampling rate cannot be calculated");
582 bitRate = (size * 1000 * 8)/timeStamp; // convert from bytes to bits for "Packet duration" mili sec of data
584 bitDepth = ConvertAudioSampleTypeToInt(sampleType);
585 sampleRate = (bitRate / (bitDepth * channel));