From: Piotr Kosko
Date: Thu, 1 Oct 2020 06:02:45 +0000 (+0200)
Subject: [Metadata] Aded getFrame method of MetadataFileHandle
X-Git-Tag: submit/tizen/20201209.085808~4
X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=26015ab14532cb05b28ce8bff912e27151ddf06a;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git
[Metadata] Aded getFrame method of MetadataFileHandle
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-271
[Verification] Code compiles withotu errors.
Works well for mp4 video.
var path = "videos/sample_video.mp4";
function showBlob(bbb) {
var elem = document.getElementById("blobImage") || document.createElement("img");
elem.setAttribute("id", "blobImage");
elem.setAttribute("height", "240");
elem.setAttribute("width", "240");
elem.setAttribute("alt", "invalid frame");
document.getElementById("test").appendChild(elem)
var objectURL = URL.createObjectURL(bbb);
elem.src = objectURL;
}
var fileHandle = tizen.metadata.createFileHandle(path);
var frame = fileHandle.getFrame();
console.log(frame);
showBlob(frame)
Change-Id: I2d5e81b19d7f11ff2c08a0096a0b58fb7e3bfc48
---
diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec
index dbad03bd..cebe7f4b 100644
--- a/packaging/webapi-plugins.spec
+++ b/packaging/webapi-plugins.spec
@@ -421,6 +421,9 @@ BuildRequires: pkgconfig(capi-appfw-app-manager)
BuildRequires: pkgconfig(capi-appfw-package-manager)
BuildRequires: pkgconfig(capi-content-media-content)
BuildRequires: pkgconfig(capi-media-metadata-extractor)
+# TODO check support on TV
+BuildRequires: pkgconfig(capi-media-image-util)
+
BuildRequires: pkgconfig(libtzplatform-config)
BuildRequires: pkgconfig(appsvc)
diff --git a/src/metadata/metadata.gyp b/src/metadata/metadata.gyp
index 0f43bf8b..2b999a7d 100644
--- a/src/metadata/metadata.gyp
+++ b/src/metadata/metadata.gyp
@@ -26,6 +26,8 @@
'variables': {
'packages': [
'capi-media-metadata-extractor',
+ # TODO check support on TV
+ 'capi-media-image-util',
]
},
}],
diff --git a/src/metadata/metadata_api.js b/src/metadata/metadata_api.js
index 66a1fa65..8e78bdb9 100755
--- a/src/metadata/metadata_api.js
+++ b/src/metadata/metadata_api.js
@@ -158,5 +158,20 @@ MetadataFileHandle.prototype.getArtwork = function() {
return new Blob([encodedData], { type: resultData.mimeType });
};
+MetadataFileHandle.prototype.getThumbnailFrame = function() {
+ var data = {
+ uri: this.uri,
+ id: this._id
+ };
+
+ var result = native_.callSync('MetadataFileHandleGetThumbnailFrame', data);
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ var encodedData = StringToArray(native_.getResultObject(result), Uint8Array);
+
+ return new Blob([encodedData]);
+};
+
// Exports
exports = new MetadataManager();
diff --git a/src/metadata/metadata_file_handle.cc b/src/metadata/metadata_file_handle.cc
index 1e40e4e5..9a0ce85e 100644
--- a/src/metadata/metadata_file_handle.cc
+++ b/src/metadata/metadata_file_handle.cc
@@ -16,6 +16,8 @@
#include "metadata/metadata_file_handle.h"
+#include
+
#include "common/logger.h"
#include "common/platform_enum.h"
#include "common/platform_exception.h"
@@ -221,5 +223,94 @@ PlatformResult MetadataFileHandle::GetArtwork(std::vector* artwork
return PlatformResult(ErrorCode::NO_ERROR);
}
+// convert frame buffer from raw RGB888 to JPG encoding
+PlatformResult MetadataFileHandle::EncodeJPEG(unsigned char* frame, size_t frame_size,
+ std::uint8_t** uint8_frame, size_t* buffer_size) {
+ ScopeLogger();
+ image_util_type_e encoder_type = IMAGE_UTIL_JPEG;
+ image_util_encode_h encode_handle = nullptr;
+ image_util_image_h image = nullptr;
+ SCOPE_EXIT {
+ image_util_encode_destroy(encode_handle);
+ image_util_destroy_image(image);
+ };
+
+ int ret = image_util_encode_create(encoder_type, &encode_handle);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
+ LoggerE("Error during jpg encoding: %d", ret);
+ return convertErrorCode(ret);
+ }
+
+ char* value = nullptr;
+ int native_res = metadata_extractor_get_metadata(handle_, METADATA_VIDEO_WIDTH, &value);
+ if (METADATA_EXTRACTOR_ERROR_NONE != native_res) {
+ LoggerE("Error during getting metadata: %d", native_res);
+ return convertErrorCode(native_res);
+ }
+ unsigned int width = (unsigned long)atoi(value);
+ free(value);
+ value = nullptr;
+
+ native_res = metadata_extractor_get_metadata(handle_, METADATA_VIDEO_HEIGHT, &value);
+ if (METADATA_EXTRACTOR_ERROR_NONE != native_res) {
+ LoggerE("Error during getting metadata: %d", native_res);
+ return convertErrorCode(native_res);
+ }
+ unsigned int height = (unsigned long)atoi(value);
+ free(value);
+ value = nullptr;
+
+ ret = image_util_create_image(width, height, IMAGE_UTIL_COLORSPACE_RGB888, frame, frame_size,
+ &image);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
+ LoggerE("Error during jpg encoding: %d", ret);
+ return convertErrorCode(ret);
+ }
+
+ unsigned char* jpg_buffer = nullptr;
+ ret = image_util_encode_run_to_buffer(encode_handle, image, &jpg_buffer, buffer_size);
+ if (IMAGE_UTIL_ERROR_NONE != ret) {
+ LoggerE("Error during jpg encoding: %d", ret);
+ return convertErrorCode(ret);
+ }
+
+ // jpg_buffer is passed outside function and need to be released after usage
+ *uint8_frame = (std::uint8_t*)jpg_buffer;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult MetadataFileHandle::GetFrame(std::vector* frame_array) {
+ ScopeLogger();
+ int size = 0;
+ size_t buffer_size = 0;
+ void* frame = nullptr;
+ char* mime_type = nullptr;
+ std::uint8_t* uint8_frame = nullptr;
+ SCOPE_EXIT {
+ free(frame);
+ free(mime_type);
+ free(uint8_frame);
+ };
+
+ int native_res = metadata_extractor_get_frame(handle_, &frame, &size);
+ if (METADATA_EXTRACTOR_ERROR_NONE != native_res) {
+ LoggerE("Error during getting metadata: %d", native_res);
+ return convertErrorCode(native_res);
+ }
+ LoggerD("Frame size %d", size);
+
+ // encode as JPEG
+ auto ret = EncodeJPEG((unsigned char*)frame, (size_t)size, &uint8_frame, &buffer_size);
+ if (!ret) {
+ return ret;
+ }
+
+ // convert frame to vector
+ std::vector out_buf(uint8_frame, uint8_frame + buffer_size);
+
+ *frame_array = std::move(out_buf);
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
} // namespace metadata
} // namespace extension
diff --git a/src/metadata/metadata_file_handle.h b/src/metadata/metadata_file_handle.h
index 67d31c54..e7bcca86 100644
--- a/src/metadata/metadata_file_handle.h
+++ b/src/metadata/metadata_file_handle.h
@@ -39,6 +39,9 @@ class MetadataFileHandle {
common::PlatformResult Get(const std::string& type, std::string* result);
common::PlatformResult GetArtwork(std::vector* data, std::string* mime_type);
+ common::PlatformResult EncodeJPEG(unsigned char* frame, size_t frame_size,
+ std::uint8_t** uint8_frame, size_t* buffer_size);
+ common::PlatformResult GetFrame(std::vector* frame_array);
private:
metadata_extractor_h handle_;
diff --git a/src/metadata/metadata_instance.cc b/src/metadata/metadata_instance.cc
index 5e1db6b8..449b9fcb 100644
--- a/src/metadata/metadata_instance.cc
+++ b/src/metadata/metadata_instance.cc
@@ -35,6 +35,7 @@ MetadataInstance::MetadataInstance() : next_handle_id_(1) {
REGISTER_METHOD(MetadataManagerCreateFileHandle);
REGISTER_METHOD(MetadataFileHandleGet);
REGISTER_METHOD(MetadataFileHandleGetArtwork);
+ REGISTER_METHOD(MetadataFileHandleGetThumbnailFrame);
REGISTER_METHOD(MetadataFileHandleRelease);
#undef REGISTER_METHOD
}
@@ -168,6 +169,41 @@ void MetadataInstance::MetadataFileHandleGetArtwork(const picojson::value& args,
ReportSuccess(result_artwork, out);
}
+void MetadataInstance::MetadataFileHandleGetThumbnailFrame(const picojson::value& args,
+ picojson::object& out) {
+ ScopeLogger();
+ const std::string& uri = args.get("uri").get();
+ const int id = static_cast(args.get("id").get());
+
+ auto res = InitializeHandleIfNeeded(uri, id);
+ if (!res) {
+ LogAndReportError(res, &out);
+ return;
+ }
+
+ std::vector data;
+ std::string mime_type;
+ try {
+ MetadataFileHandle& m = handles_map_.at(id);
+
+ auto res = m.GetFrame(&data);
+ if (!res) {
+ LogAndReportError(res, &out);
+ return;
+ }
+ } catch (...) {
+ // this should never happen
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Unknown error during accessing a file."), &out);
+ return;
+ }
+
+ std::string result_artwork;
+ encode_binary_in_string(data, result_artwork);
+
+ ReportSuccess(picojson::value(result_artwork), out);
+}
+
void MetadataInstance::MetadataFileHandleRelease(const picojson::value& args,
picojson::object& out) {
ScopeLogger();
diff --git a/src/metadata/metadata_instance.h b/src/metadata/metadata_instance.h
index 68eeddc4..14e65358 100644
--- a/src/metadata/metadata_instance.h
+++ b/src/metadata/metadata_instance.h
@@ -33,6 +33,7 @@ class MetadataInstance : public common::ParsedInstance {
common::PlatformResult InitializeHandleIfNeeded(const std::string& uri, const int id);
void MetadataFileHandleGet(const picojson::value& args, picojson::object& out);
void MetadataFileHandleGetArtwork(const picojson::value& args, picojson::object& out);
+ void MetadataFileHandleGetThumbnailFrame(const picojson::value& args, picojson::object& out);
void MetadataFileHandleRelease(const picojson::value& args, picojson::object& out);
std::map handles_map_;