From e3a12a9ad67f31217935384e5f1d18dd2c3cffb8 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Wed, 28 Feb 2024 15:15:03 +0800 Subject: [PATCH] feat(jpeg): Add jpeg decoder example for esp32p4 --- examples/peripherals/.build-test-rules.yml | 6 + .../jpeg/jpeg_decode/CMakeLists.txt | 6 + .../peripherals/jpeg/jpeg_decode/README.md | 58 ++++++ .../jpeg/jpeg_decode/main/CMakeLists.txt | 2 + .../jpeg/jpeg_decode/main/Kconfig.projbuild | 9 + .../jpeg/jpeg_decode/main/jpeg_decode_main.c | 169 ++++++++++++++++++ .../peripherals/jpeg/jpeg_decode/open_rgb.py | 91 ++++++++++ .../jpeg/jpeg_decode/requirements.txt | 2 + .../jpeg/jpeg_decode/resources/esp1080.jpg | Bin 0 -> 49420 bytes .../jpeg/jpeg_decode/resources/esp720.jpg | Bin 0 -> 24087 bytes .../jpeg/jpeg_decode/sdkconfig.defaults | 6 + 11 files changed, 349 insertions(+) create mode 100644 examples/peripherals/jpeg/jpeg_decode/CMakeLists.txt create mode 100644 examples/peripherals/jpeg/jpeg_decode/README.md create mode 100644 examples/peripherals/jpeg/jpeg_decode/main/CMakeLists.txt create mode 100644 examples/peripherals/jpeg/jpeg_decode/main/Kconfig.projbuild create mode 100644 examples/peripherals/jpeg/jpeg_decode/main/jpeg_decode_main.c create mode 100644 examples/peripherals/jpeg/jpeg_decode/open_rgb.py create mode 100644 examples/peripherals/jpeg/jpeg_decode/requirements.txt create mode 100644 examples/peripherals/jpeg/jpeg_decode/resources/esp1080.jpg create mode 100644 examples/peripherals/jpeg/jpeg_decode/resources/esp720.jpg create mode 100644 examples/peripherals/jpeg/jpeg_decode/sdkconfig.defaults diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 779e60fa70..c8278d465f 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -116,6 +116,12 @@ examples/peripherals/i2s/i2s_recorder: - esp_driver_spi - esp_driver_i2s +examples/peripherals/jpeg/jpeg_decode: + disable: + - if: SOC_JPEG_CODEC_SUPPORTED != 1 + depends_components: + - esp_driver_jpeg + examples/peripherals/lcd/i2c_oled: disable: - if: SOC_I2C_SUPPORTED != 1 diff --git a/examples/peripherals/jpeg/jpeg_decode/CMakeLists.txt b/examples/peripherals/jpeg/jpeg_decode/CMakeLists.txt new file mode 100644 index 0000000000..3b371a6c85 --- /dev/null +++ b/examples/peripherals/jpeg/jpeg_decode/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(jpeg_decode) diff --git a/examples/peripherals/jpeg/jpeg_decode/README.md b/examples/peripherals/jpeg/jpeg_decode/README.md new file mode 100644 index 0000000000..7947801298 --- /dev/null +++ b/examples/peripherals/jpeg/jpeg_decode/README.md @@ -0,0 +1,58 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | + +# JPEG decode example + +## Overview + +This example demonstrates how to use the JPEG hardware decoder to decode a 1080p and a 720p picture: + +If you have a bunch of big JPEG picture need to be decoded, such as `*.jpg` -> `*.rgb`, and this example uses hardware JPEG decoder to accelerate the decoding. + +## How to use example + +### Prerequisites Required + +This example demonstrates the flexibility of decoding pictures by decoding two different sizes: one in 1080p and another in 720p. It showcases how you can easily modify the code to meet your specific requirements, such as only decoding 1080p photos. + +### Build and Flash + +Before you start build and flash this example, please put the image `esp720.jpg` and `esp1080.jpg` in your sdcard. + +Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +```bash +I (1116) jpeg.example: Initializing SD card +I (1116) gpio: GPIO[43]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (1126) gpio: GPIO[44]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (1136) gpio: GPIO[39]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (1146) gpio: GPIO[40]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (1156) gpio: GPIO[41]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (1166) gpio: GPIO[42]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (1416) gpio: GPIO[42]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +Name: SD64G +Type: SDHC/SDXC +Speed: 40.00 MHz (limit: 40.00 MHz) +Size: 60906MB +CSD: ver=2, sector_size=512, capacity=124735488 read_bl_len=9 +SSR: bus_width=4 +I (1436) jpeg.example: jpg_file_1080:/sdcard/esp1080.jpg +I (1696) jpeg.example: jpg_file_1080:/sdcard/esp720.jpg +I (1796) jpeg.example: header parsed, width is 1920, height is 1080 +I (1846) jpeg.example: raw_file_1080:/sdcard/out.rgb +I (11836) jpeg.example: raw_file_720:/sdcard/out2.rgb +I (13336) jpeg.example: Card unmounted +I (13336) main_task: Returned from app_main() +``` + +Moreover, we provided a helper script called `open_rgb.py`, which can help you easily see the outputs on your computer. For requirements component you need, you can call `pip install -r requirements.txt` under `examples/peripheral/jpeg/jpeg_decode` folder. + +## Troubleshooting + +(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.) \ No newline at end of file diff --git a/examples/peripherals/jpeg/jpeg_decode/main/CMakeLists.txt b/examples/peripherals/jpeg/jpeg_decode/main/CMakeLists.txt new file mode 100644 index 0000000000..90f7897d87 --- /dev/null +++ b/examples/peripherals/jpeg/jpeg_decode/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "jpeg_decode_main.c" + INCLUDE_DIRS ".") diff --git a/examples/peripherals/jpeg/jpeg_decode/main/Kconfig.projbuild b/examples/peripherals/jpeg/jpeg_decode/main/Kconfig.projbuild new file mode 100644 index 0000000000..a33f65db3b --- /dev/null +++ b/examples/peripherals/jpeg/jpeg_decode/main/Kconfig.projbuild @@ -0,0 +1,9 @@ +menu "JPEG Decode Example menu" + + config EXAMPLE_FORMAT_IF_MOUNT_FAILED + bool "Format the card if mount failed" + default n + help + If this config item is set, format_if_mount_failed will be set to true and the card will be formatted if + the mount has failed. +endmenu diff --git a/examples/peripherals/jpeg/jpeg_decode/main/jpeg_decode_main.c b/examples/peripherals/jpeg/jpeg_decode/main/jpeg_decode_main.c new file mode 100644 index 0000000000..e6486ec09a --- /dev/null +++ b/examples/peripherals/jpeg/jpeg_decode/main/jpeg_decode_main.c @@ -0,0 +1,169 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include "esp_heap_caps.h" +#include "esp_vfs_fat.h" +#include "sdmmc_cmd.h" +#include "driver/sdmmc_host.h" +#include "esp_attr.h" +#include "driver/jpeg_decode.h" + +static const char *TAG = "jpeg.example"; +static sdmmc_card_t *s_card; +#define MOUNT_POINT "/sdcard" + +const static char jpg_file_1080[] = "/sdcard/esp1080.jpg"; +const static char raw_file_1080[] = "/sdcard/out.rgb"; +const static char jpg_file_720[] = "/sdcard/esp720.jpg"; +const static char raw_file_720[] = "/sdcard/out2.rgb"; + +static esp_err_t sdcard_init(void) +{ + esp_err_t ret = ESP_OK; + esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED + .max_files = 5, + .allocation_unit_size = 16 * 1024 + }; + const char mount_point[] = MOUNT_POINT; + ESP_LOGI(TAG, "Initializing SD card"); + + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + host.max_freq_khz = SDMMC_FREQ_HIGHSPEED; + // This initializes the slot without card detect (CD) and write protect (WP) signals. + // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + slot_config.width = 4; + slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP; + + ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &s_card); + + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, "Failed to mount filesystem. " + "If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option."); + } else { + ESP_LOGE(TAG, "Failed to initialize the card (%s). " + "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret)); + } + return ret; + } + // Card has been initialized, print its properties + sdmmc_card_print_info(stdout, s_card); + return ret; +} + +static void sdcard_deinit(void) +{ + const char mount_point[] = MOUNT_POINT; + esp_vfs_fat_sdcard_unmount(mount_point, s_card); +} + +void app_main(void) +{ + ESP_ERROR_CHECK(sdcard_init()); + + jpeg_decoder_handle_t jpgd_handle; + + jpeg_decode_engine_cfg_t decode_eng_cfg = { + + }; + + ESP_ERROR_CHECK(jpeg_new_decoder_engine(&decode_eng_cfg, &jpgd_handle)); + + jpeg_decode_cfg_t decode_cfg_rgb = { + .output_format = JPEG_DECODE_OUT_FORMAT_RGB888, + .rgb_order = JPEG_DEC_RGB_ELEMENT_ORDER_BGR, + }; + + jpeg_decode_cfg_t decode_cfg_gray = { + .output_format = JPEG_DECODE_OUT_FORMAT_GRAY, + }; + + FILE *file_jpg_1080p = fopen(jpg_file_1080, "rb"); + ESP_LOGI(TAG, "jpg_file_1080:%s", jpg_file_1080); + if (file_jpg_1080p == NULL) { + ESP_LOGE(TAG, "fopen file_jpg_1080p error"); + return; + } + + fseek(file_jpg_1080p, 0, SEEK_END); + int jpeg_size_1080p = ftell(file_jpg_1080p); + fseek(file_jpg_1080p, 0, SEEK_SET); + uint8_t *tx_buf_1080p = (uint8_t*)jpeg_alloc_decoder_mem(jpeg_size_1080p); + if (tx_buf_1080p == NULL) { + ESP_LOGE(TAG, "alloc 1080p tx buffer error"); + return; + } + fread(tx_buf_1080p, 1, jpeg_size_1080p, file_jpg_1080p); + fclose(file_jpg_1080p); + + FILE *file_jpg_720p = fopen(jpg_file_720, "rb"); + ESP_LOGI(TAG, "jpg_file_1080:%s", jpg_file_720); + if (file_jpg_720p == NULL) { + ESP_LOGE(TAG, "fopen file_jpg_720p error"); + return; + } + fseek(file_jpg_720p, 0, SEEK_END); + int jpeg_size_720p = ftell(file_jpg_720p); + fseek(file_jpg_720p, 0, SEEK_SET); + uint8_t *tx_buf_720p = (uint8_t*)jpeg_alloc_decoder_mem(jpeg_size_720p); + if (tx_buf_720p == NULL) { + ESP_LOGE(TAG, "alloc 720p tx buffer error"); + return; + } + fread(tx_buf_720p, 1, jpeg_size_720p, file_jpg_720p); + fclose(file_jpg_720p); + + uint8_t *rx_buf_1080p = (uint8_t*)jpeg_alloc_decoder_mem(1920 * 1080 * 3); + uint8_t *rx_buf_720p = (uint8_t*)jpeg_alloc_decoder_mem(720 * 1280); + if (rx_buf_1080p == NULL) { + ESP_LOGE(TAG, "alloc 1080p rx buffer error"); + return; + } + if (rx_buf_720p == NULL) { + ESP_LOGE(TAG, "alloc 720p rx buffer error"); + return; + } + + // Get the jpg header information (This step is optional) + jpeg_decode_picture_info_t header_info; + ESP_ERROR_CHECK(jpeg_decoder_get_info(tx_buf_1080p, jpeg_size_1080p, &header_info)); + ESP_LOGI(TAG, "header parsed, width is %" PRId32 ", height is %" PRId32, header_info.width, header_info.height); + + uint32_t out_size_1080p = 0; + uint32_t out_size_720p = 0; + ESP_ERROR_CHECK(jpeg_decoder_process(jpgd_handle, &decode_cfg_rgb, tx_buf_1080p, jpeg_size_1080p, rx_buf_1080p, &out_size_1080p)); + ESP_ERROR_CHECK(jpeg_decoder_process(jpgd_handle, &decode_cfg_gray, tx_buf_720p, jpeg_size_720p, rx_buf_720p, &out_size_720p)); + + // Write two pictures. + FILE *file_rgb_1080p = fopen(raw_file_1080, "wb"); + ESP_LOGI(TAG, "raw_file_1080:%s", raw_file_1080); + if (file_rgb_1080p == NULL) { + ESP_LOGE(TAG, "fopen file_rgb_1080p error"); + return; + } + fwrite(rx_buf_1080p, 1, out_size_1080p, file_rgb_1080p); + fclose(file_rgb_1080p); + + FILE *file_rgb_720p = fopen(raw_file_720, "wb"); + ESP_LOGI(TAG, "raw_file_720:%s", raw_file_720); + if (file_rgb_720p == NULL) { + ESP_LOGE(TAG, "fopen file_rgb_720p error"); + return; + } + fwrite(rx_buf_720p, 1, out_size_720p, file_rgb_720p); + fclose(file_rgb_720p); + + sdcard_deinit(); + ESP_LOGI(TAG, "Card unmounted"); + +} diff --git a/examples/peripherals/jpeg/jpeg_decode/open_rgb.py b/examples/peripherals/jpeg/jpeg_decode/open_rgb.py new file mode 100644 index 0000000000..c78809627f --- /dev/null +++ b/examples/peripherals/jpeg/jpeg_decode/open_rgb.py @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import argparse + +import cv2 as cv +import numpy as np + + +def open_picture(path): # type: (str) -> list[int] + with open(path, 'rb') as f: + data = f.read() + f.close() + new_data = [int(x) for x in data] + return new_data + + +def picture_show_rgb888(data, h, w): # type: (list[int], int, int) -> None + data = np.array(data).reshape(h, w, 3).astype(np.uint8) + cv.imshow('data', data) + cv.waitKey() + + +def picture_show_rgb565(data, h, w): # type: (list[int], int, int) -> None + + new_data = [0] * ((len(data) // 2) * 3) + for i in range(len(data)): + if i % 2 != 0: + new_data[3 * (i - 1) // 2 + 2] = (data[i] & 0xf8) + new_data[3 * (i - 1) // 2 + 1] |= (data[i] & 0x7) << 5 + else: + new_data[3 * i // 2] = (data[i] & 0x1f) << 3 + new_data[3 * i // 2 + 1] |= (data[i] & 0xe0) >> 3 + + new_data = np.array(new_data).reshape(h, w, 3).astype(np.uint8) + cv.imshow('data', new_data) + cv.waitKey() + + +def picture_show_gray(data, h, w): # type: (list[int], int, int) -> None + new_data = np.array(data).reshape(h, w, 1).astype(np.uint8) + cv.imshow('data', new_data) + cv.waitKey() + + +def main(): # type: () -> None + parser = argparse.ArgumentParser(description='which mode need to show') + + parser.add_argument( + '--pic_path', + type=str, + help='What is the path of your picture', + required=True) + + parser.add_argument( + '--pic_type', + type=str, + help='What type you want to show', + required=True, + choices=['rgb565', 'rgb888', 'gray']) + + parser.add_argument( + '--hight', + type=int, + help='the picture hight', + default=480) + + parser.add_argument( + '--width', + type=int, + help='the picture width', + default=640) + + args = parser.parse_args() + + hight = args.hight + width = args.width + + data = open_picture(args.pic_path) + + if (args.pic_type == 'rgb565'): + picture_show_rgb565(data, hight, width) + elif (args.pic_type == 'rgb888'): + picture_show_rgb888(data, hight, width) + elif (args.pic_type == 'gray'): + picture_show_gray(data, hight, width) + else: + print('This type is not supported in this script!') + + +if __name__ == '__main__': + main() diff --git a/examples/peripherals/jpeg/jpeg_decode/requirements.txt b/examples/peripherals/jpeg/jpeg_decode/requirements.txt new file mode 100644 index 0000000000..b96544bd0b --- /dev/null +++ b/examples/peripherals/jpeg/jpeg_decode/requirements.txt @@ -0,0 +1,2 @@ +opencv-python +numpy diff --git a/examples/peripherals/jpeg/jpeg_decode/resources/esp1080.jpg b/examples/peripherals/jpeg/jpeg_decode/resources/esp1080.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a1e6c497fdc8c1a7cd63423bc59c48598cef9996 GIT binary patch literal 49420 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 N(KJ9@8nFL=69C$q)WiS) literal 0 HcmV?d00001 diff --git a/examples/peripherals/jpeg/jpeg_decode/resources/esp720.jpg b/examples/peripherals/jpeg/jpeg_decode/resources/esp720.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bebb64a761cd5dde0ebdb30b6581e3b4d7f21c75 GIT binary patch literal 24087 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 literal 0 HcmV?d00001 diff --git a/examples/peripherals/jpeg/jpeg_decode/sdkconfig.defaults b/examples/peripherals/jpeg/jpeg_decode/sdkconfig.defaults new file mode 100644 index 0000000000..38db6f4e61 --- /dev/null +++ b/examples/peripherals/jpeg/jpeg_decode/sdkconfig.defaults @@ -0,0 +1,6 @@ +# SPIRAM configurations + +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_HEX=y +CONFIG_SPIRAM_SPEED_200M=y