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 * @file FMedia_VideoFrameExtractorImpl.cpp
20 * @brief This file contains the implementation of VideoFrameExtractor's impl layer.
24 #include <unique_ptr.h>
25 #include <FMediaImageUtil.h>
26 #include <FBaseSysLog.h>
27 #include <metadata_extractor.h>
28 #include "FMedia_VideoFrameExtractorImpl.h"
29 #include "FMedia_ColorConverter.h"
32 using namespace Tizen::Base;
33 using namespace Tizen::Graphics;
35 namespace Tizen { namespace Media {
37 _VideoFrameExtractorImpl::_VideoFrameExtractorImpl(void)
39 , __pixelFormat(MEDIA_PIXEL_FORMAT_NONE)
46 _VideoFrameExtractorImpl::~_VideoFrameExtractorImpl(void)
48 if (__extractor != null)
50 metadata_extractor_destroy(__extractor);
56 _VideoFrameExtractorImpl*
57 _VideoFrameExtractorImpl::GetInstance(VideoFrameExtractor *pVideoFrameExtractor)
59 if (pVideoFrameExtractor != null)
61 return pVideoFrameExtractor->__pImpl;
66 const _VideoFrameExtractorImpl*
67 _VideoFrameExtractorImpl::GetInstance(const VideoFrameExtractor *pVideoFrameExtractor)
69 if (pVideoFrameExtractor != null)
71 return pVideoFrameExtractor->__pImpl;
77 _VideoFrameExtractorImpl::Construct(const Tizen::Base::String &filePath, MediaPixelFormat pixelFormat)
81 std::unique_ptr<char[]> pPath;
84 SysAssertf(__extractor == null,
85 "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
87 ret = metadata_extractor_create(&__extractor);
88 TryCatch(ret == METADATA_EXTRACTOR_ERROR_NONE, r = ToResult(ret), "metadata_extractor_create:%d", ret);
90 SysTryReturn(NID_MEDIA, !filePath.IsEmpty(), E_FILE_NOT_FOUND, E_FILE_NOT_FOUND,
91 "[E_FILE_NOT_FOUND] path is empty");
93 SysTryReturn(NID_MEDIA, Tizen::Io::File::IsFileExist(filePath), E_FILE_NOT_FOUND, E_FILE_NOT_FOUND,
94 "[E_FILE_NOT_FOUND] File is not Found: %ls",filePath.GetPointer());
96 SysTryReturn(NID_MEDIA, pixelFormat > MEDIA_PIXEL_FORMAT_NONE && pixelFormat < MEDIA_PIXEL_FORMAT_GRAY,
97 E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Pixel format (%d) is invalid.", pixelFormat);
99 __pixelFormat = pixelFormat;
101 length = filePath.GetLength();
102 pPath.reset(new (std::nothrow) char[length + 2]);
104 SysTryReturn(NID_MEDIA, pPath.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
105 "[%s] Propagating. ", GetErrorMessage(GetLastResult()));
107 snprintf(pPath.get(), length+2, "%ls", filePath.GetPointer());
109 ret = metadata_extractor_set_path(__extractor, pPath.get());
110 TryCatch(ret == METADATA_EXTRACTOR_ERROR_NONE, r = ToResult(ret), "metadata_extractor_set_path:%d", ret);
112 r = GetMetaDataValue(__extractor, METADATA_VIDEO_WIDTH, __width);
113 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
115 r = GetMetaDataValue(__extractor, METADATA_VIDEO_HEIGHT, __height);
116 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
120 r = GetMetaDataValue(__extractor, METADATA_DURATION, val);
121 TryCatch(r == E_SUCCESS, , "[%s] Propagating.", GetErrorMessage(r));
130 _VideoFrameExtractorImpl::GetWidth(void) const
136 _VideoFrameExtractorImpl::GetHeight(void) const
142 _VideoFrameExtractorImpl::GetDuration(void) const
148 _VideoFrameExtractorImpl::GetFrameN(long timestamp)
150 result r = E_SUCCESS;
154 std::unique_ptr <byte[]> pBuf;
158 ImageBuffer* pImgBuf = null;
161 TryCatch(timestamp < __duration, r = E_OUT_OF_RANGE,
162 "[%s] Propagating.",GetErrorMessage(E_OUT_OF_RANGE));
164 ret = metadata_extractor_get_frame_at_time(__extractor, timestamp, false, &pFrame, &frameSize );
166 TryCatch(ret == METADATA_EXTRACTOR_ERROR_NONE, r = ToResult(ret),
167 "[%s] Propagating.",GetErrorMessage(ToResult(ret)));
169 TryCatch(pFrame != null && frameSize > 0, r = E_OPERATION_FAILED,
170 "[%s] Propagating.",GetErrorMessage(E_OPERATION_FAILED));
172 pImgBuf = new (std::nothrow) ImageBuffer();
173 TryCatch(pImgBuf != null, r = E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
175 r = cvt.Construct(MEDIA_PIXEL_FORMAT_RGB888, __width, __height, __pixelFormat, __width, __height);
176 TryCatch(r == E_SUCCESS, delete pImgBuf; pImgBuf = null, "[%s] Color conversion failed.", GetErrorMessage(r));
178 pBuf.reset(cvt.ConvertN((byte*)pFrame, frameSize, bufLength));
180 TryCatch((r == E_SUCCESS) && (pBuf.get() != null) && (bufLength > 0), delete pImgBuf; pImgBuf = null,
181 "[%s] Color conversion failed.", GetErrorMessage(r));
183 r = pImgBuf->Construct(__width, __height, __pixelFormat, pBuf.get(), bufLength);
184 TryCatch(r == E_SUCCESS, delete pImgBuf; pImgBuf = null,
185 "[%s] Color conversion failed.", GetErrorMessage(r));
200 _VideoFrameExtractorImpl::GetFrameN(const Tizen::Base::String& filePath, MediaPixelFormat pixelFormat, long timestamp)
202 result r = E_SUCCESS;
203 ImageBuffer* pImgBuf = null;
205 std::unique_ptr <_VideoFrameExtractorImpl> pImpl(new _VideoFrameExtractorImpl());
206 TryCatch(pImpl.get() != null, r = E_OUT_OF_MEMORY,
207 "[%s] Propagating. ", GetErrorMessage(GetLastResult()));
209 r = (pImpl.get())->Construct(filePath, pixelFormat);
210 TryCatch(r == E_SUCCESS, , "[%s] Failed to Construct pImpl", GetErrorMessage(r));
212 pImgBuf = (pImpl.get())->GetFrameN(timestamp);
213 TryCatch(pImgBuf != null, r = GetLastResult(), "[%s] Propagating", GetErrorMessage(r));
221 _VideoFrameExtractorImpl::ToResult(int ret)
228 { METADATA_EXTRACTOR_ERROR_NONE, E_SUCCESS },
229 { METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER, E_INVALID_ARG },
230 { METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY },
231 { METADATA_EXTRACTOR_ERROR_FILE_EXISTS, E_FILE_NOT_FOUND },
232 { METADATA_EXTRACTOR_ERROR_OPERATION_FAILED, E_UNSUPPORTED_FORMAT },
235 for (unsigned int index = 0; index < sizeof(errorMap) / sizeof(errorMap[0]); index++)
237 if (errorMap[index].slpError == ret)
239 return errorMap[index].ospError;
247 _VideoFrameExtractorImpl::GetMetaDataValue(struct metadata_extractor_s*& extractor,int key, int &value)
249 char* pOutStr = null;
250 result r = E_SUCCESS;
253 ret = metadata_extractor_get_metadata(extractor, (metadata_extractor_attr_e)key, &pOutStr);
254 TryCatch(ret == METADATA_EXTRACTOR_ERROR_NONE, r = ToResult(ret), "[%s] Propagating .", GetErrorMessage(ToResult(ret)));
256 value = atoi(pOutStr);