#include <mm_util_image.h>
#include <mm_util_imgp.h>
#include <mm_util_jpeg.h>
+#include <mm_util_magick.h>
typedef struct {
unsigned char *data;
MMVideoBuffer *vbuffer;
bool exit;
snapshot_format_e target_format;
- int quality;
+ int option;
} queue_data_s;
static const char * __format_str[] = {
[SNAPSHOT_FORMAT_RGB24] = "RGB24",
[SNAPSHOT_FORMAT_JPEG] = "JPEG",
+ [SNAPSHOT_FORMAT_PNG] = "PNG",
};
//LCOV_EXCL_START
return vbuffer;
}
-static int __mm_image_convert_colorspace(unsigned char *src_data, size_t src_size, int src_w, int src_h, mm_util_color_format_e src_fmt, mm_util_color_format_e dst_fmt, webrtc_video_frame_s *result)
+static int __mm_image_convert_colorspace(unsigned char *src_data, size_t src_size, int src_w, int src_h, mm_util_color_format_e src_fmt,
+ mm_util_color_format_e dst_fmt, webrtc_video_frame_s *result)
{
int ret;
mm_util_image_h src_image;
return WEBRTC_ERROR_NONE;
}
-static int __mm_image_encode(unsigned char *src_data, size_t src_size, int src_w, int src_h, mm_util_color_format_e src_fmt, mm_util_img_codec_type codec, int quality, webrtc_video_frame_s *result)
+static int __mm_image_encode(unsigned char *src_data, size_t src_size, int src_w, int src_h, mm_util_color_format_e src_fmt,
+ mm_util_img_codec_type codec, int option, webrtc_video_frame_s *result)
{
- int ret;
+ int mm_ret;
+ int ret = WEBRTC_ERROR_INVALID_OPERATION;
mm_util_image_h src_image;
+ mm_util_enc_opt_h enc_opt = NULL;
RET_VAL_IF(src_data == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "src_data is NULL");
RET_VAL_IF(result == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "result is NULL");
LOG_DEBUG_ENTER();
- ret = mm_image_create_image(src_w, src_h, src_fmt, src_data, src_size, &src_image);
- RET_VAL_IF(ret != MM_UTIL_ERROR_NONE, WEBRTC_ERROR_INVALID_OPERATION, "failed to mm_image_create_image()");
-
- result->width = src_w;
- result->height = src_h;
+ mm_ret = mm_image_create_image(src_w, src_h, src_fmt, src_data, src_size, &src_image);
+ RET_VAL_IF(mm_ret != MM_UTIL_ERROR_NONE, WEBRTC_ERROR_INVALID_OPERATION, "failed to mm_image_create_image()");
switch (codec) {
case IMG_CODEC_JPEG:
- ret = mm_util_encode_to_jpeg_memory(src_image, quality, (void **)&result->data, &result->size);
- mm_image_destroy_image(src_image);
- RET_VAL_IF(ret != MM_UTIL_ERROR_NONE, WEBRTC_ERROR_INVALID_OPERATION, "failed to mm_util_encode_to_jpeg_memory()");
+ /* option value is for quality (1 ~ 100) */
+ mm_ret = mm_util_encode_to_jpeg_memory(src_image, option, (void **)&result->data, &result->size);
+ if (mm_ret != MM_UTIL_ERROR_NONE) {
+ LOG_ERROR("failed to mm_util_encode_to_jpeg_memory()");
+ goto error;
+ }
+ break;
+ case IMG_CODEC_PNG: {
+ mm_ret = mm_util_enc_opt_create(&enc_opt);
+ if (mm_ret != MM_UTIL_ERROR_NONE) {
+ LOG_ERROR("failed to mm_util_enc_opt_create()");
+ goto error;
+ }
- LOG_INFO("src[data:%p, size:%zu, %dx%d, fmt:%d] -> dst[data:%p, size:%zu, %ux%u, codec:JPEG, quality:%d]",
- src_data, src_size, src_w, src_h, src_fmt,
- result->data, result->size, result->width, result->height, quality);
- return WEBRTC_ERROR_NONE;
+ mm_ret = mm_util_enc_opt_set_codec(enc_opt, IMG_CODEC_PNG);
+ if (mm_ret != MM_UTIL_ERROR_NONE) {
+ LOG_ERROR("failed to mm_util_enc_opt_set_codec()");
+ goto error;
+ }
+
+ /* option value is for compression level (0 ~ 9) */
+ mm_ret = mm_util_enc_opt_set_png_compression(enc_opt, (unsigned int)option);
+ if (mm_ret != MM_UTIL_ERROR_NONE) {
+ LOG_ERROR("failed to mm_util_enc_opt_set_png_compression()");
+ goto error;
+ }
+ mm_ret = mm_util_encode_image_to_buffer(src_image, enc_opt, (void **)&result->data, &result->size);
+ if (mm_ret != MM_UTIL_ERROR_NONE) {
+ LOG_ERROR("failed to mm_util_encode_image_to_buffer()");
+ goto error;
+ }
+ break;
+ }
default:
LOG_ERROR_IF_REACHED("codec(%d)", codec);
- mm_image_destroy_image(src_image);
- return WEBRTC_ERROR_INVALID_PARAMETER;
+ ret = WEBRTC_ERROR_INVALID_PARAMETER;
+ goto error;
}
+
+ result->width = src_w;
+ result->height = src_h;
+ ret = WEBRTC_ERROR_NONE;
+
+ LOG_INFO("src[data:%p, size:%zu, %dx%d, fmt:%d] -> dst[data:%p, size:%zu, %ux%u, codec:%d, option:%d]",
+ src_data, src_size, src_w, src_h, src_fmt,
+ result->data, result->size, result->width, result->height, codec, option);
+error:
+ if (enc_opt)
+ mm_util_enc_opt_destroy(enc_opt);
+ mm_image_destroy_image(src_image);
+ return ret;
}
static int __get_src_size(MMVideoBuffer *vbuffer, mm_util_color_format_e color_format)
LOG_WARNING("converted rgb24 frame is dumped to [%s]", file_path);
}
-static void __dump_encoded_result(webrtc_video_frame_s *result, snapshot_format_e target_format, unsigned int idx)
+static void __dump_encoded_result(webrtc_video_frame_s *result, snapshot_format_e target_format, int option, unsigned int idx)
{
g_autofree gchar *file_path = NULL;
g_autoptr(GError) error = NULL;
if (!result->data)
return;
- file_path = g_strdup_printf("/tmp/snapshot_%03u_%ux%u_%s.dump", idx, result->width, result->height, __format_str[target_format]);
+ file_path = g_strdup_printf("/tmp/snapshot_%03u_%ux%u_%s_opt%d.dump", idx, result->width, result->height, __format_str[target_format], option);
if (!g_file_set_contents(file_path, (char *)result->data, result->size, &error)) {
LOG_ERROR("failed to g_file_set_contents() for %s, error:%s", file_path, error->message);
qd->color_format = color_format;
qd->vbuffer = vbuffer;
qd->target_format = probe_data->slot->snapshot.target_format;
- qd->quality = probe_data->slot->snapshot.quality;
+ qd->option = probe_data->slot->snapshot.option;
g_async_queue_push(probe_data->slot->webrtc->snapshot.queue, qd);
out:
case SNAPSHOT_FORMAT_RGB24:
break; /* skip encoding */
case SNAPSHOT_FORMAT_JPEG:
+ case SNAPSHOT_FORMAT_PNG:
ret = __mm_image_encode(rgb24_frame.data, rgb24_frame.size, rgb24_frame.width, rgb24_frame.height, MM_UTIL_COLOR_RGB24,
- IMG_CODEC_JPEG, qd->quality, &encoded_frame);
- if (ret != WEBRTC_ERROR_NONE)
- LOG_ERROR("failed to __mm_image_encode() for %s", __format_str[qd->target_format]);
+ (qd->target_format == SNAPSHOT_FORMAT_JPEG) ? IMG_CODEC_JPEG : IMG_CODEC_PNG, qd->option, &encoded_frame);
break;
default:
LOG_ERROR_IF_REACHED("target_format(%d)", qd->target_format);
+ ret = WEBRTC_ERROR_INVALID_PARAMETER;
break;
}
+ if (ret != WEBRTC_ERROR_NONE)
+ LOG_ERROR("failed to encode image(), ret[0x%x]", ret);
#ifdef DUMP_CONVERTED_RESULT
__dump_rgb24_result(&rgb24_frame, ++idx);
- __dump_encoded_result(&encoded_frame, qd->target_format, idx);
+ __dump_encoded_result(&encoded_frame, qd->target_format, qd->option, idx);
#endif
/* TODO: Append data to user callback */
}
RET_VAL_IF(sink == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "sink is NULL");
RET_VAL_IF(sink->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
- RET_VAL_IF(!(videosink = gst_bin_get_by_name(sink->bin, ELEMENT_NAME_VIDEO_SINK)), WEBRTC_ERROR_INVALID_OPERATION, "could not find video sink element");
+ RET_VAL_IF(!(videosink = gst_bin_get_by_name(sink->bin, ELEMENT_NAME_VIDEO_SINK)), WEBRTC_ERROR_INVALID_OPERATION,
+ "could not find video sink element");
__add_probe_to_pad_for_snapshot(sink, videosink, __snapshot_probe_cb);