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 <FBaseColArrayListT.h>
20 #include <FBaseColHashMap.h>
21 #include <FMediaTypes.h>
22 #include <FMediaAudioTypes.h>
23 #include <FBaseSysLog.h>
24 #include "FMedia_Ffmpeg.h"
25 #include "FMedia_FfmpegUtil.h"
26 #include "FMedia_IAudioDecoder.h"
27 #include "FMedia_Mp3Decoder.h"
29 using namespace Tizen::Base;
30 using namespace Tizen::Io;
31 using namespace Tizen::Base::Collection;
33 namespace Tizen { namespace Media
37 _Mp3Decoder_CreateInstance(void)
39 return new (std::nothrow) _Mp3Decoder();
42 _Mp3Decoder::_Mp3Decoder(void)
46 __decodeCalled = false;
50 _Mp3Decoder::~_Mp3Decoder(void)
52 if (__pCodecCtx != null)
54 avcodec_close(__pCodecCtx);
57 if (__pOutBuf != null)
64 _Mp3Decoder::Construct(const Tizen::Base::Collection::HashMap* pOption)
69 SysAssertf((__pCodecCtx == null && __pCodec == null), " Already Constructed .");
\r
71 avcodec_register_all();
73 __pCodecCtx = avcodec_alloc_context();
74 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_SYSTEM, E_SYSTEM,
75 "[%s] AVCODEC Context Allcoation Failed",GetErrorMessage(E_SYSTEM));
\r
76 __pCodec = avcodec_find_decoder(CODEC_ID_MP3);
77 SysTryCatch(NID_MEDIA, __pCodec != null, r = E_SYSTEM, E_SYSTEM,
78 "[%s] AVCODEC Find Decoder Failed for CODEC_ID_MP3",GetErrorMessage(E_SYSTEM));
\r
80 res = avcodec_open(__pCodecCtx, __pCodec);
81 SysTryCatch(NID_MEDIA, res >= 0, r = E_SYSTEM, E_SYSTEM,
82 "[%s] AVCODEC Codec Open Failed for CODEC_ID_MP3",GetErrorMessage(E_SYSTEM));
\r
84 // AVCodecContext parameters
85 if (__pCodec->capabilities & CODEC_CAP_TRUNCATED)
87 __pCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
90 __pCodecCtx->debug_mv = 0; //set by user
91 __pCodecCtx->debug = 0; //set by user
92 __pCodecCtx->workaround_bugs = 1; //set by user
93 __pCodecCtx->lowres = 0; //set by user
94 __pCodecCtx->skip_frame = AVDISCARD_DEFAULT; //set by user
95 __pCodecCtx->skip_idct = AVDISCARD_DEFAULT; //set by user
96 __pCodecCtx->skip_loop_filter = AVDISCARD_DEFAULT; //set by user
98 __pOutBuf = new (std::nothrow) byte[_MIN_OUT_BUFFER_SIZE];
99 SysTryCatch(NID_MEDIA, __pOutBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
100 "[%s] Memory Allocation Failed ",GetErrorMessage(E_OUT_OF_MEMORY));
\r
105 if (__pCodecCtx != null)
107 avcodec_close(__pCodecCtx);
108 av_free(__pCodecCtx);
112 if (__pOutBuf != null)
121 _Mp3Decoder::Decode(const byte* pSrcBuf, int srcBufSize, int& srcBufUsed,
122 byte* pDstBuf, int dstBufSize, int& dstBufUsed)
124 result r = E_SUCCESS;
126 AVPacket inputPacket;
128 bool hasSyncBits = false;
129 byte* pOutBuf = null;
130 int srcBytesSkipped = 0;
132 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
133 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
\r
134 SysTryCatch(NID_MEDIA, pSrcBuf != null && pDstBuf != null && srcBufSize > 0 && dstBufSize > 0,
135 r = E_INVALID_ARG, E_INVALID_ARG,
136 "[%s] Invalid argument is used. The argument is not valid",GetErrorMessage(E_INVALID_ARG));
\r
138 av_init_packet(&inputPacket);
140 // check this routines is required
141 for (int i = 0; i < srcBufSize - 1; i++)
143 if ((pSrcBuf[i] == 0xff) && ((pSrcBuf[i + 1] == 0xfb) || (pSrcBuf[i + 1] == 0xf3)))
146 inputPacket.size = srcBufSize - i;
147 inputPacket.data = (uint8_t*)pSrcBuf + i;
153 SysTryCatch(NID_MEDIA, hasSyncBits, r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
154 "[%s] The input data format is not supported ",GetErrorMessage(E_UNSUPPORTED_FORMAT));
\r
156 if (dstBufSize >= _MIN_OUT_BUFFER_SIZE)
159 outBufSize = dstBufSize;
164 outBufSize = _MIN_OUT_BUFFER_SIZE;
167 res = avcodec_decode_audio3(__pCodecCtx, (int16_t*)pOutBuf, &outBufSize, &inputPacket);
168 SysTryCatch(NID_MEDIA, (res > 0 && outBufSize > 0), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
169 "[%s] The input data format is not supported ",GetErrorMessage(E_UNSUPPORTED_FORMAT));
\r
171 SysTryCatch(NID_MEDIA, dstBufSize >= outBufSize, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
172 "[%s] Memory Allocation Failed ",GetErrorMessage(E_OUT_OF_MEMORY));
\r
174 dstBufUsed = outBufSize; // the decoded audio data size
175 srcBufUsed = res + srcBytesSkipped; // input bytes used
176 if (pOutBuf != pDstBuf)
178 memcpy(pDstBuf, pOutBuf, outBufSize);
179 __decodeCalled = true;
188 _Mp3Decoder::Probe(const byte* pSrcBuf, const int srcBufSize,
189 AudioSampleType& sampleType, AudioChannelType& channelType, int& sampleRate)
191 result r = E_SUCCESS;
196 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
197 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
\r
198 SysTryCatch(NID_MEDIA, pSrcBuf != null && srcBufSize > 0, r = E_INVALID_ARG, E_INVALID_ARG,
199 "[%s] Invalid argument is used. The argument is not valid",GetErrorMessage(E_INVALID_ARG));
\r
201 r = Decode(pSrcBuf, srcBufSize, srcBufUsed, __pOutBuf, _MIN_OUT_BUFFER_SIZE, dstBufUsed);
203 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Decode failed", GetErrorMessage(r));
205 channelType = _FfmpegUtil::ToAudioChannelType(__pCodecCtx->channels);
206 sampleType = _FfmpegUtil::ToAudioSampleType(__pCodecCtx->sample_fmt);
207 sampleRate = __pCodecCtx->sample_rate;
209 SetLastResult(E_SUCCESS);
217 _Mp3Decoder::Reset(void)
219 result r = E_SUCCESS;
221 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
222 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
\r
224 avcodec_flush_buffers(__pCodecCtx);
226 __decodeCalled = false;
227 SetLastResult(E_SUCCESS);
235 _Mp3Decoder::GetValue(MediaPropertyType type, int& value) const
237 result r = E_SUCCESS;
239 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
240 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
\r
241 SysTryCatch(NID_MEDIA, type > 0, r = E_INVALID_ARG, E_INVALID_ARG,
242 "[%s] Invalid argument is used. The argument is not valid",GetErrorMessage(E_INVALID_ARG));
\r
243 SysTryCatch(NID_MEDIA, __decodeCalled, r = E_INVALID_STATE, E_INVALID_STATE,
244 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
\r
248 case MEDIA_PROPERTY_AUDIO_CHANNEL_TYPE:
249 value = _FfmpegUtil::ToAudioChannelType(__pCodecCtx->channels);
252 case MEDIA_PROPERTY_AUDIO_SAMPLE_TYPE:
253 value = _FfmpegUtil::ToAudioSampleType(__pCodecCtx->sample_fmt);
256 case MEDIA_PROPERTY_AUDIO_SAMPLE_RATE:
257 value = __pCodecCtx->sample_rate;
260 case MEDIA_PROPERTY_AUDIO_BIT_RATE:
261 value = __pCodecCtx->bit_rate;
276 _Mp3Decoder::GetValue(MediaPropertyType type, float& value) const
278 result r = E_SUCCESS;
279 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
280 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
\r
281 SysTryCatch(NID_MEDIA, type > 0, r = E_INVALID_ARG, E_INVALID_ARG,
282 "[%s] Invalid argument is used. The argument is not valid",GetErrorMessage(E_INVALID_ARG));
\r
283 SysTryCatch(NID_MEDIA, __decodeCalled, r = E_INVALID_STATE, E_INVALID_STATE,
284 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
\r
286 return E_OBJ_NOT_FOUND;
292 Tizen::Base::Collection::IListT<MediaPropertyType>*
293 _Mp3Decoder::GetSupportedPropertyListN(void) const
295 result r = E_SUCCESS;
296 ArrayListT<MediaPropertyType>* pList = new (std::nothrow) ArrayListT<MediaPropertyType>;
298 SysTryCatch(NID_MEDIA, pList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
299 "[%s] Memory Allocation Failed ",GetErrorMessage(E_OUT_OF_MEMORY));
\r
300 pList->Add(MEDIA_PROPERTY_AUDIO_SAMPLE_RATE);
301 pList->Add(MEDIA_PROPERTY_AUDIO_CHANNEL_TYPE);
302 pList->Add(MEDIA_PROPERTY_AUDIO_SAMPLE_TYPE);
303 pList->Add(MEDIA_PROPERTY_AUDIO_BIT_RATE);
312 _Mp3Decoder::IsPropertySupported(MediaPropertyType type) const
314 result r = E_SUCCESS;
316 SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_INVALID_STATE, E_INVALID_STATE,
317 "[%s] The instance is in invalid state",GetErrorMessage(E_INVALID_STATE));
\r
318 SysTryCatch(NID_MEDIA, type == MEDIA_PROPERTY_AUDIO_SAMPLE_RATE ||
319 type == MEDIA_PROPERTY_AUDIO_CHANNEL_TYPE ||
320 type == MEDIA_PROPERTY_AUDIO_SAMPLE_TYPE ||
321 type == MEDIA_PROPERTY_AUDIO_BIT_RATE,
322 r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
323 "[%s] The instance is not available ",GetErrorMessage(E_OBJ_NOT_FOUND));
\r