Tizen 2.0 Release
[framework/osp/media.git] / src / FMedia_AmrEncoder.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 #include <unique_ptr.h>
19 #include <interf_enc.h>
20 #include <FBaseColHashMap.h>
21 #include <FBaseInteger.h>
22 #include <FMediaTypes.h>
23 #include <FMediaAudioTypes.h>
24 #include <FBaseSysLog.h>
25 #include "FMedia_AmrEncoder.h"
26
27 using namespace Tizen::Base;
28 using namespace Tizen::Io;
29 using namespace Tizen::Base::Collection;
30
31
32 namespace Tizen { namespace Media
33 {
34
35 _IAudioEncoder*
36 _AmrEncoder_CreateInstance(void)
37 {
38         return new (std::nothrow) _AmrEncoder();
39 }
40
41 _AmrEncoder::_AmrEncoder(void)
42 {
43         __pEnc = null;
44         __encBitrate = MR122;
45         __frameCount = 0;
46 }
47
48 _AmrEncoder::~_AmrEncoder(void)
49 {
50         if (__pEnc != null)
51         {
52                 Encoder_Interface_exit(__pEnc);
53                 __pEnc = null;
54         }
55 }
56
57 result
58 _AmrEncoder::Construct(const Tizen::Base::Collection::HashMap* pOption)
59 {
60         result r = E_SUCCESS;
61         Integer* pKey = null;
62         Integer* pValue = null;
63         int key = -1;
64         int value = -1;
65
66         SysTryReturnResult(NID_MEDIA, __pEnc == null, E_INVALID_STATE, "already constructed");
67
68         if (pOption != null)
69         {
70                 // The initialization values are given in the Hashmap
71                 std::unique_ptr<IMapEnumerator> pMapEnum(pOption->GetMapEnumeratorN());
72                 if (pMapEnum.get() != null)
73                 {
74                         while (pMapEnum.get()->MoveNext() == E_SUCCESS)
75                         {
76                                 pKey = static_cast<Integer*>(pMapEnum.get()->GetKey());
77                                 pValue = static_cast<Integer*>(pMapEnum.get()->GetValue());
78
79                                 if (pKey != null && pValue != null)
80                                 {
81                                         key = pKey->ToInt();
82                                         value = pValue->ToInt();
83
84                                         switch (key)
85                                         {
86                                         case MEDIA_PROPERTY_AUDIO_CHANNEL_TYPE:
87                                                 SysTryCatch(NID_MEDIA, value == AUDIO_CHANNEL_TYPE_MONO || value == AUDIO_CHANNEL_TYPE_STEREO,
88                                                                    r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
89                                                                    "[%s] Audio Channel Type is out of range :%d", GetErrorMessage(E_OUT_OF_RANGE), value);
90                                                 break;
91
92                                         case MEDIA_PROPERTY_AUDIO_SAMPLE_RATE:
93                                                 SysTryCatch(NID_MEDIA, value == 8000, r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
94                                                                    "[%s] Audio sampleRate is out of range :%d", GetErrorMessage(E_OUT_OF_RANGE), value);
95                                                 break;
96
97                                         case MEDIA_PROPERTY_AUDIO_BIT_RATE:
98                                                 SysTryCatch(NID_MEDIA, (value > 0), r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
99                                                                    "[%s] Audio bitrate is out of range :%d", GetErrorMessage(E_OUT_OF_RANGE), value);
100                                                 __encBitrate = GetBitrateMode(value);
101                                                 SysTryCatch(NID_MEDIA, __encBitrate >= 0, r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
102                                                                    "[%s] Audio bitrate is out of range %d %d", GetErrorMessage(E_OUT_OF_RANGE), value, __encBitrate);
103                                                 break;
104
105                                         default:
106                                                 break;
107                                         }
108                                 }
109                         }
110
111                 }
112         }
113         //intialising using opencore amr
114         __pEnc = Encoder_Interface_init(0);
115         SysTryCatch(NID_MEDIA, __pEnc != null, r = E_SYSTEM, E_SYSTEM,
116                            "[%s] Encoder init failed", GetErrorMessage(E_SYSTEM));
117
118         return r;
119
120 CATCH:
121
122         if (__pEnc != null)
123         {
124                 Encoder_Interface_exit(__pEnc);
125                 __pEnc = null;
126         }
127         return r;
128 }
129
130 result
131 _AmrEncoder::Encode(const byte* srcBuf, int& srcBufLength, byte*& dstBuf, int& dstBufLength)
132 {
133         result r = E_SUCCESS;
134         int res = 0;
135         byte outBuf[DECODED_FRAME_SIZE];
136         memset(outBuf, 0, sizeof(outBuf));
137         SysTryReturnResult(NID_MEDIA, __pEnc, E_INVALID_STATE, "not constructed");
138
139         //Partial frame encoding is supported by the open core amr_nb library . So no need of checking sourcebuf length.
140         SysTryCatch(NID_MEDIA, srcBuf != null && dstBuf != null
141                            && srcBufLength > 0 && dstBufLength > 0,
142                            r = E_INVALID_ARG, E_INVALID_ARG,
143                            "[E_INVALID_ARG] Invalid argument is used. 0x%x %d 0x%x %d",
144                            srcBuf, srcBufLength, dstBuf, dstBufLength);
145
146         // Encoding the Audio  packet using the amr open core
147         // Accomodating for destinationBuf less than encoded frame size.
148         if (dstBufLength >= DECODED_FRAME_SIZE )
149         {
150                 res = Encoder_Interface_Encode(__pEnc, __encBitrate, (const short*)srcBuf, dstBuf, 0);
151         }
152         else
153         {
154                 res = Encoder_Interface_Encode(__pEnc, __encBitrate, (const short*)srcBuf,(byte*) outBuf, 0);
155         }
156
157         SysTryCatch(NID_MEDIA, res > 0, r = E_SYSTEM, E_SYSTEM,
158                            "[%s] Amr Encoding Failed:%d", GetErrorMessage(E_SYSTEM), res);
159         SysTryCatch(NID_MEDIA, res <= dstBufLength, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
160                            "[%s] Amr Encoding Failed %d %d", GetErrorMessage(E_OUT_OF_MEMORY), res, dstBufLength);
161
162         if (dstBufLength < DECODED_FRAME_SIZE )
163         {
164                 memcpy(dstBuf, outBuf, res);
165         }
166         srcBufLength = DECODED_FRAME_SIZE;
167         dstBufLength = res;
168         return r;
169
170 CATCH:
171         return r;
172 }
173
174 result
175 _AmrEncoder::Reset(void)
176 {
177         result r = E_SUCCESS;
178
179         SysTryReturnResult(NID_MEDIA, __pEnc, E_INVALID_STATE, "not constructed");
180         return r;
181 }
182
183 Mode
184 _AmrEncoder::GetBitrateMode(int bitrate)
185 {
186         // make the correspondance between bitrate and mode
187         static struct _AmrBitRate
188         {
189                 int  key;
190                 Mode value;
191         } map[] = {
192                 { 4750, MR475},
193                 { 5150, MR515},
194                 { 5900, MR59},
195                 { 6700, MR67},
196                 { 7400, MR74},
197                 { 7950, MR795},
198                 {10200, MR102},
199                 {12200, MR122},
200         };
201         Mode mode = MR122;
202
203         for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
204         {
205                 if (map[i].key == bitrate)
206                 {
207                         return map[i].value;
208                 }
209         }
210
211         return mode;
212 }
213
214 }} // Tizen::Media