Merge "seek expection handling bug" into tizen_2.2
[platform/framework/native/media.git] / src / FMedia_H263Encoder.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 <stdio.h>
20 #include <FBaseColArrayListT.h>
21 #include <FBaseColHashMap.h>
22 #include <FBaseInteger.h>
23 #include <FMediaTypes.h>
24 #include <FBaseSysLog.h>
25 #include "FMedia_Ffmpeg.h"
26 #include "FMedia_IVideoEncoder.h"
27 #include "FMedia_H263Encoder.h"
28
29 using namespace std;
30 using namespace Tizen::Base;
31 using namespace Tizen::Io;
32 using namespace Tizen::Base::Collection;
33
34 namespace Tizen { namespace Media
35 {
36
37 _IVideoEncoder*
38 _H263Encoder_CreateInstance(void)
39 {
40         return new (std::nothrow) _H263Encoder();
41 }
42
43 _H263Encoder::_H263Encoder(void)
44 {
45         __pCodecCtx = null;
46         __pCodec = null;
47         __pFrame = null;
48         __firstFrame = true;
49 }
50
51 _H263Encoder::~_H263Encoder(void)
52 {
53         if (__pCodecCtx != null)
54         {
55                 avcodec_close(__pCodecCtx);
56                 av_free(__pCodecCtx);
57                 __pCodecCtx = null;
58                 __pCodec = null;
59         }
60
61         if (__pFrame != null)
62         {
63                 av_free(__pFrame);
64         }
65 }
66
67 result
68 _H263Encoder::Construct(const Tizen::Base::Collection::HashMap* pOption)
69 {
70         result r = E_SUCCESS;
71         int res = 0;
72         Integer* pKey = null;
73         Integer* pValue = null;
74         int key = -1;
75         int value = -1;
76
77         SysTryReturnResult(NID_MEDIA, __pCodecCtx == null, E_INVALID_STATE, "already constructed");
78
79         av_log_set_level (AV_LOG_QUIET);
80         avcodec_register_all();
81
82         __pCodec = avcodec_find_encoder(CODEC_ID_H263P);
83         SysTryCatch(NID_MEDIA, __pCodec != null, r = E_SYSTEM, E_SYSTEM, "[%s] Failed to get avcodec encoder",GetErrorMessage(E_SYSTEM));
84
85         __pCodecCtx = avcodec_alloc_context3(__pCodec);
86         SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_SYSTEM, E_SYSTEM,
87                            "[%s] Failed to allocate avcodec context", GetErrorMessage(E_SYSTEM));
88
89         __pCodecCtx->bit_rate = BITRATE_IN_BITS;
90         __pCodecCtx->width = WIDTH;
91         __pCodecCtx->height = HEIGHT;
92         __pCodecCtx->time_base.den = 15;
93         __pCodecCtx->time_base.num = 1;
94         __pCodecCtx->gop_size = GOP ;
95         __pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
96         __pCodecCtx->thread_count = 1;
97         __pCodecCtx->max_b_frames = 0;
98
99         __pCodecCtx->qmin = MIN_QP;
100         __pCodecCtx->qmax = MAX_QP;
101         __pCodecCtx->mpeg_quant = 0;
102         __pCodecCtx->profile = 0;
103         __pCodecCtx->mb_decision = FF_MB_DECISION_BITS;
104         if (pOption != null)
105         {
106         // The initialization values are given in the Hashmap
107         unique_ptr<IMapEnumerator> pMapEnum(pOption->GetMapEnumeratorN());
108         SysTryCatch(NID_MEDIA, pMapEnum.get() != null, r = E_SYSTEM, E_SYSTEM, "Propagating");
109
110         while (pMapEnum->MoveNext() == E_SUCCESS)
111         {
112                 pKey = dynamic_cast<Integer*> (pMapEnum->GetKey());
113                 pValue = dynamic_cast<Integer*> (pMapEnum->GetValue());
114
115                 if (pKey == null || pValue == null)
116                 {
117                         continue;
118                 }
119
120                 key = pKey->ToInt();
121                 value = pValue->ToInt();
122
123
124                 switch (key)
125                 {
126                 case MEDIA_PROPERTY_VIDEO_WIDTH:
127                         SysTryCatch(NID_MEDIA, value > 0, r = E_INVALID_ARG, E_INVALID_ARG,
128                                            "[%s] Invalid argument is used: width %d", GetErrorMessage(E_INVALID_ARG), value);
129                         __pCodecCtx->width = value;
130                         break;
131
132                 case MEDIA_PROPERTY_VIDEO_HEIGHT:
133                         SysTryCatch(NID_MEDIA, value > 0, r = E_INVALID_ARG, E_INVALID_ARG,
134                                            "[%s] Invalid argument is used: height %d", GetErrorMessage(E_INVALID_ARG), value);
135                         __pCodecCtx->height = value;
136                         break;
137
138                 case MEDIA_PROPERTY_VIDEO_FRAME_RATE:
139                         SysTryCatch(NID_MEDIA, value > 0, r = E_INVALID_ARG, E_INVALID_ARG,
140                                            "[%s] Invalid argument is used: frameRate %d", GetErrorMessage(E_INVALID_ARG), value);
141                         __pCodecCtx->time_base.den = value;
142                         __pCodecCtx->time_base.num = 1;
143                         break;
144
145                 case MEDIA_PROPERTY_VIDEO_PIXEL_FORMAT:
146                         SysTryCatch(NID_MEDIA, value == MEDIA_PIXEL_FORMAT_YUV420P,
147                                            r = E_INVALID_ARG, E_INVALID_ARG,
148                                            "[%s] Invalid argument is used: pixelFormat %d", GetErrorMessage(E_INVALID_ARG), value);
149                         __pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
150                         break;
151
152                 case MEDIA_PROPERTY_VIDEO_BIT_RATE:
153                         SysTryCatch(NID_MEDIA, value >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
154                                            "[%s] Invalid argument is used: bitRate %d", GetErrorMessage(E_INVALID_ARG), value);
155                         __pCodecCtx->bit_rate = value;
156                         break;
157
158                 case MEDIA_PROPERTY_VIDEO_QUANTIZATION_MIN :
159                         SysTryCatch(NID_MEDIA, value >= MIN_QP && value <= MAX_QP,
160                                            r = E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used: quantization min %d", GetErrorMessage(E_INVALID_ARG), value);
161                         __pCodecCtx->qmin = value;
162                         break;
163
164                 case MEDIA_PROPERTY_VIDEO_QUANTIZATION_MAX :
165                         SysTryCatch(NID_MEDIA, value >= MIN_QP && value <= MAX_QP,
166                                            r = E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used: quantization max %d", GetErrorMessage(E_INVALID_ARG), value);
167                         __pCodecCtx->qmax = value;
168                         break;
169
170                 case MEDIA_PROPERTY_VIDEO_GOP_SIZE :
171                         SysTryCatch(NID_MEDIA, value  >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
172                                            "[%s] Invalid argument is used: gop size %d", GetErrorMessage(E_INVALID_ARG), value);
173                         __pCodecCtx->gop_size = value;
174                         break;
175
176                 case MEDIA_PROPERTY_VIDEO_PROFILE:
177                         SysTryCatch(NID_MEDIA, value  == 0 || value == 3, r = E_INVALID_ARG, E_INVALID_ARG,
178                                            "[%s] Invalid argument is used: video profile %d", GetErrorMessage(E_INVALID_ARG), value);
179                         __pCodecCtx->profile = value;
180                         break;
181
182                 case MEDIA_PROPERTY_VIDEO_SLICE_SIZE_IN_BYTE:
183                         SysTryCatch(NID_MEDIA, value >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
184                                            "[%s] Invalid argument is used: slice size %d", GetErrorMessage(E_INVALID_ARG), value);
185                         __pCodecCtx->rtp_payload_size = value;
186                         break;
187
188                 case MEDIA_PROPERTY_VIDEO_QUANTIZATION_PARAMETER :
189                         SysTryCatch(NID_MEDIA, value >= MIN_QP && value <= MAX_QP,
190                                            r = E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used: quantization max %d", GetErrorMessage(E_INVALID_ARG), value);
191                         break;
192
193                 case MEDIA_PROPERTY_VIDEO_GOB_SIZE :
194                 SysTryCatch(NID_MEDIA, value > 0 && value <= __pCodecCtx->height/16, r = E_INVALID_ARG, E_INVALID_ARG,
195                                            "[%s] Invalid argument is used: gob size %d", GetErrorMessage(E_INVALID_ARG), value);
196                         break;
197
198                 case MEDIA_PROPERTY_VIDEO_USE_AC_PREDICTION :
199                 SysTryCatch(NID_MEDIA, value == 0 || value == 1, r = E_INVALID_ARG, E_INVALID_ARG,
200                                            "[%s] Invalid argument is used: ac prediction setting  %d", GetErrorMessage(E_INVALID_ARG), value);
201                         break;
202
203                 case MEDIA_PROPERTY_VIDEO_USE_HEADER_EXTENSION_CODE :
204                 SysTryCatch(NID_MEDIA, value == 0 || value == 1, r = E_INVALID_ARG, E_INVALID_ARG,
205                                            "[%s] Invalid argument is used: header extension code %d", GetErrorMessage(E_INVALID_ARG), value);
206                         break;
207
208                 case MEDIA_PROPERTY_VIDEO_USE_FRAME_SKIP:
209                 SysTryCatch(NID_MEDIA, value == 0 || value == 1, r = E_INVALID_ARG, E_INVALID_ARG,
210                                            "[%s] Invalid argument is used: frame skip setting %d", GetErrorMessage(E_INVALID_ARG), value);
211                         break;
212
213                 default:
214                         break;
215                 }
216         }
217         }
218
219         res = avcodec_open2(__pCodecCtx, __pCodec, null);
220         SysTryCatch(NID_MEDIA, res >= 0, r = E_SYSTEM, E_SYSTEM,
221                            "[%s] avcodec open failed %d ", GetErrorMessage(E_SYSTEM), res);
222
223         __pFrame = avcodec_alloc_frame();
224         SysTryCatch(NID_MEDIA, __pFrame != null, r = E_SYSTEM, E_SYSTEM, "[%s] avcodec alloc frame failed", GetErrorMessage(E_SYSTEM));
225
226         for (int i = 0; i < 4; i++)
227         {
228                 __pFrame->data[i] = null;
229                 __pFrame->linesize[i] = 0;
230         }
231         __firstFrame = true;
232
233         return r;
234
235 CATCH:
236
237         if (__pCodecCtx != null)
238         {
239                 avcodec_close(__pCodecCtx);
240                 av_free(__pCodecCtx);
241                 __pCodecCtx = null;
242                 __pCodec = null;
243         }
244         return r;
245 }
246
247
248 result
249 _H263Encoder::Encode(const byte* srcBuf, int& srcBufLength, byte*& dstBuf, int& dstBufLength)
250 {
251         result r = E_SUCCESS;
252         int res = 0;
253         int outIndex = 0;
254         int minSrcBufLength = 0;
255         int gotOutput = 0;
256         unique_ptr<AVPacket, _FfmpegDeleter> pPkt(null, ffmpegDeleter);
257
258         SysTryReturnResult(NID_MEDIA, __pCodecCtx, E_INVALID_STATE, "not constructed");
259
260         minSrcBufLength = __pCodecCtx->width * __pCodecCtx->height * 3 / 2;
261         SysTryCatch(NID_MEDIA, (srcBuf != null && dstBuf != null && srcBufLength >= minSrcBufLength
262                                                    && dstBufLength >= FF_MIN_BUFFER_SIZE),
263                            r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
264                            "[%s] Invalid argument is used. 0x%x %d %d 0x%x %d %d",
265                            GetErrorMessage(E_OUT_OF_MEMORY), srcBuf, srcBufLength, minSrcBufLength, dstBuf, dstBufLength, FF_MIN_BUFFER_SIZE);
266
267         __pFrame->data[0] = (uint8_t*)srcBuf;
268         __pFrame->data[1] = (uint8_t*)srcBuf + __pCodecCtx->width * __pCodecCtx->height;
269         __pFrame->data[2] = (uint8_t*)srcBuf + __pCodecCtx->width * __pCodecCtx->height * 5 / 4;
270         __pFrame->linesize[0] = __pCodecCtx->width;
271         __pFrame->linesize[1] = __pCodecCtx->width / 2;
272         __pFrame->linesize[2] = __pCodecCtx->width / 2;
273
274         pPkt.reset(new (std::nothrow) AVPacket);
275         SysTryReturnResult(NID_MEDIA, pPkt.get() != null, E_OUT_OF_MEMORY, "new AVPacket failed.");
276         av_init_packet(pPkt.get());
277         pPkt->data = NULL;    // packet data will be allocated by the encoder
278         pPkt->size = 0;
279 #if 0
280         res = avcodec_encode_video(__pCodecCtx, (uint8_t*) dstBuf+outIndex, dstBufLength, __pFrame);
281         SysTryCatch(NID_MEDIA, res >= 0, r = E_SYSTEM, E_SYSTEM, "[%s] H263 Video Encode Failed %d", GetErrorMessage(E_SYSTEM), res);
282         srcBufLength = minSrcBufLength;
283         dstBufLength = res + outIndex;
284 #endif
285
286         __pFrame->pts++;
287
288         res = avcodec_encode_video2(__pCodecCtx, pPkt.get(), __pFrame, &gotOutput);
289         SysTryCatch(NID_MEDIA, res >= 0, r = E_SYSTEM, E_SYSTEM, "[%s] Video Encode Failed %d", GetErrorMessage(E_SYSTEM), res);
290
291         if (gotOutput)
292         {
293                 SysTryCatch(NID_MEDIA, pPkt->size <= dstBufLength, r = E_INVALID_ARG, E_INVALID_ARG,
294                                         "[%s] dst buffer is insufficient:%d %d", GetErrorMessage(E_INVALID_ARG), dstBufLength, pPkt->size);
295                 memcpy(dstBuf+outIndex, pPkt->data, pPkt->size);
296                 srcBufLength = minSrcBufLength;
297                 dstBufLength = pPkt->size + outIndex;
298         }
299         else
300         {
301                 srcBufLength = minSrcBufLength;
302                 dstBufLength = outIndex;
303         }
304
305 CATCH:
306         return r;
307 }
308
309
310 result
311 _H263Encoder::Reset(void)
312 {
313         result r = E_SUCCESS;
314
315         SysTryReturnResult(NID_MEDIA, __pCodecCtx, E_INVALID_STATE, "not constructed");
316         avcodec_flush_buffers(__pCodecCtx);
317         return r;
318 }
319
320 result
321 _H263Encoder::SetValue(MediaPropertyType type, int value)
322 {
323         result r = E_SUCCESS;
324
325         SysTryReturnResult(NID_MEDIA, __pCodecCtx, E_INVALID_STATE, "not constructed");
326         SysTryCatch(NID_MEDIA, value >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
327                            "[E_INVALID_ARG] Invalid argument is used. type:%d", GetErrorMessage(E_INVALID_ARG), type);
328         SysTryCatch(NID_MEDIA, type > 0, r = E_INVALID_ARG, E_INVALID_ARG,
329                            "[E_INVALID_ARG] Invalid argument is used. type:%d", GetErrorMessage(E_INVALID_ARG), type);
330         SysTryCatch(NID_MEDIA, type >= MEDIA_PROPERTY_VIDEO_WIDTH && type <= MEDIA_PROPERTY_AUDIO_SAMPLE_RATE,
331                            r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found. type:%d", GetErrorMessage(E_OBJ_NOT_FOUND), type);
332
333         switch (type)
334         {
335         case MEDIA_PROPERTY_VIDEO_WIDTH:
336         SysTryCatch(NID_MEDIA, value <= MAX_WIDTH, r = E_INVALID_ARG, E_INVALID_ARG,
337                            "[%s] Invalid argument is used. type:%d", GetErrorMessage(E_INVALID_ARG), type);
338                 __pCodecCtx->width = value;
339         break;
340
341         case MEDIA_PROPERTY_VIDEO_HEIGHT:
342         SysTryCatch(NID_MEDIA, value <= MAX_HEIGHT, r = E_INVALID_ARG, E_INVALID_ARG,
343                            "[%s] Invalid argument is used. type:%d", GetErrorMessage(E_INVALID_ARG), type);
344                 __pCodecCtx->height = value;
345         break;
346
347         case MEDIA_PROPERTY_VIDEO_PIXEL_FORMAT:
348                 __pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
349                 break;
350
351         case MEDIA_PROPERTY_VIDEO_FRAME_RATE:
352                 __pCodecCtx->time_base.den = 15;
353                 __pCodecCtx->time_base.num = 1;
354                 break;
355
356         case MEDIA_PROPERTY_VIDEO_BIT_RATE:
357                 __pCodecCtx->bit_rate = value;
358                 break;
359
360         case MEDIA_PROPERTY_VIDEO_QUANTIZATION_PARAMETER :
361                 __pCodecCtx->mpeg_quant = value;
362         break;
363
364         case MEDIA_PROPERTY_VIDEO_QUANTIZATION_MIN :
365                 __pCodecCtx->qmin = value;
366                 break;
367
368         case MEDIA_PROPERTY_VIDEO_QUANTIZATION_MAX :
369                 __pCodecCtx->qmax = value;
370                 break;
371
372         case MEDIA_PROPERTY_VIDEO_GOP_SIZE :
373                 __pCodecCtx->gop_size = value;
374                 break;
375
376         case MEDIA_PROPERTY_VIDEO_SLICE_SIZE_IN_BYTE  :
377                 __pCodecCtx->rtp_payload_size = value;
378                 break ;
379         default:
380                 return E_OBJ_NOT_FOUND;
381         break;
382         }
383         return r;
384
385 CATCH:
386         return r;
387 }
388
389 result
390 _H263Encoder::SetValue(MediaPropertyType type, bool value)
391 {
392         result r = E_SUCCESS;
393
394         SysTryReturnResult(NID_MEDIA, __pCodecCtx, E_INVALID_STATE, "not constructed");
395         SysTryCatch(NID_MEDIA, type>0, r = E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used",GetErrorMessage(E_INVALID_ARG));
396         SysTryCatch(NID_MEDIA, value == 0 || value == 1, r = E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used.",GetErrorMessage(E_INVALID_ARG));
397         SysTryCatch(NID_MEDIA, type >= MEDIA_PROPERTY_VIDEO_WIDTH || type <= MEDIA_PROPERTY_AUDIO_SAMPLE_RATE,
398                            r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] Object not found", GetErrorMessage(E_OBJ_NOT_FOUND));
399         switch (type)
400         {
401         case MEDIA_PROPERTY_VIDEO_FORCE_SKIP_FRAME:
402                 __pCodecCtx->skip_frame = AVDISCARD_DEFAULT;
403         break;
404
405         case MEDIA_PROPERTY_VIDEO_FORCE_INTRA_CODING:
406                 __pCodecCtx->skip_idct = AVDISCARD_DEFAULT;
407         break;
408
409         default:
410                 return E_OBJ_NOT_FOUND;
411         break;
412         }
413
414
415         return r;
416
417 CATCH:
418         return r;
419 }
420
421 Tizen::Base::Collection::IListT<MediaPropertyType>*
422 _H263Encoder::GetSupportedPropertyListN(void) const
423 {
424         result r = E_SUCCESS;
425         ArrayListT<MediaPropertyType>* pPropList = new (std::nothrow) ArrayListT<MediaPropertyType>;
426
427         SysTryCatch(NID_MEDIA, pPropList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
428                            "[%s] Memory allocation failed",GetErrorMessage(E_OUT_OF_MEMORY));
429         pPropList->Add(MEDIA_PROPERTY_VIDEO_WIDTH);
430         pPropList->Add(MEDIA_PROPERTY_VIDEO_HEIGHT);
431         pPropList->Add(MEDIA_PROPERTY_VIDEO_PIXEL_FORMAT);
432         pPropList->Add(MEDIA_PROPERTY_VIDEO_FRAME_RATE);
433         pPropList->Add(MEDIA_PROPERTY_VIDEO_BIT_RATE);
434         pPropList->Add(MEDIA_PROPERTY_VIDEO_QUANTIZATION_PARAMETER);
435         pPropList->Add( MEDIA_PROPERTY_VIDEO_QUANTIZATION_MAX);
436         pPropList->Add(MEDIA_PROPERTY_VIDEO_QUANTIZATION_MIN);
437         pPropList->Add(MEDIA_PROPERTY_VIDEO_GOP_SIZE);
438         pPropList->Add(MEDIA_PROPERTY_VIDEO_PROFILE);
439         pPropList->Add(MEDIA_PROPERTY_VIDEO_USE_FRAME_SKIP);
440         pPropList->Add(MEDIA_PROPERTY_VIDEO_GOB_SIZE);
441         pPropList->Add(MEDIA_PROPERTY_VIDEO_SLICE_SIZE_IN_BYTE);
442         pPropList->Add(MEDIA_PROPERTY_VIDEO_FORCE_SKIP_FRAME);
443         pPropList->Add(MEDIA_PROPERTY_VIDEO_FORCE_INTRA_CODING);
444
445         SetLastResult(r);
446         return pPropList;
447
448 CATCH:
449         return null;
450 }
451
452 bool
453 _H263Encoder::IsPropertySupported(MediaPropertyType type) const
454 {
455         result r = E_SUCCESS;
456
457         SysTryReturn(NID_MEDIA, __pCodecCtx, false, E_INVALID_STATE, "[E_INVALID_STATE] not constructed");
458         SysTryCatch(NID_MEDIA, ( type == MEDIA_PROPERTY_VIDEO_WIDTH || type == MEDIA_PROPERTY_VIDEO_HEIGHT
459                                                         || type == MEDIA_PROPERTY_VIDEO_PIXEL_FORMAT || type == MEDIA_PROPERTY_VIDEO_FRAME_RATE
460                         || type == MEDIA_PROPERTY_VIDEO_BIT_RATE || type == MEDIA_PROPERTY_VIDEO_QUANTIZATION_PARAMETER || type ==
461                         MEDIA_PROPERTY_VIDEO_QUANTIZATION_MIN || type == MEDIA_PROPERTY_VIDEO_QUANTIZATION_MAX || type == MEDIA_PROPERTY_VIDEO_GOP_SIZE || type ==
462                         MEDIA_PROPERTY_VIDEO_PROFILE || type ==  MEDIA_PROPERTY_VIDEO_USE_FRAME_SKIP || type ==  MEDIA_PROPERTY_VIDEO_GOB_SIZE || type ==
463                         MEDIA_PROPERTY_VIDEO_SLICE_SIZE_IN_BYTE || type ==  MEDIA_PROPERTY_VIDEO_FORCE_SKIP_FRAME || type ==  MEDIA_PROPERTY_VIDEO_FORCE_INTRA_CODING),
464                            r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
465                            "[%s] Object not found %d", GetErrorMessage(E_OBJ_NOT_FOUND), type);
466         SetLastResult(r);
467         return true;
468
469 CATCH:
470         return false;
471 }
472
473 }} // Tizen::Media