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