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 #include <unique_ptr.h>
20 #include <FBaseColArrayListT.h>
21 #include <FBaseInteger.h>
22 #include <FBaseColHashMap.h>
23 #include <FMediaTypes.h>
24 #include <FMediaAudioTypes.h>
25 #include <FBaseSysLog.h>
26 #include "FMedia_Ffmpeg.h"
27 #include "FMedia_FfmpegUtil.h"
28 #include "FMedia_IAudioDecoder.h"
29 #include "FMedia_AlawDecoder.h"
31 using namespace Tizen::Base;
32 using namespace Tizen::Io;
33 using namespace Tizen::Base::Collection;
35 namespace Tizen { namespace Media
39 _AlawDecoder_CreateInstance(void)
41 return new (std::nothrow) _AlawDecoder();
44 _AlawDecoder::_AlawDecoder(void)
48 __decodeCalled = false;
50 __decoderConfigured = false;
53 _AlawDecoder::~_AlawDecoder(void)
55 if (__pCodecCtx != null)
57 avcodec_close(__pCodecCtx);
60 if (__pOutBuf != null)
67 _AlawDecoder::Construct(const Tizen::Base::Collection::HashMap* pOption)
72 Integer* pValue = null;
76 SysAssertf((__pCodecCtx == null && __pCodec == null), " Already Constructed .");
77 SysTryReturnResult(NID_MEDIA, pOption != null, E_INVALID_ARG, "pOtion is null");
79 avcodec_register_all();
81 __pCodecCtx = avcodec_alloc_context();
82 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_SYSTEM, E_SYSTEM,
83 "[%s] AVCODEC Context Allcoation Failed",GetErrorMessage(E_SYSTEM));
84 __pCodec = avcodec_find_decoder(CODEC_ID_PCM_ALAW);
85 SysTryCatch(NID_MEDIA, __pCodec != null, r = E_SYSTEM, E_SYSTEM,
86 "[%s] AVCODEC Find Decoder Failed for CODEC_ID_PCM_ALAW",GetErrorMessage(E_SYSTEM));
90 // The initialization values are given in the Hashmap
91 std::unique_ptr<IMapEnumerator> pMapEnum(pOption->GetMapEnumeratorN());
92 if (pMapEnum.get() != null)
94 while (pMapEnum.get()->MoveNext() == E_SUCCESS)
96 pKey = static_cast<Integer*>(pMapEnum.get()->GetKey());
97 pValue = static_cast<Integer*>(pMapEnum.get()->GetValue());
101 value = pValue->ToInt();
104 case MEDIA_PROPERTY_AUDIO_CHANNEL_TYPE:
105 SysTryCatch(NID_MEDIA, (value == 0 || value == 1 || value == 2), r = E_OUT_OF_RANGE,
106 E_OUT_OF_RANGE, "[%s] Invalid argument is used. The value is out of range",GetErrorMessage(E_OUT_OF_RANGE));
107 __pCodecCtx->channels = value;
108 __decoderConfigured = true;
111 case MEDIA_PROPERTY_AUDIO_SAMPLE_RATE:
112 SysTryCatch(NID_MEDIA, !(value < 0), r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
113 "[%s] Invalid argument is used. The value is out of range",GetErrorMessage(E_OUT_OF_RANGE));
114 __pCodecCtx->sample_rate = value;
117 case MEDIA_PROPERTY_AUDIO_SAMPLE_TYPE:
118 SysTryCatch(NID_MEDIA, !(value < 0), r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
119 "[%s] Invalid argument is used. The value is out of range",GetErrorMessage(E_OUT_OF_RANGE));
120 __pCodecCtx->sample_fmt = _FfmpegUtil::ToAvSampleFormat((AudioSampleType)value);
132 SysTryReturnResult(NID_MEDIA, __pCodecCtx->channels != 0, E_INVALID_ARG, "Channel is not set");
133 SysTryReturnResult(NID_MEDIA, __pCodecCtx->sample_rate != 0, E_INVALID_ARG, "Sample rate is not set");
134 SysTryReturnResult(NID_MEDIA, __pCodecCtx->sample_fmt != AV_SAMPLE_FMT_NONE, E_INVALID_ARG, "Sample type is not set");
136 res = avcodec_open(__pCodecCtx, __pCodec);
137 SysTryCatch(NID_MEDIA, res >= 0, r = E_SYSTEM, E_SYSTEM,
138 "[%s] AVCODEC Codec Open Failed for CODEC_ID_PCM_ALAW",GetErrorMessage(E_SYSTEM));
140 // AVCodecContext parameters
141 if (__pCodec->capabilities & CODEC_CAP_TRUNCATED)
143 __pCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
146 __pCodecCtx->debug_mv = 0; //set by user
147 __pCodecCtx->debug = 0; //set by user
148 __pCodecCtx->workaround_bugs = 1; //set by user
149 __pCodecCtx->lowres = 0; //set by user
151 __pOutBuf = new (std::nothrow) byte[MIN_OUT_BUFFER_SIZE];
152 SysTryCatch(NID_MEDIA, __pOutBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
153 "[%s] Memory Allocation Failed ",GetErrorMessage(E_OUT_OF_MEMORY));
158 if (__pCodecCtx != null)
160 avcodec_close(__pCodecCtx);
161 av_free(__pCodecCtx);
165 if (__pOutBuf != null)
174 _AlawDecoder::Decode(const byte* pSrcBuf, int srcBufSize, int& srcBufUsed,
175 byte* pDstBuf, int dstBufSize, int& dstBufUsed)
177 result r = E_SUCCESS;
179 AVPacket inputPacket;
181 byte* pOutBuf = null;
185 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
186 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
187 SysTryCatch(NID_MEDIA, pSrcBuf != null && pDstBuf != null && srcBufSize > 0 && dstBufSize > 0,
188 r = E_INVALID_ARG, E_INVALID_ARG,
189 "[%s] Invalid argument is used. The argument is not valid",GetErrorMessage(E_INVALID_ARG));
191 // This blocks reads the input data format , i.e channel count and format type is read.
192 // No error checkin id done here as we are trying to get the channel count if user wont specify
194 if (__decoderConfigured == false)
197 _WavFormatInfo wavFormatInfo;
198 _RiffFileHeader riffHdr;
199 _RiffChunkHeader chunkHdr;
201 if ( srcBufSize > _MIN_WAVE_HEADER_SIZE )
203 memcpy(&riffHdr, pSrcBuf, sizeof(riffHdr)); // file header of 12 bytes
204 offSet += sizeof(riffHdr);
205 memcpy(&chunkHdr, pSrcBuf + offSet, sizeof(chunkHdr)); // format sub chunk header of 8 bytes
206 offSet += sizeof(chunkHdr);
207 memcpy(&wavFormatInfo, pSrcBuf + offSet, sizeof(wavFormatInfo)); // format sub chunk consists of wave info 16 bytes
208 offSet += sizeof(wavFormatInfo);
209 // assign to codec context if it is mono or stereo
210 if ( riffHdr.chunkId == _RIFF_CHUNK_ID && riffHdr.format== _RIFF_FORMAT_WAVE )
212 __pCodecCtx->channels = wavFormatInfo.channels;
213 __decoderConfigured = true;
214 // Data starts in next sub chunk
215 memcpy(&chunkHdr, pSrcBuf + offSet, sizeof(chunkHdr)); // data sub chunk header of 8 bytes
216 offSet += sizeof(chunkHdr); // offset is now at data start
220 offSet = 0; // Header info is not available
228 av_init_packet(&inputPacket);
230 inputPacket.size = srcBufSize -offSet;
231 inputPacket.data = (uint8_t*)pSrcBuf + offSet;
233 if (dstBufSize >= MIN_OUT_BUFFER_SIZE)
236 outBufSize = dstBufSize;
241 outBufSize = MIN_OUT_BUFFER_SIZE;
244 SysTryCatch(NID_MEDIA, __decoderConfigured == true, r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
245 "[%s] The input data format is not supported ",GetErrorMessage(E_UNSUPPORTED_FORMAT));
246 res = avcodec_decode_audio3(__pCodecCtx, (int16_t*)pOutBuf, &outBufSize, &inputPacket);
247 SysTryCatch(NID_MEDIA, (res > 0 && outBufSize > 0), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
248 "[%s] The input data format is not supported ",GetErrorMessage(E_UNSUPPORTED_FORMAT));
250 SysTryCatch(NID_MEDIA, dstBufSize >= outBufSize, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
251 "[%s] Memory Allocation Failed ",GetErrorMessage(E_OUT_OF_MEMORY));
253 dstBufUsed = outBufSize; // the decoded audio data size
254 srcBufUsed = res + offSet; // // input bytes used + offset header that is skipped
255 if (pOutBuf != pDstBuf)
257 memcpy(pDstBuf, pOutBuf, outBufSize);
259 __decodeCalled = true;
267 _AlawDecoder::Probe(const byte* pSrcBuf, const int srcBufSize,
268 AudioSampleType& sampleType, AudioChannelType& channelType, int& sampleRate)
270 result r = E_SUCCESS;
274 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
275 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
276 SysTryCatch(NID_MEDIA, pSrcBuf != null && srcBufSize > 0, r = E_INVALID_ARG, E_INVALID_ARG,
277 "[%s] Invalid argument is used. The argument is not valid",GetErrorMessage(E_INVALID_ARG));
279 r = Decode(pSrcBuf, srcBufSize, srcBufUsed, __pOutBuf, MIN_OUT_BUFFER_SIZE, dstBufUsed);
281 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Decode failed", GetErrorMessage(r));
283 channelType = _FfmpegUtil::ToAudioChannelType(__pCodecCtx->channels);
284 sampleType = _FfmpegUtil::ToAudioSampleType(__pCodecCtx->sample_fmt);
285 sampleRate = __pCodecCtx->sample_rate;
287 SetLastResult(E_SUCCESS);
295 _AlawDecoder::Reset(void)
297 result r = E_SUCCESS;
299 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
300 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
302 avcodec_flush_buffers(__pCodecCtx);
304 __decodeCalled = false;
305 __decoderConfigured = false;
307 SetLastResult(E_SUCCESS);
315 _AlawDecoder::GetValue(MediaPropertyType type, int& value) const
317 result r = E_SUCCESS;
319 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
320 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
321 SysTryCatch(NID_MEDIA, type > 0, r = E_INVALID_ARG, E_INVALID_ARG,
322 "[%s] Invalid argument is used. The argument is not valid",GetErrorMessage(E_INVALID_ARG));
323 SysTryCatch(NID_MEDIA, __decodeCalled, r = E_INVALID_STATE, E_INVALID_STATE,
324 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
328 case MEDIA_PROPERTY_AUDIO_CHANNEL_TYPE:
329 value = _FfmpegUtil::ToAudioChannelType(__pCodecCtx->channels);
332 case MEDIA_PROPERTY_AUDIO_SAMPLE_TYPE:
333 value = _FfmpegUtil::ToAudioSampleType(__pCodecCtx->sample_fmt);
336 case MEDIA_PROPERTY_AUDIO_SAMPLE_RATE:
337 value = __pCodecCtx->sample_rate;
352 _AlawDecoder::GetValue(MediaPropertyType type, float& value) const
354 result r = E_SUCCESS;
355 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
356 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
357 SysTryCatch(NID_MEDIA, type > 0, r = E_INVALID_ARG, E_INVALID_ARG,
358 "[%s] Invalid argument is used. The argument is not valid",GetErrorMessage(E_INVALID_ARG));
359 SysTryCatch(NID_MEDIA, __decodeCalled, r = E_INVALID_STATE, E_INVALID_STATE,
360 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
362 return E_OBJ_NOT_FOUND;
368 Tizen::Base::Collection::IListT<MediaPropertyType>*
369 _AlawDecoder::GetSupportedPropertyListN(void) const
371 result r = E_SUCCESS;
372 ArrayListT<MediaPropertyType>* pList = new (std::nothrow) ArrayListT<MediaPropertyType>;
374 SysTryCatch(NID_MEDIA, pList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
375 "[%s] Memory Allocation Failed ",GetErrorMessage(E_OUT_OF_MEMORY));
376 pList->Add(MEDIA_PROPERTY_AUDIO_SAMPLE_RATE);
377 pList->Add(MEDIA_PROPERTY_AUDIO_CHANNEL_TYPE);
378 pList->Add(MEDIA_PROPERTY_AUDIO_SAMPLE_TYPE);
387 _AlawDecoder::IsPropertySupported(MediaPropertyType type) const
389 result r = E_SUCCESS;
391 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
392 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
393 SysTryCatch(NID_MEDIA, type == MEDIA_PROPERTY_AUDIO_SAMPLE_RATE ||
394 type == MEDIA_PROPERTY_AUDIO_CHANNEL_TYPE ||
395 type == MEDIA_PROPERTY_AUDIO_SAMPLE_TYPE,
396 r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
397 "[%s] The instance is not available ",GetErrorMessage(E_OBJ_NOT_FOUND));