From 035f1563cc5ef2c5e779229665fcbeb5f055b537 Mon Sep 17 00:00:00 2001 From: Seungchul Kim Date: Mon, 4 Mar 2019 16:16:08 +0900 Subject: libhwjpeg: support the multiple APPX segments libhwjpeg is modified to support the multiple APPX segments. For example, libhwjpeg can now update the multiple APP4 segments to the JPEG file. Change-Id: If494db0ba54a885469a161651198e08e9a41ab66 Signed-off-by: Seungchul Kim --- libhwjpeg/ExynosJpegEncoderForCamera.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'libhwjpeg/ExynosJpegEncoderForCamera.cpp') diff --git a/libhwjpeg/ExynosJpegEncoderForCamera.cpp b/libhwjpeg/ExynosJpegEncoderForCamera.cpp index 45695ae..a05f70a 100644 --- a/libhwjpeg/ExynosJpegEncoderForCamera.cpp +++ b/libhwjpeg/ExynosJpegEncoderForCamera.cpp @@ -103,6 +103,8 @@ ExynosJpegEncoderForCamera::ExynosJpegEncoderForCamera(bool bBTBComp) if (IsBTBCompressionSupported()) SetState(STATE_THUMBSIZE_CHANGED); + m_extraInfo.appInfo = m_appInfo; + ALOGD("ExynosJpegEncoderForCamera Created: %p, ION %d", this, m_fdIONClient); } @@ -219,7 +221,7 @@ void *ExynosJpegEncoderForCamera::tCompressThumbnail(void *p) bool ExynosJpegEncoderForCamera::ProcessExif(char *base, size_t limit, exif_attribute_t *exifInfo, - debug_attribute_t *debuginfo) + extra_appinfo_t *extra) { // PREREQUISITES: The main and the thumbnail image size should be configured before. @@ -252,7 +254,7 @@ bool ExynosJpegEncoderForCamera::ProcessExif(char *base, size_t limit, if (!!(GetDeviceCapabilities() & V4L2_CAP_EXYNOS_JPEG_NO_STREAMBASE_ALIGN)) align = 1; - m_pAppWriter->PrepareAppWriter(base + JPEG_MARKER_SIZE, exifInfo, debuginfo); + m_pAppWriter->PrepareAppWriter(base + JPEG_MARKER_SIZE, exifInfo, extra); if (limit <= (m_pAppWriter->CalculateAPPSize(0) + NECESSARY_JPEG_LENGTH)) { ALOGE("Too small JPEG stream buffer size, %zu bytes", limit); @@ -331,6 +333,23 @@ int ExynosJpegEncoderForCamera::encode(int *size, exif_attribute_t *exifInfo, int ExynosJpegEncoderForCamera::encode(int *size, exif_attribute_t *exifInfo, int fdJpegBuffer, char** pcJpegBuffer, debug_attribute_t *debugInfo) +{ + if ((!debugInfo) || (debugInfo->num_of_appmarker == 0)) { + extra_appinfo_t *extra = NULL; + return encode(size, exifInfo, fdJpegBuffer, pcJpegBuffer, extra); + } + + m_extraInfo.num_of_appmarker = 0; + memset(m_appInfo, 0, sizeof(m_appInfo)); + + ExtractDebugAttributeInfo(debugInfo, &m_extraInfo); + + return encode(size, exifInfo, fdJpegBuffer, pcJpegBuffer, &m_extraInfo); +} + +int ExynosJpegEncoderForCamera::encode(int *size, exif_attribute_t *exifInfo, + int fdJpegBuffer, char** pcJpegBuffer, + extra_appinfo_t *appInfo) { if (!(*pcJpegBuffer)) { ALOGE("Target stream buffer is not specified"); @@ -348,13 +367,13 @@ int ExynosJpegEncoderForCamera::encode(int *size, exif_attribute_t *exifInfo, char *jpeg_base = m_pStreamBase; ALOGI_IF(!exifInfo, "Exif is not specified. Skipping writing APP1 marker"); - ALOGI_IF(!debugInfo, + ALOGI_IF(!appInfo, "Debugging information is not specified. Skipping writing APP4 marker"); ALOGD("Given stream buffer size: %d bytes", *size); CStopWatch stopwatch(true); - if (!ProcessExif(jpeg_base, m_nStreamSize, exifInfo, debugInfo)) + if (!ProcessExif(jpeg_base, m_nStreamSize, exifInfo, appInfo)) return -1; int offset = PTR_DIFF(m_pStreamBase, m_pAppWriter->GetMainStreamBase()); -- cgit v1.2.3 From 8da348de51010dafbe2dd56980f9be12d8c109aa Mon Sep 17 00:00:00 2001 From: Cho KyongHo Date: Tue, 13 Aug 2019 17:50:44 +0900 Subject: libhwjpeg: refactor Set[Src|Dst]Image() The LibScalerForJpeg is the thumbnail image generator for libhwjpeg and the image and buffer types to LibScalerForJpeg does not vary. Unnecessary flexibility increases the complexity of a module. So, we should discard the support for userptr in SetDstImage(). In addition, LibScalerForJpeg requires unnecessary type casting to libhwjpeg for SetSrcImage and SetDstImage for the historical reasion. However, it is no longer needed because we can decide our API now. Change-Id: Ie8eebc38bf4f09889cc001e673f128570fb642c1 Signed-off-by: Cho KyongHo --- libhwjpeg/ExynosJpegEncoderForCamera.cpp | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'libhwjpeg/ExynosJpegEncoderForCamera.cpp') diff --git a/libhwjpeg/ExynosJpegEncoderForCamera.cpp b/libhwjpeg/ExynosJpegEncoderForCamera.cpp index a05f70a..8d72eac 100644 --- a/libhwjpeg/ExynosJpegEncoderForCamera.cpp +++ b/libhwjpeg/ExynosJpegEncoderForCamera.cpp @@ -581,41 +581,36 @@ bool ExynosJpegEncoderForCamera::GenerateThumbnailImage() ALOGD("Generating thumbnail image: %dx%d -> %dx%d", main_width, main_height, m_nThumbWidth, m_nThumbHeight); - int len_srcbufs[3] = {0, 0, 0}; - void *srcbufs[3] = {NULL, NULL, NULL}; - int memtype; + bool okay = false; if (checkInBufType() == JPEG_BUF_TYPE_USER_PTR) { char *bufs[3]; + int len_srcbufs[3]; + if (getInBuf(bufs, len_srcbufs, 3) < 0) { ALOGE("Failed to retrieve the main image buffers"); return false; } - memtype = V4L2_MEMORY_USERPTR; - srcbufs[0] = reinterpret_cast(bufs[0]); - srcbufs[1] = reinterpret_cast(bufs[1]); - srcbufs[2] = reinterpret_cast(bufs[2]); + + okay = m_pLibScaler.SetSrcImage(main_width, main_height, v4l2Format, bufs); } else { // mainbuftype == JPEG_BUF_TYPE_DMA_BUF int bufs[3]; + int len_srcbufs[3]; + if (getInBuf(bufs, len_srcbufs, 3) < 0) { ALOGE("Failed to retrieve the main image buffers"); return false; } - memtype = V4L2_MEMORY_DMABUF; - srcbufs[0] = reinterpret_cast(bufs[0]); - srcbufs[1] = reinterpret_cast(bufs[1]); - srcbufs[2] = reinterpret_cast(bufs[2]); + okay = m_pLibScaler.SetSrcImage(main_width, main_height, v4l2Format, bufs); } - void *dstbuf[3] = {NULL, NULL, NULL}; - dstbuf[0] = reinterpret_cast(m_fdIONThumbImgBuffer); - - if (!m_pLibScaler.SetSrcImage(main_width, main_height, v4l2Format, srcbufs, memtype)) { + if (!okay) { ALOGE("Failed to configure the main image format to LibScalerForJpeg"); return false; } + if (!m_pLibScaler.SetDstImage(m_nThumbWidth, m_nThumbHeight, - GetThumbnailFormat(v4l2Format), dstbuf, V4L2_MEMORY_DMABUF)) { + GetThumbnailFormat(v4l2Format), m_fdIONThumbImgBuffer)) { ALOGE("Failed to configure the target image format to LibScalerForJpeg"); return false; } -- cgit v1.2.3 From 6ef6bc8731a2319103d27912353eb814265152bc Mon Sep 17 00:00:00 2001 From: Cho KyongHo Date: Wed, 14 Aug 2019 11:35:01 +0900 Subject: libhwjpeg: delegate driver init to each port V4L2 API call sequence in LibScalerForJpeg is deviced by the APIs for both of the ports including output and capture: s_fmt(output) & s_fmt(capture) -> reqbufs(output) & reqbufs(capture) -> qbuf(output) & qbuf(capture) -> dqbuf(output) & dqbuf(capture). But LibScalerForJpeg should revert the success of an API call for output if the following the same API call for capture is failed for the next try. Now we can choose the better way: (s_fmt(output)->reqbufs(output))&(s_fmt(capture)->reqbufs(capture)) -> qbuf(output) & qbuf(capture) We do not need to revert an API call for output even though its following API call for capture.o We also moved parameters of LibScalerForJpeg::Set[Src|Dst]Image() about image buffers to LibScalerForJpeg::RunStream() because image dimension and format seldom change while buffers can be changed every frame. This change helps the better design. We do not need to hold the buffer information confirued by LibScalerForJpeg::Set[Src|Dst]Image() until LibScalerForJpeg::RunStream() is called. Change-Id: I4af0750975068b22055c1c2eafc53ce76d366479 Signed-off-by: Cho KyongHo --- libhwjpeg/ExynosJpegEncoderForCamera.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'libhwjpeg/ExynosJpegEncoderForCamera.cpp') diff --git a/libhwjpeg/ExynosJpegEncoderForCamera.cpp b/libhwjpeg/ExynosJpegEncoderForCamera.cpp index 8d72eac..bb4dc2c 100644 --- a/libhwjpeg/ExynosJpegEncoderForCamera.cpp +++ b/libhwjpeg/ExynosJpegEncoderForCamera.cpp @@ -581,6 +581,17 @@ bool ExynosJpegEncoderForCamera::GenerateThumbnailImage() ALOGD("Generating thumbnail image: %dx%d -> %dx%d", main_width, main_height, m_nThumbWidth, m_nThumbHeight); + if (!m_pLibScaler.SetSrcImage(main_width, main_height, v4l2Format)) { + ALOGE("Failed to configure the main image format to LibScalerForJpeg"); + return false; + } + + + if (!m_pLibScaler.SetDstImage(m_nThumbWidth, m_nThumbHeight, GetThumbnailFormat(v4l2Format))) { + ALOGE("Failed to configure the target image format to LibScalerForJpeg"); + return false; + } + bool okay = false; if (checkInBufType() == JPEG_BUF_TYPE_USER_PTR) { @@ -592,7 +603,7 @@ bool ExynosJpegEncoderForCamera::GenerateThumbnailImage() return false; } - okay = m_pLibScaler.SetSrcImage(main_width, main_height, v4l2Format, bufs); + okay = m_pLibScaler.RunStream(bufs, m_fdIONThumbImgBuffer); } else { // mainbuftype == JPEG_BUF_TYPE_DMA_BUF int bufs[3]; int len_srcbufs[3]; @@ -601,21 +612,10 @@ bool ExynosJpegEncoderForCamera::GenerateThumbnailImage() ALOGE("Failed to retrieve the main image buffers"); return false; } - okay = m_pLibScaler.SetSrcImage(main_width, main_height, v4l2Format, bufs); + okay = m_pLibScaler.RunStream(bufs, m_fdIONThumbImgBuffer); } if (!okay) { - ALOGE("Failed to configure the main image format to LibScalerForJpeg"); - return false; - } - - if (!m_pLibScaler.SetDstImage(m_nThumbWidth, m_nThumbHeight, - GetThumbnailFormat(v4l2Format), m_fdIONThumbImgBuffer)) { - ALOGE("Failed to configure the target image format to LibScalerForJpeg"); - return false; - } - - if (!m_pLibScaler.RunStream()) { ALOGE("Failed to convert the main image to thumbnail with LibScalerForJpeg"); return false; } -- cgit v1.2.3 From a6b44cc59409195144498eb568742a59983c2571 Mon Sep 17 00:00:00 2001 From: Cho KyongHo Date: Wed, 14 Aug 2019 17:13:47 +0900 Subject: libhwjpeg: use buffer size instead of payload ExynosJpegEncoderForCamera has the lengths of mage buffers to LibScalerForJpeg but it does not get informed about the lengths. Instead LibScalerForJpeg feeds VIDIOC_QBUF the required payloads of images studied by VIDOC_S_FMT as the buffer length which is not the length of the buffer. Change-Id: Id51f3a6e4f701fdb5f33bf84d17045448ab5f97a Signed-off-by: Cho KyongHo --- libhwjpeg/ExynosJpegEncoderForCamera.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'libhwjpeg/ExynosJpegEncoderForCamera.cpp') diff --git a/libhwjpeg/ExynosJpegEncoderForCamera.cpp b/libhwjpeg/ExynosJpegEncoderForCamera.cpp index bb4dc2c..39e877e 100644 --- a/libhwjpeg/ExynosJpegEncoderForCamera.cpp +++ b/libhwjpeg/ExynosJpegEncoderForCamera.cpp @@ -595,24 +595,24 @@ bool ExynosJpegEncoderForCamera::GenerateThumbnailImage() bool okay = false; if (checkInBufType() == JPEG_BUF_TYPE_USER_PTR) { - char *bufs[3]; - int len_srcbufs[3]; + char *bufs[SCALER_MAX_PLANES]; + int len_srcbufs[SCALER_MAX_PLANES]; - if (getInBuf(bufs, len_srcbufs, 3) < 0) { + if (getInBuf(bufs, len_srcbufs, SCALER_MAX_PLANES) < 0) { ALOGE("Failed to retrieve the main image buffers"); return false; } - okay = m_pLibScaler.RunStream(bufs, m_fdIONThumbImgBuffer); + okay = m_pLibScaler.RunStream(bufs, len_srcbufs, m_fdIONThumbImgBuffer, m_szIONThumbImgBuffer); } else { // mainbuftype == JPEG_BUF_TYPE_DMA_BUF - int bufs[3]; - int len_srcbufs[3]; + int bufs[SCALER_MAX_PLANES]; + int len_srcbufs[SCALER_MAX_PLANES]; - if (getInBuf(bufs, len_srcbufs, 3) < 0) { + if (getInBuf(bufs, len_srcbufs, SCALER_MAX_PLANES) < 0) { ALOGE("Failed to retrieve the main image buffers"); return false; } - okay = m_pLibScaler.RunStream(bufs, m_fdIONThumbImgBuffer); + okay = m_pLibScaler.RunStream(bufs, len_srcbufs, m_fdIONThumbImgBuffer, m_szIONThumbImgBuffer); } if (!okay) { -- cgit v1.2.3 From 376a9251edbb8fd8ff6d1bd9055499dd36ae06b6 Mon Sep 17 00:00:00 2001 From: Cho KyongHo Date: Wed, 14 Aug 2019 20:48:42 +0900 Subject: libhwjpeg: introduce polymorphic thumbnail scaler LibScalerForJpeg is the only thumbnail scaler implemented with the legacy V4L2 MSCL driver. But we may need to use another types of thumbnail scaler that runs with different H/W or different API. Therefore abstract calss, ThumbnailScaler is introduced and the concrete object of the thumbnail scaler is created with ThumbnailScaler::createInstance(). All the implementation details and differences between products are handled in createInstance(). Change-Id: Ibef2693ca6ea9e23f8993c9e525e58ac54a22333 Signed-off-by: Cho KyongHo --- libhwjpeg/ExynosJpegEncoderForCamera.cpp | 35 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'libhwjpeg/ExynosJpegEncoderForCamera.cpp') diff --git a/libhwjpeg/ExynosJpegEncoderForCamera.cpp b/libhwjpeg/ExynosJpegEncoderForCamera.cpp index 39e877e..ed09cb8 100644 --- a/libhwjpeg/ExynosJpegEncoderForCamera.cpp +++ b/libhwjpeg/ExynosJpegEncoderForCamera.cpp @@ -27,7 +27,7 @@ #include "hwjpeg-internal.h" #include "AppMarkerWriter.h" -#include "LibScalerForJpeg.h" +#include "ThumbnailScaler.h" #include "IFDWriter.h" // Data length written by H/W without the scan data. @@ -105,6 +105,8 @@ ExynosJpegEncoderForCamera::ExynosJpegEncoderForCamera(bool bBTBComp) m_extraInfo.appInfo = m_appInfo; + mThumbnailScaler.reset(ThumbnailScaler::createInstance()); + ALOGD("ExynosJpegEncoderForCamera Created: %p, ION %d", this, m_fdIONClient); } @@ -581,42 +583,47 @@ bool ExynosJpegEncoderForCamera::GenerateThumbnailImage() ALOGD("Generating thumbnail image: %dx%d -> %dx%d", main_width, main_height, m_nThumbWidth, m_nThumbHeight); - if (!m_pLibScaler.SetSrcImage(main_width, main_height, v4l2Format)) { - ALOGE("Failed to configure the main image format to LibScalerForJpeg"); + if (!mThumbnailScaler) { + ALOGE("Thumbnail scaler is not prepared"); + return false; + } + + if (!mThumbnailScaler->SetSrcImage(main_width, main_height, v4l2Format)) { + ALOGE("Failed to configure the main image to the thumbnail scaler"); return false; } - if (!m_pLibScaler.SetDstImage(m_nThumbWidth, m_nThumbHeight, GetThumbnailFormat(v4l2Format))) { - ALOGE("Failed to configure the target image format to LibScalerForJpeg"); + if (!mThumbnailScaler->SetDstImage(m_nThumbWidth, m_nThumbHeight, GetThumbnailFormat(v4l2Format))) { + ALOGE("Failed to configure the target image to the thumbnail scaler"); return false; } bool okay = false; if (checkInBufType() == JPEG_BUF_TYPE_USER_PTR) { - char *bufs[SCALER_MAX_PLANES]; - int len_srcbufs[SCALER_MAX_PLANES]; + char *bufs[ThumbnailScaler::SCALER_MAX_PLANES]; + int len_srcbufs[ThumbnailScaler::SCALER_MAX_PLANES]; - if (getInBuf(bufs, len_srcbufs, SCALER_MAX_PLANES) < 0) { + if (getInBuf(bufs, len_srcbufs, ThumbnailScaler::SCALER_MAX_PLANES) < 0) { ALOGE("Failed to retrieve the main image buffers"); return false; } - okay = m_pLibScaler.RunStream(bufs, len_srcbufs, m_fdIONThumbImgBuffer, m_szIONThumbImgBuffer); + okay = mThumbnailScaler->RunStream(bufs, len_srcbufs, m_fdIONThumbImgBuffer, m_szIONThumbImgBuffer); } else { // mainbuftype == JPEG_BUF_TYPE_DMA_BUF - int bufs[SCALER_MAX_PLANES]; - int len_srcbufs[SCALER_MAX_PLANES]; + int bufs[ThumbnailScaler::SCALER_MAX_PLANES]; + int len_srcbufs[ThumbnailScaler::SCALER_MAX_PLANES]; - if (getInBuf(bufs, len_srcbufs, SCALER_MAX_PLANES) < 0) { + if (getInBuf(bufs, len_srcbufs, ThumbnailScaler::SCALER_MAX_PLANES) < 0) { ALOGE("Failed to retrieve the main image buffers"); return false; } - okay = m_pLibScaler.RunStream(bufs, len_srcbufs, m_fdIONThumbImgBuffer, m_szIONThumbImgBuffer); + okay = mThumbnailScaler->RunStream(bufs, len_srcbufs, m_fdIONThumbImgBuffer, m_szIONThumbImgBuffer); } if (!okay) { - ALOGE("Failed to convert the main image to thumbnail with LibScalerForJpeg"); + ALOGE("Failed to convert the main image to thumbnail with the thumbnail scaler"); return false; } -- cgit v1.2.3