@@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
project(test_esp_gmf_core)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRC_DIRS "." "elements"
|
||||
INCLUDE_DIRS "." "elements"
|
||||
REQUIRES unity esp_codec_dev esp_gdbstub
|
||||
EMBED_FILES "hi_lexin.pcm" "test_48000hz_16bit_2ch_5000ms.flac"
|
||||
WHOLE_ARCHIVE)
|
||||
+597
@@ -0,0 +1,597 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_bit_defs.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#include "esp_gmf_element.h"
|
||||
#include "esp_gmf_oal_mem.h"
|
||||
#include "esp_gmf_obj.h"
|
||||
#include "esp_gmf_port.h"
|
||||
#include "esp_gmf_job.h"
|
||||
#include "esp_gmf_cap.h"
|
||||
#include "esp_gmf_caps_def.h"
|
||||
|
||||
#include "esp_gmf_wn.h"
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32P4)
|
||||
#include "esp_afe_config.h"
|
||||
#include "esp_gmf_afe_manager.h"
|
||||
#include "esp_gmf_afe.h"
|
||||
#include "esp_gmf_aec.h"
|
||||
#include "esp_dsp.h"
|
||||
#endif /* defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32P4) */
|
||||
#include "esp_gmf_app_setup_peripheral.h"
|
||||
|
||||
#define DEBUG2FILE (false)
|
||||
#define FS 16000
|
||||
#define DURATION 1
|
||||
#define SIGNAL_LEN (FS * DURATION)
|
||||
#define STEREO_LEN (SIGNAL_LEN * 2)
|
||||
#define DELAY 0
|
||||
#define ATTENUATION 0.1
|
||||
|
||||
#define WAKEUP_DETECTED (BIT0)
|
||||
#define VAD_DETECTED (BIT1)
|
||||
#define VCMD_FOUND (BIT2)
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define AEC_ENABLE (false)
|
||||
#define MN_ENABLE (false)
|
||||
#define EVENTS_2_WAIT (WAKEUP_DETECTED | VAD_DETECTED)
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32P4)
|
||||
#define AEC_ENABLE (true)
|
||||
#define MN_ENABLE (true)
|
||||
#define EVENTS_2_WAIT (WAKEUP_DETECTED | VAD_DETECTED | VCMD_FOUND)
|
||||
#else
|
||||
#define AEC_ENABLE (false)
|
||||
#define MN_ENABLE (false)
|
||||
#define EVENTS_2_WAIT (WAKEUP_DETECTED)
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32 */
|
||||
|
||||
static const char *TAG = "AI_AUDIO_TEST";
|
||||
static uint32_t out_count = 0;
|
||||
static EventGroupHandle_t g_event_group = NULL;
|
||||
extern const uint8_t hi_lexin_pcm_start[] asm("_binary_hi_lexin_pcm_start");
|
||||
extern const uint8_t hi_lexin_pcm_end[] asm("_binary_hi_lexin_pcm_end");
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32P4)
|
||||
void generate_reference_signal(int16_t *signal, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
double t = (double)i / FS;
|
||||
double value = sin(2 * M_PI * 1000 * t);
|
||||
signal[i] = (int16_t)(value * 32767);
|
||||
}
|
||||
}
|
||||
|
||||
void generate_noise(int16_t *noise_buffer, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
double t = (double)i / FS;
|
||||
double value = sin(2 * M_PI * 2000 * t);
|
||||
noise_buffer[i] = (int16_t)(value * 32767 * ATTENUATION);
|
||||
}
|
||||
}
|
||||
|
||||
void generate_echo_signal(int16_t *reference, int16_t *noise_buffer, int16_t *echo, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
int idx = (i - DELAY) >= 0 ? (i - DELAY) : 0;
|
||||
double echo_sample = reference[idx] * ATTENUATION;
|
||||
echo_sample += noise_buffer[i];
|
||||
if (echo_sample > 32767) {
|
||||
echo_sample = 32767;
|
||||
}
|
||||
if (echo_sample < -32768) {
|
||||
echo_sample = -32768;
|
||||
}
|
||||
|
||||
echo[i] = (int16_t)echo_sample;
|
||||
}
|
||||
}
|
||||
|
||||
void create_stereo_pcm(int16_t *reference, int16_t *echo, int length, int16_t *stereo)
|
||||
{
|
||||
for (int i = 0; i < length; i++) {
|
||||
stereo[2 * i] = reference[i];
|
||||
stereo[2 * i + 1] = echo[i];
|
||||
}
|
||||
}
|
||||
|
||||
void analyze_frequency(int16_t *pcm_data, uint32_t n_samples)
|
||||
{
|
||||
float *real = (float *)esp_gmf_oal_malloc_align(16, n_samples * 2 * sizeof(float));
|
||||
float *hanning_win = (float *)esp_gmf_oal_malloc_align(16, n_samples * sizeof(float));
|
||||
TEST_ASSERT_NOT_NULL(real);
|
||||
TEST_ASSERT_NOT_NULL(hanning_win);
|
||||
|
||||
// Perform FFT
|
||||
TEST_ASSERT_EQUAL(ESP_OK, dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE));
|
||||
dsps_wind_hann_f32(hanning_win, n_samples);
|
||||
for (int i = 0; i < n_samples; i++) {
|
||||
real[i * 2 + 0] = ((float)pcm_data[i] / 32768.0f) * hanning_win[i];
|
||||
real[i * 2 + 1] = 0;
|
||||
}
|
||||
|
||||
dsps_fft2r_fc32(real, n_samples);
|
||||
dsps_bit_rev_fc32(real, n_samples);
|
||||
dsps_cplx2reC_fc32(real, n_samples);
|
||||
|
||||
for (int i = 0; i < n_samples >> 1; i++) {
|
||||
real[i] = 10 * log10f((real[i * 2 + 0] * real[i * 2 + 0] + real[i * 2 + 1] * real[i * 2 + 1]) / n_samples);
|
||||
}
|
||||
|
||||
// dsps_view(real, n_samples / 2, 64, 10, -60, 40, '|');
|
||||
float max_energy = -INFINITY;
|
||||
int max_index = 0;
|
||||
for (int i = 0; i < n_samples >> 1; i++) {
|
||||
if (real[i] > max_energy) {
|
||||
max_energy = real[i];
|
||||
max_index = i;
|
||||
}
|
||||
}
|
||||
float max_frequency = (float)max_index * FS / n_samples;
|
||||
if (max_energy > -20) {
|
||||
TEST_ASSERT_EQUAL(2000, (int)max_frequency);
|
||||
}
|
||||
|
||||
esp_gmf_oal_free(real);
|
||||
esp_gmf_oal_free(hanning_win);
|
||||
dsps_fft2r_deinit_fc32();
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t aec_acquire_read(void *handle, esp_gmf_payload_t *load, int wanted_size, int block_ticks)
|
||||
{
|
||||
uint8_t *src = (uint8_t *)handle;
|
||||
static int count = 0;
|
||||
if (load->buf == NULL) {
|
||||
return ESP_GMF_IO_FAIL;
|
||||
}
|
||||
esp_gmf_err_io_t ret = ESP_GMF_IO_OK;
|
||||
if (count < STEREO_LEN * 2) {
|
||||
if (count + wanted_size > STEREO_LEN * 2) {
|
||||
wanted_size = STEREO_LEN * 2 - count;
|
||||
}
|
||||
memcpy(load->buf, &src[count], wanted_size);
|
||||
count += wanted_size;
|
||||
load->valid_size = wanted_size;
|
||||
|
||||
if (count == STEREO_LEN * 2) {
|
||||
load->is_done = true;
|
||||
}
|
||||
} else {
|
||||
load->valid_size = 0;
|
||||
load->is_done = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t aec_release_read(void *handle, esp_gmf_payload_t *load, int block_ticks)
|
||||
{
|
||||
load->valid_size = 0;
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t aec_acquire_write(void *handle, esp_gmf_payload_t *load, int wanted_size, int block_ticks)
|
||||
{
|
||||
if (load->buf == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t aec_release_write(void *handle, esp_gmf_payload_t *load, int block_ticks)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)handle;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
||||
analyze_frequency((int16_t *)load->buf, load->valid_size / 2);
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32S3 */
|
||||
if (out_count < SIGNAL_LEN * 2) {
|
||||
if (out_count + load->valid_size > SIGNAL_LEN * 2) {
|
||||
load->valid_size = SIGNAL_LEN * 2 - out_count;
|
||||
}
|
||||
memcpy(&dest[out_count], load->buf, load->valid_size);
|
||||
out_count += load->valid_size;
|
||||
if (out_count == SIGNAL_LEN * 2) {
|
||||
load->is_done = true;
|
||||
}
|
||||
} else {
|
||||
load->valid_size = 0;
|
||||
load->is_done = true;
|
||||
}
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
TEST_CASE("Test gmf aec process", "[ESP_GMF_AEC]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
|
||||
printf("\r\n///////////////////// AEC /////////////////////\r\n");
|
||||
#if DEBUG2FILE == true
|
||||
void *sdcard_handle = NULL;
|
||||
esp_gmf_app_setup_sdcard(&sdcard_handle);
|
||||
#endif /* DEBUG2FILE == true */
|
||||
int16_t *reference_signal = (int16_t *)esp_gmf_oal_malloc_align(16, SIGNAL_LEN * sizeof(int16_t));
|
||||
TEST_ASSERT_NOT_NULL(reference_signal);
|
||||
int16_t *echo_signal = (int16_t *)esp_gmf_oal_malloc_align(16, SIGNAL_LEN * sizeof(int16_t));
|
||||
TEST_ASSERT_NOT_NULL(echo_signal);
|
||||
int16_t *stereo_signal = (int16_t *)esp_gmf_oal_malloc_align(16, STEREO_LEN * sizeof(int16_t));
|
||||
TEST_ASSERT_NOT_NULL(stereo_signal);
|
||||
int16_t *output_signal = (int16_t *)esp_gmf_oal_malloc_align(16, SIGNAL_LEN * sizeof(int16_t));
|
||||
TEST_ASSERT_NOT_NULL(output_signal);
|
||||
int16_t *noise_buffer = (int16_t *)esp_gmf_oal_malloc_align(16, SIGNAL_LEN * sizeof(int16_t));
|
||||
TEST_ASSERT_NOT_NULL(noise_buffer);
|
||||
generate_reference_signal(reference_signal, SIGNAL_LEN);
|
||||
generate_noise(noise_buffer, SIGNAL_LEN);
|
||||
generate_echo_signal(reference_signal, noise_buffer, echo_signal, SIGNAL_LEN);
|
||||
create_stereo_pcm(reference_signal, echo_signal, SIGNAL_LEN, stereo_signal);
|
||||
|
||||
esp_gmf_port_handle_t in_port = NEW_ESP_GMF_PORT_IN_BYTE(aec_acquire_read, aec_release_read, NULL, stereo_signal, 1024, 100);
|
||||
esp_gmf_port_handle_t out_port = NEW_ESP_GMF_PORT_OUT_BYTE(aec_acquire_write, aec_release_write, NULL, output_signal, 1024, 100);
|
||||
|
||||
esp_gmf_element_handle_t gmf_aec_handle = NULL;
|
||||
esp_gmf_aec_cfg_t gmf_aec_cfg = {
|
||||
.filter_len = 4,
|
||||
.type = AFE_TYPE_VC,
|
||||
.mode = AFE_MODE_HIGH_PERF,
|
||||
.input_format = (char *)"RM",
|
||||
};
|
||||
esp_gmf_aec_init(&gmf_aec_cfg, &gmf_aec_handle);
|
||||
esp_gmf_cap_t *caps = NULL;
|
||||
esp_gmf_cap_t *out_caps = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_get_caps(gmf_aec_handle, (const esp_gmf_cap_t **)&caps));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_cap_fetch_node(caps, ESP_GMF_CAPS_AUDIO_AEC, &out_caps));
|
||||
|
||||
esp_gmf_element_register_in_port(gmf_aec_handle, in_port);
|
||||
esp_gmf_element_register_out_port(gmf_aec_handle, out_port);
|
||||
esp_gmf_element_process_open(gmf_aec_handle, NULL);
|
||||
esp_gmf_job_err_t ret = ESP_GMF_JOB_ERR_OK;
|
||||
do {
|
||||
ret = esp_gmf_element_process_running(gmf_aec_handle, NULL);
|
||||
if (ret == ESP_GMF_JOB_ERR_FAIL) {
|
||||
ESP_LOGE(TAG, "AEC process failed");
|
||||
break;
|
||||
} else if (ret == ESP_GMF_JOB_ERR_DONE) {
|
||||
ESP_LOGI(TAG, "AEC process done");
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
esp_gmf_element_process_close(gmf_aec_handle, NULL);
|
||||
esp_gmf_obj_delete(gmf_aec_handle);
|
||||
|
||||
#if DEBUG2FILE == true
|
||||
FILE *fp = fopen("/sdcard/reference_signal.pcm", "wb");
|
||||
if (fp) {
|
||||
fwrite(reference_signal, sizeof(int16_t), SIGNAL_LEN, fp);
|
||||
fclose(fp);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to open reference_signal.pcm for writing");
|
||||
}
|
||||
fp = fopen("/sdcard/echo_signal.pcm", "wb");
|
||||
if (fp) {
|
||||
fwrite(echo_signal, sizeof(int16_t), SIGNAL_LEN, fp);
|
||||
fclose(fp);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to open echo_signal.pcm for writing");
|
||||
}
|
||||
fp = fopen("/sdcard/output_signal.pcm", "wb");
|
||||
if (fp) {
|
||||
fwrite(output_signal, 1, out_count, fp);
|
||||
fclose(fp);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to open output_signal.pcm for writing");
|
||||
}
|
||||
fp = fopen("/sdcard/stereo_signal.pcm", "wb");
|
||||
if (fp) {
|
||||
fwrite(stereo_signal, sizeof(int16_t), STEREO_LEN, fp);
|
||||
fclose(fp);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to open stereo_signal.pcm for writing");
|
||||
}
|
||||
fp = fopen("/sdcard/noise_buffer.pcm", "wb");
|
||||
if (fp) {
|
||||
fwrite(noise_buffer, sizeof(int16_t), SIGNAL_LEN, fp);
|
||||
fclose(fp);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to open noise_buffer.pcm for writing");
|
||||
}
|
||||
esp_gmf_app_teardown_sdcard(sdcard_handle);
|
||||
#endif /* DEBUG2FILE == true */
|
||||
out_count = 0;
|
||||
esp_gmf_oal_free(noise_buffer);
|
||||
esp_gmf_oal_free(reference_signal);
|
||||
esp_gmf_oal_free(echo_signal);
|
||||
esp_gmf_oal_free(stereo_signal);
|
||||
esp_gmf_oal_free(output_signal);
|
||||
}
|
||||
|
||||
TEST_CASE("Test gmf afe manager create", "[ESP_GMF_AFE_MANAGER]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
|
||||
printf("\r\n///////////////////// AFE MANAGER CREATE /////////////////////\r\n");
|
||||
|
||||
esp_gmf_afe_manager_handle_t afe_manager = NULL;
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
const char *ch_format = "MR";
|
||||
afe_config_t *afe_cfg = afe_config_init(ch_format, models, AFE_TYPE_SR, AFE_MODE_HIGH_PERF);
|
||||
afe_cfg->vad_init = true;
|
||||
afe_cfg->vad_mode = VAD_MODE_2;
|
||||
afe_cfg->vad_min_speech_ms = 64;
|
||||
afe_cfg->vad_min_noise_ms = 100;
|
||||
afe_cfg->wakenet_init = true;
|
||||
afe_cfg->aec_init = true;
|
||||
esp_gmf_afe_manager_cfg_t afe_manager_cfg = DEFAULT_GMF_AFE_MANAGER_CFG(afe_cfg, NULL, NULL, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_afe_manager_create(&afe_manager_cfg, &afe_manager));
|
||||
afe_config_free(afe_cfg);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_afe_manager_destroy(afe_manager));
|
||||
esp_srmodel_deinit(models);
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t afe_acquire_read(void *handle, esp_gmf_payload_t *load, int wanted_size, int block_ticks)
|
||||
{
|
||||
static int offset = 0;
|
||||
const uint8_t *src = hi_lexin_pcm_start;
|
||||
int total_size = hi_lexin_pcm_end - hi_lexin_pcm_start;
|
||||
|
||||
if (offset < total_size) {
|
||||
if (offset + wanted_size > total_size) {
|
||||
wanted_size = total_size - offset;
|
||||
}
|
||||
memcpy(load->buf, &src[offset], wanted_size);
|
||||
offset += wanted_size;
|
||||
load->valid_size = wanted_size;
|
||||
|
||||
if (offset == total_size) {
|
||||
offset = 0;
|
||||
load->is_done = true;
|
||||
}
|
||||
} else {
|
||||
load->valid_size = 0;
|
||||
load->is_done = true;
|
||||
}
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t afe_release_read(void *handle, esp_gmf_payload_t *load, int block_ticks)
|
||||
{
|
||||
load->valid_size = 0;
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t afe_acquire_write(void *handle, esp_gmf_payload_t *load, int wanted_size, int block_ticks)
|
||||
{
|
||||
if (load->buf == NULL) {
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t afe_release_write(void *handle, esp_gmf_payload_t *load, int block_ticks)
|
||||
{
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
void esp_gmf_afe_event_cb(esp_gmf_obj_handle_t obj, esp_gmf_afe_evt_t *event, void *user_data)
|
||||
{
|
||||
switch (event->type) {
|
||||
case ESP_GMF_AFE_EVT_WAKEUP_START: {
|
||||
xEventGroupSetBits(g_event_group, WAKEUP_DETECTED);
|
||||
#if MN_ENABLE == true
|
||||
esp_gmf_afe_vcmd_detection_cancel(obj);
|
||||
esp_gmf_afe_vcmd_detection_begin(obj);
|
||||
#endif /* MN_ENABLE == true */
|
||||
esp_gmf_afe_wakeup_info_t *info = event->event_data;
|
||||
ESP_LOGI(TAG, "WAKEUP_START [%d : %d]", info->wake_word_index, info->wakenet_model_index);
|
||||
break;
|
||||
}
|
||||
case ESP_GMF_AFE_EVT_WAKEUP_END: {
|
||||
#if MN_ENABLE == true
|
||||
esp_gmf_afe_vcmd_detection_cancel(obj);
|
||||
#endif /* MN_ENABLE == true */
|
||||
ESP_LOGI(TAG, "WAKEUP_END");
|
||||
break;
|
||||
}
|
||||
case ESP_GMF_AFE_EVT_VAD_START: {
|
||||
xEventGroupSetBits(g_event_group, VAD_DETECTED);
|
||||
ESP_LOGI(TAG, "VAD_START");
|
||||
break;
|
||||
}
|
||||
case ESP_GMF_AFE_EVT_VAD_END: {
|
||||
ESP_LOGI(TAG, "VAD_END");
|
||||
break;
|
||||
}
|
||||
case ESP_GMF_AFE_EVT_VCMD_DECT_TIMEOUT: {
|
||||
ESP_LOGI(TAG, "VCMD_DECT_TIMEOUT");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
esp_gmf_afe_vcmd_info_t *info = event->event_data;
|
||||
ESP_LOGW(TAG, "Command %d, phrase_id %d, prob %f, str: %s",
|
||||
event->type, info->phrase_id, info->prob, info->str);
|
||||
if (event->type == 25 || event->type == 216) {
|
||||
// 25: "da kai kong tiao"
|
||||
// 216: "kai kong tiao"
|
||||
xEventGroupSetBits(g_event_group, VCMD_FOUND);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test gmf afe process", "[ESP_GMF_AFE]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
|
||||
printf("\r\n///////////////////// AFE /////////////////////\r\n");
|
||||
g_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT_NOT_NULL(g_event_group);
|
||||
|
||||
esp_gmf_port_handle_t in_port = NEW_ESP_GMF_PORT_IN_BYTE(afe_acquire_read, afe_release_read, NULL, NULL, 1024, 100);
|
||||
esp_gmf_port_handle_t out_port = NEW_ESP_GMF_PORT_OUT_BYTE(afe_acquire_write, afe_release_write, NULL, NULL, 1024, 100);
|
||||
|
||||
esp_gmf_afe_manager_handle_t afe_manager = NULL;
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
const char *ch_format = "MR";
|
||||
afe_config_t *afe_cfg = afe_config_init(ch_format, models, AFE_TYPE_SR, AFE_MODE_HIGH_PERF);
|
||||
afe_cfg->vad_init = true;
|
||||
afe_cfg->vad_mode = VAD_MODE_2;
|
||||
afe_cfg->vad_min_speech_ms = 64;
|
||||
afe_cfg->vad_min_noise_ms = 100;
|
||||
afe_cfg->wakenet_init = true;
|
||||
afe_cfg->aec_init = AEC_ENABLE;
|
||||
esp_gmf_afe_manager_cfg_t afe_manager_cfg = DEFAULT_GMF_AFE_MANAGER_CFG(afe_cfg, NULL, NULL, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_afe_manager_create(&afe_manager_cfg, &afe_manager));
|
||||
esp_gmf_element_handle_t gmf_afe = NULL;
|
||||
esp_gmf_afe_cfg_t gmf_afe_cfg = DEFAULT_GMF_AFE_CFG(afe_manager, esp_gmf_afe_event_cb, NULL, models);
|
||||
gmf_afe_cfg.vcmd_detect_en = MN_ENABLE;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_afe_init(&gmf_afe_cfg, &gmf_afe));
|
||||
esp_gmf_cap_t *caps = NULL;
|
||||
esp_gmf_cap_t *out_caps = {0};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_get_caps(gmf_afe, (const esp_gmf_cap_t **)&caps));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_cap_fetch_node(caps, ESP_GMF_CAPS_AUDIO_AEC, &out_caps));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_cap_fetch_node(caps, ESP_GMF_CAPS_AUDIO_NS, &out_caps));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_cap_fetch_node(caps, ESP_GMF_CAPS_AUDIO_AGC, &out_caps));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_cap_fetch_node(caps, ESP_GMF_CAPS_AUDIO_VAD, &out_caps));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_cap_fetch_node(caps, ESP_GMF_CAPS_AUDIO_WWE, &out_caps));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_cap_fetch_node(caps, ESP_GMF_CAPS_AUDIO_VCMD, &out_caps));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_register_in_port(gmf_afe, in_port));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_register_out_port(gmf_afe, out_port));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_process_open(gmf_afe, NULL));
|
||||
esp_gmf_job_err_t ret = ESP_GMF_JOB_ERR_OK;
|
||||
do {
|
||||
ret = esp_gmf_element_process_running(gmf_afe, NULL);
|
||||
if (ret == ESP_GMF_JOB_ERR_FAIL) {
|
||||
ESP_LOGE(TAG, "AFE process failed");
|
||||
break;
|
||||
} else if (ret == ESP_GMF_JOB_ERR_DONE) {
|
||||
ESP_LOGI(TAG, "AFE process done");
|
||||
break;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
} while (true);
|
||||
TEST_ASSERT_EQUAL(EVENTS_2_WAIT, xEventGroupWaitBits(g_event_group, EVENTS_2_WAIT, pdTRUE, pdTRUE, pdMS_TO_TICKS(10 * 1000)));
|
||||
esp_gmf_element_process_close(gmf_afe, NULL);
|
||||
esp_gmf_obj_delete(gmf_afe);
|
||||
afe_config_free(afe_cfg);
|
||||
esp_gmf_afe_manager_destroy(afe_manager);
|
||||
esp_srmodel_deinit(models);
|
||||
vEventGroupDelete(g_event_group);
|
||||
g_event_group = NULL;
|
||||
}
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4 */
|
||||
|
||||
static esp_gmf_err_io_t wn_acquire_read(void *handle, esp_gmf_payload_t *load, int wanted_size, int block_ticks)
|
||||
{
|
||||
static int offset = 0;
|
||||
const uint8_t *src = hi_lexin_pcm_start;
|
||||
int total_size = hi_lexin_pcm_end - hi_lexin_pcm_start;
|
||||
|
||||
if (offset < total_size) {
|
||||
if (offset + wanted_size > total_size) {
|
||||
wanted_size = total_size - offset;
|
||||
}
|
||||
memcpy(load->buf, &src[offset], wanted_size);
|
||||
offset += wanted_size;
|
||||
load->valid_size = wanted_size;
|
||||
|
||||
if (offset == total_size) {
|
||||
offset = 0;
|
||||
load->is_done = true;
|
||||
}
|
||||
} else {
|
||||
load->valid_size = 0;
|
||||
load->is_done = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t wn_release_read(void *handle, esp_gmf_payload_t *load, int block_ticks)
|
||||
{
|
||||
load->valid_size = 0;
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t wn_acquire_write(void *handle, esp_gmf_payload_t *load, int wanted_size, int block_ticks)
|
||||
{
|
||||
if (load->buf == NULL) {
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t wn_release_write(void *handle, esp_gmf_payload_t *load, int block_ticks)
|
||||
{
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
static void esp_gmf_wn_event_cb(esp_gmf_obj_handle_t obj, int32_t trigger_ch, void *user_ctx)
|
||||
{
|
||||
static int32_t cnt = 1;
|
||||
ESP_LOGI(TAG, "WWE detected on channel %" PRIu32 ", cnt: %" PRIi32, trigger_ch, cnt++);
|
||||
xEventGroupSetBits(g_event_group, WAKEUP_DETECTED);
|
||||
}
|
||||
|
||||
TEST_CASE("Test gmf wakenet process", "[ESP_GMF_WN]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
|
||||
printf("\r\n///////////////////// Wakenet /////////////////////\r\n");
|
||||
g_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT_NOT_NULL(g_event_group);
|
||||
|
||||
esp_gmf_port_handle_t in_port = NEW_ESP_GMF_PORT_IN_BYTE(wn_acquire_read, wn_release_read, NULL, NULL, 1024, 100);
|
||||
esp_gmf_port_handle_t out_port = NEW_ESP_GMF_PORT_OUT_BYTE(wn_acquire_write, wn_release_write, NULL, NULL, 1024, 100);
|
||||
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
const char *ch_format = "MR";
|
||||
esp_gmf_wn_cfg_t wn_cfg = {
|
||||
.input_format = (char *)ch_format,
|
||||
.det_mode = DET_MODE_95,
|
||||
.models = models,
|
||||
.detect_cb = esp_gmf_wn_event_cb,
|
||||
.user_ctx = NULL,
|
||||
};
|
||||
esp_gmf_element_handle_t gmf_wn = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_wn_init(&wn_cfg, &gmf_wn));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_register_in_port(gmf_wn, in_port));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_register_out_port(gmf_wn, out_port));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_process_open(gmf_wn, NULL));
|
||||
esp_gmf_job_err_t ret = ESP_GMF_JOB_ERR_OK;
|
||||
do {
|
||||
ret = esp_gmf_element_process_running(gmf_wn, NULL);
|
||||
if (ret == ESP_GMF_JOB_ERR_FAIL) {
|
||||
ESP_LOGE(TAG, "WN process failed");
|
||||
break;
|
||||
} else if (ret == ESP_GMF_JOB_ERR_DONE) {
|
||||
ESP_LOGI(TAG, "WN process done");
|
||||
break;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
} while (true);
|
||||
TEST_ASSERT_EQUAL(WAKEUP_DETECTED, xEventGroupWaitBits(g_event_group, WAKEUP_DETECTED, pdTRUE, pdTRUE, pdMS_TO_TICKS(10 * 1000)));
|
||||
esp_gmf_element_process_close(gmf_wn, NULL);
|
||||
esp_gmf_obj_delete(gmf_wn);
|
||||
esp_srmodel_deinit(models);
|
||||
vEventGroupDelete(g_event_group);
|
||||
g_event_group = NULL;
|
||||
}
|
||||
+530
@@ -0,0 +1,530 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
#include <string.h>
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "esp_gmf_element.h"
|
||||
#include "esp_gmf_pipeline.h"
|
||||
#include "esp_gmf_pool.h"
|
||||
#include "esp_gmf_oal_mem.h"
|
||||
#include "esp_gmf_oal_thread.h"
|
||||
#include "esp_gmf_port.h"
|
||||
#include "esp_gmf_obj.h"
|
||||
#include "esp_gmf_data_bus.h"
|
||||
#include "esp_gmf_new_databus.h"
|
||||
|
||||
#include "esp_gmf_bit_cvt.h"
|
||||
#include "esp_gmf_ch_cvt.h"
|
||||
#include "esp_gmf_eq.h"
|
||||
#include "esp_gmf_alc.h"
|
||||
#include "esp_gmf_fade.h"
|
||||
#include "esp_gmf_mixer.h"
|
||||
#include "esp_gmf_rate_cvt.h"
|
||||
#include "esp_gmf_sonic.h"
|
||||
#include "esp_gmf_interleave.h"
|
||||
#include "esp_gmf_deinterleave.h"
|
||||
#include "esp_gmf_audio_enc.h"
|
||||
#include "esp_gmf_audio_dec.h"
|
||||
#include "esp_audio_simple_dec_default.h"
|
||||
#include "esp_audio_enc_reg.h"
|
||||
#include "esp_audio_dec_reg.h"
|
||||
|
||||
#include "esp_gmf_app_setup_peripheral.h"
|
||||
#include "esp_audio_enc_default.h"
|
||||
#include "esp_audio_dec_default.h"
|
||||
#include "esp_audio_dec_reg.h"
|
||||
#include "esp_gmf_audio_helper.h"
|
||||
#include "esp_gmf_audio_methods_def.h"
|
||||
#include "esp_gmf_method.h"
|
||||
#include "esp_gmf_audio_param.h"
|
||||
#include "gmf_audio_play_com.h"
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
#include "media_lib_adapter.h"
|
||||
#include "media_lib_mem_trace.h"
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
|
||||
static const char *TAG = "AUDIO_EFFECTS_ELEMENT_TEST";
|
||||
|
||||
#define PIPELINE_BLOCK_BIT BIT(0)
|
||||
#define PIPELINE_BLOCK_RUN_BIT BIT(1)
|
||||
|
||||
#define ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT (4096)
|
||||
|
||||
static esp_err_t _pipeline_event(esp_gmf_event_pkt_t *event, void *ctx)
|
||||
{
|
||||
// The warning messages are used to make the content more noticeable.
|
||||
ESP_LOGW(TAG, "CB: RECV Pipeline EVT: el:%s-%p, type:%x, sub:%s, payload:%p, size:%d,%p",
|
||||
"OBJ_GET_TAG(event->from)", event->from, event->type, esp_gmf_event_get_state_str(event->sub),
|
||||
event->payload, event->payload_size, ctx);
|
||||
if ((event->sub == ESP_GMF_EVENT_STATE_STOPPED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_FINISHED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_ERROR)) {
|
||||
if (ctx) {
|
||||
xEventGroupSetBits((EventGroupHandle_t)ctx, PIPELINE_BLOCK_BIT);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp_err_t _pipeline_event2(esp_gmf_event_pkt_t *event, void *ctx)
|
||||
{
|
||||
ESP_LOGW(TAG, "CB: RECV Pipeline2 EVT: el:%s-%p, type:%d, sub:%s, payload:%p, size:%d,%p",
|
||||
"OBJ_GET_TAG(event->from)", event->from, event->type, esp_gmf_event_get_state_str(event->sub),
|
||||
event->payload, event->payload_size, ctx);
|
||||
if ((event->sub == ESP_GMF_EVENT_STATE_STOPPED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_FINISHED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_ERROR)) {
|
||||
xEventGroupSetBits((EventGroupHandle_t)ctx, PIPELINE_BLOCK_BIT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp_err_t _pipeline_event3(esp_gmf_event_pkt_t *event, void *ctx)
|
||||
{
|
||||
ESP_LOGW(TAG, "CB: RECV Pipeline3 EVT: el:%s-%p, type:%d, sub:%s, payload:%p, size:%d,%p",
|
||||
"OBJ_GET_TAG(event->from)", event->from, event->type, esp_gmf_event_get_state_str(event->sub),
|
||||
event->payload, event->payload_size, ctx);
|
||||
if ((event->sub == ESP_GMF_EVENT_STATE_STOPPED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_FINISHED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_ERROR)) {
|
||||
xEventGroupSetBits((EventGroupHandle_t)ctx, PIPELINE_BLOCK_BIT);
|
||||
}
|
||||
if (event->sub == ESP_GMF_EVENT_STATE_RUNNING) {
|
||||
if (ctx) {
|
||||
xEventGroupSetBits((EventGroupHandle_t)ctx, PIPELINE_BLOCK_RUN_BIT);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp_err_t _pipeline_event4(esp_gmf_event_pkt_t *event, void *ctx)
|
||||
{
|
||||
ESP_LOGW(TAG, "CB: RECV Pipeline4 EVT: el:%s-%p, type:%d, sub:%s, payload:%p, size:%d,%p",
|
||||
"OBJ_GET_TAG(event->from)", event->from, event->type, esp_gmf_event_get_state_str(event->sub),
|
||||
event->payload, event->payload_size, ctx);
|
||||
if ((event->sub == ESP_GMF_EVENT_STATE_STOPPED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_FINISHED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_ERROR)) {
|
||||
xEventGroupSetBits((EventGroupHandle_t)ctx, PIPELINE_BLOCK_BIT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_CASE("Audio Effects Play, [io_file->aud_dec->aud_rate_cvt->aud_ch_cvt->aud_bit_cvt->aud_sonic->aud_alc->aud_eq->aud_fade->io_codec_dev]", "[ESP_GMF_Effects]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("ESP_GMF_PIPELINE", ESP_LOG_DEBUG);
|
||||
esp_log_level_set("ESP_GMF_POOL", ESP_LOG_DEBUG);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
esp_gmf_app_setup_codec_dev(NULL);
|
||||
void *sdcard_handle = NULL;
|
||||
esp_gmf_app_setup_sdcard(&sdcard_handle);
|
||||
EventGroupHandle_t pipe_sync_evt = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt, return);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_pool_handle_t pool = NULL;
|
||||
esp_gmf_pool_init(&pool);
|
||||
TEST_ASSERT_NOT_NULL(pool);
|
||||
|
||||
gmf_register_audio_all(pool);
|
||||
|
||||
ESP_GMF_POOL_SHOW_ITEMS(pool);
|
||||
esp_gmf_pipeline_handle_t pipe = NULL;
|
||||
|
||||
const char *name[] = {"aud_dec", "aud_rate_cvt", "aud_ch_cvt", "aud_bit_cvt", "aud_sonic", "aud_alc", "aud_eq", "aud_fade"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, "io_file", name, sizeof(name) / sizeof(char *), "io_codec_dev", &pipe));
|
||||
TEST_ASSERT_NOT_NULL(pipe);
|
||||
|
||||
gmf_setup_pipeline_out_dev(pipe);
|
||||
esp_gmf_task_cfg_t cfg = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg.ctx = NULL;
|
||||
cfg.cb = NULL;
|
||||
esp_gmf_task_handle_t work_task = NULL;
|
||||
esp_gmf_task_init(&cfg, &work_task);
|
||||
TEST_ASSERT_NOT_NULL(work_task);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe, work_task));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe, _pipeline_event, pipe_sync_evt));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_reset(pipe));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_in_uri(pipe, "/sdcard/test.mp3"));
|
||||
esp_gmf_element_handle_t dec_el = NULL;
|
||||
esp_gmf_element_handle_t sonic_el = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_get_el_by_name(pipe, "aud_dec", &dec_el));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_get_el_by_name(pipe, "aud_sonic", &sonic_el));
|
||||
esp_gmf_info_sound_t info = {
|
||||
.format_id = ESP_AUDIO_SIMPLE_DEC_TYPE_MP3,
|
||||
};
|
||||
esp_gmf_audio_dec_reconfig_by_sound_info(dec_el, &info);
|
||||
esp_gmf_sonic_set_speed(sonic_el, 1.5f);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe));
|
||||
|
||||
vTaskDelay(2000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_pause(pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_resume(pipe));
|
||||
esp_gmf_sonic_set_pitch(sonic_el, 1.5f);
|
||||
xEventGroupWaitBits(pipe_sync_evt, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe));
|
||||
gmf_unregister_audio_all(pool);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_deinit(pool));
|
||||
vEventGroupDelete(pipe_sync_evt);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_app_teardown_sdcard(sdcard_handle);
|
||||
esp_gmf_app_teardown_codec_dev();
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
/***
|
||||
// Test deinterleave with two pipeline
|
||||
+-----+
|
||||
+- RB1 ->+ alc +-> RB3 -+
|
||||
+-------------------------------------+ | +-----+ | +-----------------------+
|
||||
| Pipe: file-->dec-->deinterleave |-- + +--| interleave-->rate_cvt |
|
||||
+---------------------+-------------- + | +-----+ | +-----------------------+
|
||||
+- RB2 ->+ alc +-> RB4 -+
|
||||
+-----+
|
||||
***/
|
||||
TEST_CASE("Audio Effects Data Weaver test", "[ESP_GMF_Effects]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("ESP_GMF_PIPELINE", ESP_LOG_DEBUG);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
esp_gmf_app_setup_codec_dev(NULL);
|
||||
void *sdcard_handle = NULL;
|
||||
esp_gmf_app_setup_sdcard(&sdcard_handle);
|
||||
EventGroupHandle_t pipe_sync_evt1 = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt1, return);
|
||||
EventGroupHandle_t pipe_sync_evt2 = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt2, return);
|
||||
EventGroupHandle_t pipe_sync_evt3 = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt3, return);
|
||||
EventGroupHandle_t pipe_sync_evt4 = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt4, return);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_pool_handle_t pool = NULL;
|
||||
esp_gmf_pool_init(&pool);
|
||||
TEST_ASSERT_NOT_NULL(pool);
|
||||
|
||||
gmf_register_audio_all(pool);
|
||||
|
||||
ESP_GMF_POOL_SHOW_ITEMS(pool);
|
||||
esp_gmf_pipeline_handle_t pipe1 = NULL;
|
||||
const char *name1[] = {"aud_dec", "aud_deintlv"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, "io_file", name1, sizeof(name1) / sizeof(char *), NULL, &pipe1));
|
||||
TEST_ASSERT_NOT_NULL(pipe1);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_in_uri(pipe1, "/sdcard/test.mp3"));
|
||||
esp_gmf_element_handle_t dec_el = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_get_el_by_name(pipe1, "aud_dec", &dec_el));
|
||||
esp_gmf_info_sound_t info = {
|
||||
.format_id = ESP_AUDIO_SIMPLE_DEC_TYPE_MP3,
|
||||
};
|
||||
esp_gmf_audio_dec_reconfig_by_sound_info(dec_el, &info);
|
||||
|
||||
esp_gmf_pipeline_handle_t pipe2 = NULL;
|
||||
const char *name2[] = {"aud_alc"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, NULL, name2, sizeof(name2) / sizeof(char *), NULL, &pipe2));
|
||||
TEST_ASSERT_NOT_NULL(pipe2);
|
||||
|
||||
esp_gmf_pipeline_handle_t pipe3 = NULL;
|
||||
const char *name3[] = {"aud_alc"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, NULL, name3, sizeof(name3) / sizeof(char *), NULL, &pipe3));
|
||||
TEST_ASSERT_NOT_NULL(pipe3);
|
||||
|
||||
esp_gmf_pipeline_handle_t pipe4 = NULL;
|
||||
const char *name4[] = {"aud_intlv", "aud_rate_cvt"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, NULL, name4, sizeof(name4) / sizeof(char *), "io_codec_dev", &pipe4));
|
||||
TEST_ASSERT_NOT_NULL(pipe4);
|
||||
|
||||
gmf_setup_pipeline_out_dev(pipe4);
|
||||
// create rb
|
||||
esp_gmf_db_handle_t db1 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_db_new_ringbuf(10, 1024, &db1));
|
||||
esp_gmf_port_handle_t out_port = NEW_ESP_GMF_PORT_OUT_BYTE(esp_gmf_db_acquire_write, esp_gmf_db_release_write, esp_gmf_db_deinit, db1,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 300);
|
||||
esp_gmf_port_handle_t in_port = NEW_ESP_GMF_PORT_IN_BYTE(esp_gmf_db_acquire_read, esp_gmf_db_release_read, esp_gmf_db_deinit, db1,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 300);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_connect_pipe(pipe1, "aud_deintlv", out_port, pipe2, "aud_alc", in_port));
|
||||
esp_gmf_db_handle_t db2 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_db_new_ringbuf(10, 1024, &db2));
|
||||
out_port = NEW_ESP_GMF_PORT_OUT_BYTE(esp_gmf_db_acquire_write, esp_gmf_db_release_write, esp_gmf_db_deinit, db2,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 3000);
|
||||
in_port = NEW_ESP_GMF_PORT_IN_BYTE(esp_gmf_db_acquire_read, esp_gmf_db_release_read, esp_gmf_db_deinit, db2,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 3000);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_connect_pipe(pipe1, "aud_deintlv", out_port, pipe3, "aud_alc", in_port));
|
||||
esp_gmf_db_handle_t db3 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_db_new_ringbuf(10, 1024, &db3));
|
||||
out_port = NEW_ESP_GMF_PORT_OUT_BYTE(esp_gmf_db_acquire_write, esp_gmf_db_release_write, esp_gmf_db_deinit, db3,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 3000);
|
||||
in_port = NEW_ESP_GMF_PORT_IN_BYTE(esp_gmf_db_acquire_read, esp_gmf_db_release_read, esp_gmf_db_deinit, db3,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 3000);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_connect_pipe(pipe2, "aud_alc", out_port, pipe4, "aud_intlv", in_port));
|
||||
esp_gmf_db_handle_t db4 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_db_new_ringbuf(10, 1024, &db4));
|
||||
out_port = NEW_ESP_GMF_PORT_OUT_BYTE(esp_gmf_db_acquire_write, esp_gmf_db_release_write, esp_gmf_db_deinit, db4,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 3000);
|
||||
in_port = NEW_ESP_GMF_PORT_IN_BYTE(esp_gmf_db_acquire_read, esp_gmf_db_release_read, esp_gmf_db_deinit, db4,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 3000);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_connect_pipe(pipe3, "aud_alc", out_port, pipe4, "aud_intlv", in_port));
|
||||
|
||||
esp_gmf_task_cfg_t cfg1 = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg1.ctx = NULL;
|
||||
cfg1.cb = NULL;
|
||||
cfg1.thread.core = 0;
|
||||
cfg1.thread.prio = 3;
|
||||
cfg1.name = "aud_deintlv";
|
||||
esp_gmf_task_handle_t work_task1 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_init(&cfg1, &work_task1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe1, work_task1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe1, _pipeline_event, pipe_sync_evt1));
|
||||
|
||||
esp_gmf_task_cfg_t cfg2 = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg2.thread.core = 0;
|
||||
cfg2.thread.prio = 3;
|
||||
cfg2.name = "channel1";
|
||||
esp_gmf_task_handle_t work_task2 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_init(&cfg2, &work_task2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe2, work_task2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe2, _pipeline_event2, pipe_sync_evt2));
|
||||
|
||||
esp_gmf_task_cfg_t cfg3 = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg3.ctx = NULL;
|
||||
cfg3.cb = NULL;
|
||||
cfg3.thread.core = 1;
|
||||
cfg3.thread.prio = 3;
|
||||
cfg3.name = "channel2";
|
||||
esp_gmf_task_handle_t work_task3 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_init(&cfg3, &work_task3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe3, work_task3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe3, _pipeline_event3, pipe_sync_evt3));
|
||||
|
||||
esp_gmf_task_cfg_t cfg4 = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg4.ctx = NULL;
|
||||
cfg4.cb = NULL;
|
||||
cfg4.thread.core = 0;
|
||||
cfg4.thread.prio = 3;
|
||||
cfg4.name = "aud_intlv";
|
||||
esp_gmf_task_handle_t work_task4 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_init(&cfg4, &work_task4));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe4, work_task4));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe4));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe4, _pipeline_event4, pipe_sync_evt4));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe4));
|
||||
|
||||
vTaskDelay(2000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_pause(pipe4));
|
||||
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_resume(pipe4));
|
||||
|
||||
xEventGroupWaitBits(pipe_sync_evt1, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
xEventGroupWaitBits(pipe_sync_evt2, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
xEventGroupWaitBits(pipe_sync_evt3, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
xEventGroupWaitBits(pipe_sync_evt4, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe4));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task4));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe4));
|
||||
gmf_unregister_audio_all(pool);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_deinit(pool));
|
||||
vEventGroupDelete(pipe_sync_evt1);
|
||||
vEventGroupDelete(pipe_sync_evt2);
|
||||
vEventGroupDelete(pipe_sync_evt3);
|
||||
vEventGroupDelete(pipe_sync_evt4);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_app_teardown_sdcard(sdcard_handle);
|
||||
esp_gmf_app_teardown_codec_dev();
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
/***
|
||||
// Test mix with two pipeline
|
||||
|
||||
+-------------------------------------+
|
||||
| Pipe1: file-->dec-->deinterleave |-+- RB1 -+
|
||||
+---------------------+-------------- + |
|
||||
| +-------+
|
||||
+-- | mixer |
|
||||
| +-------+
|
||||
+-------------------------------------+ |
|
||||
| Pipe1: file-->dec-->deinterleave |-+- RB2 -+
|
||||
+---------------------+-------------- +
|
||||
|
||||
***/
|
||||
TEST_CASE("Audio mixer Play", "[ESP_GMF_Effects]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("ESP_GMF_PIPELINE", ESP_LOG_DEBUG);
|
||||
esp_log_level_set("ESP_GMF_POOL", ESP_LOG_DEBUG);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_app_setup_codec_dev(NULL);
|
||||
void *sdcard_handle = NULL;
|
||||
esp_gmf_app_setup_sdcard(&sdcard_handle);
|
||||
EventGroupHandle_t pipe_sync_evt1 = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt1, return);
|
||||
|
||||
EventGroupHandle_t pipe_sync_evt2 = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt2, return);
|
||||
|
||||
EventGroupHandle_t pipe_sync_evt3 = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt3, return);
|
||||
|
||||
esp_gmf_pool_handle_t pool = NULL;
|
||||
esp_gmf_pool_init(&pool);
|
||||
TEST_ASSERT_NOT_NULL(pool);
|
||||
gmf_register_audio_all(pool);
|
||||
|
||||
ESP_GMF_POOL_SHOW_ITEMS(pool);
|
||||
esp_gmf_pipeline_handle_t pipe1 = NULL;
|
||||
const char *name1[] = {"aud_dec", "aud_rate_cvt", "aud_ch_cvt", "aud_bit_cvt"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, "io_file", name1, sizeof(name1) / sizeof(char *), NULL, &pipe1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_in_uri(pipe1, "/sdcard/test1.mp3"));
|
||||
esp_gmf_element_handle_t dec_el = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_get_el_by_name(pipe1, "aud_dec", &dec_el));
|
||||
esp_gmf_info_sound_t info = {
|
||||
.format_id = ESP_AUDIO_SIMPLE_DEC_TYPE_MP3,
|
||||
};
|
||||
esp_gmf_audio_dec_reconfig_by_sound_info(dec_el, &info);
|
||||
|
||||
esp_gmf_pipeline_handle_t pipe2 = NULL;
|
||||
const char *name2[] = {"aud_dec", "aud_rate_cvt", "aud_ch_cvt", "aud_bit_cvt"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, "io_file", name2, sizeof(name2) / sizeof(char *), NULL, &pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_in_uri(pipe2, "/sdcard/test.mp3"));
|
||||
dec_el = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_get_el_by_name(pipe2, "aud_dec", &dec_el));
|
||||
esp_gmf_audio_dec_reconfig_by_sound_info(dec_el, &info);
|
||||
|
||||
esp_gmf_pipeline_handle_t pipe3 = NULL;
|
||||
const char *name3[] = {"aud_mixer"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, NULL, name3, sizeof(name3) / sizeof(char *), "io_codec_dev", &pipe3));
|
||||
gmf_setup_pipeline_out_dev(pipe3);
|
||||
// create rb
|
||||
esp_gmf_db_handle_t db = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_db_new_ringbuf(10, 1024, &db));
|
||||
esp_gmf_db_handle_t db2 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_db_new_ringbuf(10, 1024, &db2));
|
||||
|
||||
esp_gmf_port_handle_t out_port = NEW_ESP_GMF_PORT_OUT_BYTE(esp_gmf_db_acquire_write, esp_gmf_db_release_write, esp_gmf_db_deinit, db,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 300);
|
||||
esp_gmf_port_handle_t in_port = NEW_ESP_GMF_PORT_IN_BYTE(esp_gmf_db_acquire_read, esp_gmf_db_release_read, esp_gmf_db_deinit, db,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 300);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_connect_pipe(pipe1, "aud_bit_cvt", out_port, pipe3, "aud_mixer", in_port));
|
||||
|
||||
out_port = NEW_ESP_GMF_PORT_OUT_BYTE(esp_gmf_db_acquire_write, esp_gmf_db_release_write, esp_gmf_db_deinit, db2,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 300);
|
||||
in_port = NEW_ESP_GMF_PORT_IN_BYTE(esp_gmf_db_acquire_read, esp_gmf_db_release_read, esp_gmf_db_deinit, db2,
|
||||
ESP_GMF_PORT_PAYLOAD_LEN_DEFAULT, 300);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_connect_pipe(pipe2, "aud_bit_cvt", out_port, pipe3, "aud_mixer", in_port));
|
||||
|
||||
esp_gmf_task_cfg_t cfg1 = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg1.ctx = NULL;
|
||||
cfg1.cb = NULL;
|
||||
cfg1.thread.core = 1;
|
||||
cfg1.thread.prio = 10;
|
||||
cfg1.name = "stream1";
|
||||
esp_gmf_task_handle_t work_task1 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_init(&cfg1, &work_task1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe1, work_task1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe1, _pipeline_event, pipe_sync_evt1));
|
||||
|
||||
esp_gmf_task_cfg_t cfg2 = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg2.thread.core = 0;
|
||||
cfg2.thread.prio = 10;
|
||||
cfg2.name = "stream2";
|
||||
esp_gmf_task_handle_t work_task2 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_init(&cfg2, &work_task2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe2, work_task2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe2, _pipeline_event2, pipe_sync_evt2));
|
||||
|
||||
esp_gmf_task_cfg_t cfg3 = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg3.ctx = NULL;
|
||||
cfg3.cb = NULL;
|
||||
cfg3.thread.core = 0;
|
||||
cfg3.thread.prio = 5;
|
||||
cfg3.name = "mix_process";
|
||||
esp_gmf_task_handle_t work_task3 = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_init(&cfg3, &work_task3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe3, work_task3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe3, _pipeline_event3, pipe_sync_evt3));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe3));
|
||||
esp_gmf_element_handle_t mixer_hd = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_get_el_by_name(pipe3, "aud_mixer", &mixer_hd));
|
||||
xEventGroupWaitBits(pipe_sync_evt3, PIPELINE_BLOCK_RUN_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
// set mode
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_mixer_set_mode(mixer_hd, 0, ESP_AE_MIXER_MODE_FADE_UPWARD));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_mixer_set_mode(mixer_hd, 1, ESP_AE_MIXER_MODE_FADE_DOWNWARD));
|
||||
|
||||
xEventGroupWaitBits(pipe_sync_evt1, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
xEventGroupWaitBits(pipe_sync_evt2, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe1));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task3));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe3));
|
||||
gmf_unregister_audio_all(pool);
|
||||
esp_gmf_pool_deinit(pool);
|
||||
vEventGroupDelete(pipe_sync_evt1);
|
||||
vEventGroupDelete(pipe_sync_evt2);
|
||||
vEventGroupDelete(pipe_sync_evt3);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_app_teardown_sdcard(sdcard_handle);
|
||||
esp_gmf_app_teardown_codec_dev();
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
+487
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "esp_gmf_audio_methods_def.h"
|
||||
#include "esp_gmf_method_helper.h"
|
||||
#include "esp_gmf_eq.h"
|
||||
#include "esp_gmf_fade.h"
|
||||
#include "esp_gmf_mixer.h"
|
||||
#include "esp_gmf_audio_enc.h"
|
||||
#include "esp_gmf_audio_dec.h"
|
||||
#include "esp_gmf_audio_param.h"
|
||||
#include "esp_gmf_args_desc.h"
|
||||
#include "gmf_audio_el_com.h"
|
||||
#include "esp_audio_enc_default.h"
|
||||
#include "esp_audio_dec_default.h"
|
||||
#include "esp_audio_simple_dec_default.h"
|
||||
|
||||
#define PREPARE_METHOD() \
|
||||
esp_gmf_method_exec_ctx_t exec_ctx = {}; \
|
||||
const esp_gmf_method_t *method_head = NULL; \
|
||||
esp_gmf_element_get_method(self, &method_head); \
|
||||
esp_gmf_err_t ret = esp_gmf_method_prepare_exec_ctx(method_head, method_name, &exec_ctx); \
|
||||
if (ret != ESP_GMF_ERR_OK) { \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define SET_METHOD_ARG(arg_name, value) \
|
||||
esp_gmf_args_set_value(exec_ctx.method->args_desc, arg_name, exec_ctx.exec_buf, (uint8_t *)&value, sizeof(value));
|
||||
|
||||
#define EXEC_METHOD() \
|
||||
ret = exec_ctx.method->func(self, exec_ctx.method->args_desc, exec_ctx.exec_buf, exec_ctx.buf_size);
|
||||
|
||||
#define GET_METHOD_ARG(arg_name, value) \
|
||||
esp_gmf_args_extract_value(exec_ctx.method->args_desc, arg_name, exec_ctx.exec_buf, exec_ctx.buf_size, (uint32_t *)value);
|
||||
|
||||
#define RELEASE_METHOD() \
|
||||
esp_gmf_method_release_exec_ctx(&exec_ctx);
|
||||
|
||||
// Audio effect parameter setting methods
|
||||
static esp_gmf_err_t audio_el_test_set_eq_filter_para(esp_gmf_element_handle_t self, uint8_t idx, esp_ae_eq_filter_para_t *para)
|
||||
{
|
||||
const char *method_name = AMETHOD(EQ, SET_PARA);
|
||||
PREPARE_METHOD();
|
||||
|
||||
SET_METHOD_ARG(AMETHOD_ARG(EQ, SET_PARA, IDX), idx);
|
||||
SET_METHOD_ARG(AMETHOD_ARG(EQ, SET_PARA, PARA), *para);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_get_eq_filter_para(esp_gmf_element_handle_t self, uint8_t idx, esp_ae_eq_filter_para_t *para)
|
||||
{
|
||||
const char *method_name = AMETHOD(EQ, GET_PARA);
|
||||
PREPARE_METHOD();
|
||||
|
||||
SET_METHOD_ARG(AMETHOD_ARG(EQ, GET_PARA, IDX), idx);
|
||||
EXEC_METHOD();
|
||||
GET_METHOD_ARG(AMETHOD_ARG(EQ, GET_PARA, PARA), para);
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_enable_eq_filter(esp_gmf_element_handle_t self, uint8_t idx, bool enable)
|
||||
{
|
||||
const char *method_name = AMETHOD(EQ, ENABLE_FILTER);
|
||||
PREPARE_METHOD();
|
||||
|
||||
SET_METHOD_ARG(AMETHOD_ARG(EQ, ENABLE_FILTER, IDX), idx);
|
||||
SET_METHOD_ARG(AMETHOD_ARG(EQ, ENABLE_FILTER, ENABLE), enable);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_get_encoder_frame_size(esp_gmf_element_handle_t self, uint32_t *in_size, uint32_t *out_size)
|
||||
{
|
||||
const char *method_name = AMETHOD(ENCODER, GET_FRAME_SZ);
|
||||
PREPARE_METHOD();
|
||||
EXEC_METHOD();
|
||||
GET_METHOD_ARG(AMETHOD_ARG(ENCODER, GET_FRAME_SZ, INSIZE), in_size);
|
||||
GET_METHOD_ARG(AMETHOD_ARG(ENCODER, GET_FRAME_SZ, OUTSIZE), out_size);
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_set_encoder_bitrate(esp_gmf_element_handle_t self, uint32_t bitrate)
|
||||
{
|
||||
const char *method_name = AMETHOD(ENCODER, SET_BITRATE);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(ENCODER, SET_BITRATE, BITRATE), bitrate);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_get_encoder_bitrate(esp_gmf_element_handle_t self, uint32_t *bitrate)
|
||||
{
|
||||
const char *method_name = AMETHOD(ENCODER, GET_BITRATE);
|
||||
PREPARE_METHOD();
|
||||
EXEC_METHOD();
|
||||
GET_METHOD_ARG(AMETHOD_ARG(ENCODER, GET_BITRATE, BITRATE), bitrate);
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_reconfig_encoder(esp_gmf_element_handle_t self, esp_audio_enc_config_t *cfg)
|
||||
{
|
||||
const char *method_name = AMETHOD(ENCODER, RECONFIG);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(ENCODER, RECONFIG, CFG), *cfg);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_reconfig_encoder_by_sound_info(esp_gmf_element_handle_t self, esp_gmf_info_sound_t *info)
|
||||
{
|
||||
const char *method_name = AMETHOD(ENCODER, RECONFIG_BY_SND_INFO);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(ENCODER, RECONFIG_BY_SND_INFO, INFO), *info);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_reconfig_decoder(esp_gmf_element_handle_t self, esp_audio_simple_dec_cfg_t *cfg)
|
||||
{
|
||||
const char *method_name = AMETHOD(DECODER, RECONFIG);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(DECODER, RECONFIG, CFG), *cfg);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_reconfig_decoder_by_sound_info(esp_gmf_element_handle_t self, esp_gmf_info_sound_t *info)
|
||||
{
|
||||
const char *method_name = AMETHOD(DECODER, RECONFIG_BY_SND_INFO);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(DECODER, RECONFIG_BY_SND_INFO, INFO), *info);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_set_fade_mode(esp_gmf_element_handle_t self, esp_ae_fade_mode_t mode)
|
||||
{
|
||||
const char *method_name = AMETHOD(FADE, SET_MODE);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(FADE, SET_MODE, MODE), mode);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_get_fade_mode(esp_gmf_element_handle_t self, esp_ae_fade_mode_t *mode)
|
||||
{
|
||||
const char *method_name = AMETHOD(FADE, GET_MODE);
|
||||
PREPARE_METHOD();
|
||||
EXEC_METHOD();
|
||||
GET_METHOD_ARG(AMETHOD_ARG(FADE, GET_MODE, MODE), mode);
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_reset_fade_weight(esp_gmf_element_handle_t self)
|
||||
{
|
||||
const char *method_name = AMETHOD(FADE, RESET_WEIGHT);
|
||||
PREPARE_METHOD();
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_set_mixer_mode(esp_gmf_element_handle_t self, uint8_t idx, esp_ae_mixer_mode_t mode)
|
||||
{
|
||||
const char *method_name = AMETHOD(MIXER, SET_MODE);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(MIXER, SET_MODE, IDX), idx);
|
||||
SET_METHOD_ARG(AMETHOD_ARG(MIXER, SET_MODE, MODE), mode);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_set_mixer_info(esp_gmf_element_handle_t self, uint32_t sample_rate, uint32_t channels, uint32_t bits)
|
||||
{
|
||||
const char *method_name = AMETHOD(MIXER, SET_INFO);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(MIXER, SET_INFO, RATE), sample_rate);
|
||||
SET_METHOD_ARG(AMETHOD_ARG(MIXER, SET_INFO, CH), channels);
|
||||
SET_METHOD_ARG(AMETHOD_ARG(MIXER, SET_INFO, BITS), bits);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_set_sonic_speed(esp_gmf_element_handle_t self, float speed)
|
||||
{
|
||||
const char *method_name = AMETHOD(SONIC, SET_SPEED);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(SONIC, SET_SPEED, SPEED), speed);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_get_sonic_speed(esp_gmf_element_handle_t self, float *speed)
|
||||
{
|
||||
const char *method_name = AMETHOD(SONIC, GET_SPEED);
|
||||
PREPARE_METHOD();
|
||||
EXEC_METHOD();
|
||||
GET_METHOD_ARG(AMETHOD_ARG(SONIC, GET_SPEED, SPEED), speed);
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_set_sonic_pitch(esp_gmf_element_handle_t self, float pitch)
|
||||
{
|
||||
const char *method_name = AMETHOD(SONIC, SET_PITCH);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(SONIC, SET_PITCH, PITCH), pitch);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_get_sonic_pitch(esp_gmf_element_handle_t self, float *pitch)
|
||||
{
|
||||
const char *method_name = AMETHOD(SONIC, GET_PITCH);
|
||||
PREPARE_METHOD();
|
||||
EXEC_METHOD();
|
||||
GET_METHOD_ARG(AMETHOD_ARG(SONIC, GET_PITCH, PITCH), pitch);
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_set_alc_gain(esp_gmf_element_handle_t self, uint8_t idx, int8_t gain)
|
||||
{
|
||||
const char *method_name = AMETHOD(ALC, SET_GAIN);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(ALC, SET_GAIN, IDX), idx);
|
||||
SET_METHOD_ARG(AMETHOD_ARG(ALC, SET_GAIN, GAIN), gain);
|
||||
EXEC_METHOD();
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t audio_el_test_get_alc_gain(esp_gmf_element_handle_t self, uint8_t idx, int8_t *gain)
|
||||
{
|
||||
const char *method_name = AMETHOD(ALC, GET_GAIN);
|
||||
PREPARE_METHOD();
|
||||
SET_METHOD_ARG(AMETHOD_ARG(ALC, GET_GAIN, IDX), idx);
|
||||
EXEC_METHOD();
|
||||
GET_METHOD_ARG(AMETHOD_ARG(ALC, GET_GAIN, GAIN), gain);
|
||||
RELEASE_METHOD();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void encoder_config_callback(esp_gmf_element_handle_t el, void *ctx)
|
||||
{
|
||||
audio_el_res_t *res = (audio_el_res_t *)ctx;
|
||||
esp_audio_enc_config_t enc_cfg = {0};
|
||||
uint32_t bitrate = 0;
|
||||
esp_gmf_event_state_t event_state = 0;
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
uint32_t in_size = 0, out_size = 0;
|
||||
esp_gmf_err_t ret = ESP_GMF_ERR_OK;
|
||||
if (event_state >= ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_encoder_frame_size(el, &in_size, &out_size));
|
||||
ret = esp_gmf_audio_enc_reconfig(el, &enc_cfg);
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
if (event_state >= ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_FAIL, ret);
|
||||
}
|
||||
ret = esp_gmf_audio_enc_reconfig_by_sound_info(el, &res->in_inst[0].src_info);
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
if (event_state >= ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_FAIL, ret);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Test AMRNB encoder configuration
|
||||
esp_amrnb_enc_config_t new_amrnb_cfg = {
|
||||
.sample_rate = 8000,
|
||||
.channel = 1,
|
||||
.bits_per_sample = 16,
|
||||
.dtx_enable = true,
|
||||
.bitrate_mode = ESP_AMRNB_ENC_BITRATE_MR122,
|
||||
.no_file_header = false};
|
||||
enc_cfg.type = ESP_AUDIO_TYPE_AMRNB;
|
||||
enc_cfg.cfg = &new_amrnb_cfg;
|
||||
enc_cfg.cfg_sz = sizeof(esp_amrnb_enc_config_t);
|
||||
ret = audio_el_test_reconfig_encoder(el, &enc_cfg);
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
if (event_state < ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, ret);
|
||||
// Verify AMRNB configuration
|
||||
esp_audio_enc_config_t *get_cfg = OBJ_GET_CFG(el);
|
||||
TEST_ASSERT_EQUAL(ESP_AUDIO_TYPE_AMRNB, get_cfg->type);
|
||||
esp_amrnb_enc_config_t *amrnb_cfg = (esp_amrnb_enc_config_t *)get_cfg->cfg;
|
||||
TEST_ASSERT_EQUAL(new_amrnb_cfg.sample_rate, amrnb_cfg->sample_rate);
|
||||
TEST_ASSERT_EQUAL(new_amrnb_cfg.channel, amrnb_cfg->channel);
|
||||
TEST_ASSERT_EQUAL(new_amrnb_cfg.bits_per_sample, amrnb_cfg->bits_per_sample);
|
||||
TEST_ASSERT_EQUAL(new_amrnb_cfg.dtx_enable, amrnb_cfg->dtx_enable);
|
||||
TEST_ASSERT_EQUAL(new_amrnb_cfg.bitrate_mode, amrnb_cfg->bitrate_mode);
|
||||
TEST_ASSERT_EQUAL(new_amrnb_cfg.no_file_header, amrnb_cfg->no_file_header);
|
||||
// Test bitrate interface
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_encoder_bitrate(el, 12200));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_encoder_bitrate(el, &bitrate));
|
||||
TEST_ASSERT_EQUAL(12200, bitrate);
|
||||
}
|
||||
// Test reconfiguration using sound info
|
||||
ret = audio_el_test_reconfig_encoder_by_sound_info(el, &res->in_inst[0].src_info);
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
if (event_state < ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, ret);
|
||||
// Verify AMRNB configuration
|
||||
esp_audio_enc_config_t *get_cfg = OBJ_GET_CFG(el);
|
||||
TEST_ASSERT_EQUAL(res->in_inst[0].src_info.format_id, get_cfg->type);
|
||||
}
|
||||
// Verify frame size after reconfiguration
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_encoder_frame_size(el, &in_size, &out_size));
|
||||
}
|
||||
|
||||
void decoder_config_callback(esp_gmf_element_handle_t el, void *ctx)
|
||||
{
|
||||
audio_el_res_t *res = (audio_el_res_t *)ctx;
|
||||
esp_audio_simple_dec_cfg_t dec_cfg = {0};
|
||||
esp_gmf_event_state_t event_state = 0;
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
esp_gmf_err_t ret = ESP_GMF_ERR_OK;
|
||||
if (event_state >= ESP_GMF_EVENT_STATE_OPENING) {
|
||||
ret = audio_el_test_reconfig_decoder(el, &dec_cfg);
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
if (event_state >= ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_FAIL, ret);
|
||||
}
|
||||
ret = audio_el_test_reconfig_decoder_by_sound_info(el, &res->in_inst[0].src_info);
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
if (event_state >= ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_FAIL, ret);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Test LC3 decoder configuration
|
||||
esp_lc3_dec_cfg_t new_lc3_cfg = {
|
||||
.sample_rate = 48000,
|
||||
.channel = 2,
|
||||
.bits_per_sample = 16,
|
||||
.frame_dms = 100,
|
||||
.is_cbr = 1,
|
||||
.len_prefixed = 1,
|
||||
.enable_plc = 1,
|
||||
.nbyte = 120};
|
||||
dec_cfg.dec_type = ESP_AUDIO_TYPE_LC3;
|
||||
dec_cfg.dec_cfg = &new_lc3_cfg;
|
||||
dec_cfg.cfg_size = sizeof(esp_lc3_dec_cfg_t);
|
||||
ret = audio_el_test_reconfig_decoder(el, &dec_cfg);
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
if (event_state < ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, ret);
|
||||
// Verify LC3 configuration
|
||||
esp_audio_simple_dec_cfg_t *get_cfg = OBJ_GET_CFG(el);
|
||||
TEST_ASSERT_EQUAL(ESP_AUDIO_TYPE_LC3, get_cfg->dec_type);
|
||||
esp_lc3_dec_cfg_t *lc3_cfg = (esp_lc3_dec_cfg_t *)get_cfg->dec_cfg;
|
||||
TEST_ASSERT_EQUAL(new_lc3_cfg.sample_rate, lc3_cfg->sample_rate);
|
||||
TEST_ASSERT_EQUAL(new_lc3_cfg.channel, lc3_cfg->channel);
|
||||
TEST_ASSERT_EQUAL(new_lc3_cfg.bits_per_sample, lc3_cfg->bits_per_sample);
|
||||
TEST_ASSERT_EQUAL(new_lc3_cfg.frame_dms, lc3_cfg->frame_dms);
|
||||
TEST_ASSERT_EQUAL(new_lc3_cfg.is_cbr, lc3_cfg->is_cbr);
|
||||
TEST_ASSERT_EQUAL(new_lc3_cfg.len_prefixed, lc3_cfg->len_prefixed);
|
||||
TEST_ASSERT_EQUAL(new_lc3_cfg.enable_plc, lc3_cfg->enable_plc);
|
||||
}
|
||||
// Test FLAC decoder configuration using sound info
|
||||
esp_gmf_info_sound_t dec_info = {
|
||||
.format_id = ESP_AUDIO_SIMPLE_DEC_TYPE_FLAC,
|
||||
.sample_rates = 48000,
|
||||
.channels = 2,
|
||||
.bits = 16,
|
||||
.bitrate = 0};
|
||||
ret = audio_el_test_reconfig_decoder_by_sound_info(el, &dec_info);
|
||||
esp_gmf_element_get_state(el, &event_state);
|
||||
if (event_state < ESP_GMF_EVENT_STATE_OPENING) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, ret);
|
||||
esp_audio_simple_dec_cfg_t *get_cfg = OBJ_GET_CFG(el);
|
||||
TEST_ASSERT_EQUAL(ESP_AUDIO_SIMPLE_DEC_TYPE_FLAC, get_cfg->dec_type);
|
||||
}
|
||||
}
|
||||
|
||||
void eq_config_callback(esp_gmf_element_handle_t self, void *ctx)
|
||||
{
|
||||
esp_ae_eq_filter_para_t filter_para[] = {
|
||||
{.fc = 100,
|
||||
.gain = 6.0f,
|
||||
.q = 1.0f,
|
||||
.filter_type = ESP_AE_EQ_FILTER_LOW_SHELF},
|
||||
{.fc = 1000,
|
||||
.gain = -3.0f,
|
||||
.q = 2.0f,
|
||||
.filter_type = ESP_AE_EQ_FILTER_PEAK},
|
||||
{.fc = 10000,
|
||||
.gain = 3.0f,
|
||||
.q = 1.0f,
|
||||
.filter_type = ESP_AE_EQ_FILTER_HIGH_SHELF}};
|
||||
esp_ae_eq_filter_para_t read_para = {0};
|
||||
for (int i = 0; i < sizeof(filter_para) / sizeof(filter_para[0]); i++) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_eq_filter_para(self, i, &filter_para[i]));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_eq_filter_para(self, i, &read_para));
|
||||
TEST_ASSERT_EQUAL(filter_para[i].fc, read_para.fc);
|
||||
TEST_ASSERT_EQUAL_FLOAT(filter_para[i].gain, read_para.gain);
|
||||
TEST_ASSERT_EQUAL_FLOAT(filter_para[i].q, read_para.q);
|
||||
TEST_ASSERT_EQUAL(filter_para[i].filter_type, read_para.filter_type);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_enable_eq_filter(self, i, true));
|
||||
}
|
||||
}
|
||||
|
||||
void fade_config_callback(esp_gmf_element_handle_t self, void *ctx)
|
||||
{
|
||||
esp_ae_fade_mode_t mode = 0;
|
||||
// Test fade mode setting and getting
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_fade_mode(self, ESP_AE_FADE_MODE_FADE_IN));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_fade_mode(self, &mode));
|
||||
TEST_ASSERT_EQUAL(ESP_AE_FADE_MODE_FADE_IN, mode);
|
||||
// Test fade weight reset
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_reset_fade_weight(self));
|
||||
}
|
||||
|
||||
void mixer_config_callback(esp_gmf_element_handle_t self, void *ctx)
|
||||
{
|
||||
// Test mixer mode setting for each channel
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_mixer_mode(self, 0, ESP_AE_MIXER_MODE_FADE_UPWARD));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_mixer_mode(self, 1, ESP_AE_MIXER_MODE_FADE_DOWNWARD));
|
||||
// Test mixer info setting
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_mixer_info(self, 48000, 2, 16));
|
||||
}
|
||||
|
||||
void sonic_config_callback(esp_gmf_element_handle_t self, void *ctx)
|
||||
{
|
||||
float speed = 0.0f;
|
||||
float pitch = 0.0f;
|
||||
// Test speed setting and getting
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_sonic_speed(self, 1.5f));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_sonic_speed(self, &speed));
|
||||
TEST_ASSERT_EQUAL_FLOAT(1.5f, speed);
|
||||
// Test pitch setting and getting
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_sonic_pitch(self, 1.2f));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_sonic_pitch(self, &pitch));
|
||||
TEST_ASSERT_EQUAL_FLOAT(1.2f, pitch);
|
||||
}
|
||||
|
||||
void alc_config_callback(esp_gmf_element_handle_t self, void *ctx)
|
||||
{
|
||||
audio_el_res_t *res = (audio_el_res_t *)ctx;
|
||||
int8_t gain = 0;
|
||||
for (int i = 0; i < res->in_inst[0].src_info.channels; i++) {
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_alc_gain(self, i, 2));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_alc_gain(self, i, &gain));
|
||||
TEST_ASSERT_EQUAL(2, gain);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_set_alc_gain(self, i, 1));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, audio_el_test_get_alc_gain(self, i, &gain));
|
||||
TEST_ASSERT_EQUAL(1, gain);
|
||||
}
|
||||
}
|
||||
|
||||
void bit_cvt_config_callback(esp_gmf_element_handle_t self, void *ctx)
|
||||
{
|
||||
audio_el_res_t *res = (audio_el_res_t *)ctx;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_param_set_dest_bits(self, res->out_inst[0].out_info.bits));
|
||||
}
|
||||
|
||||
void ch_cvt_config_callback(esp_gmf_element_handle_t self, void *ctx)
|
||||
{
|
||||
audio_el_res_t *res = (audio_el_res_t *)ctx;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_param_set_dest_ch(self, res->out_inst[0].out_info.channels));
|
||||
}
|
||||
|
||||
void rate_cvt_config_callback(esp_gmf_element_handle_t self, void *ctx)
|
||||
{
|
||||
audio_el_res_t *res = (audio_el_res_t *)ctx;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_param_set_dest_rate(self, res->out_inst[0].out_info.sample_rates));
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _GMF_AUDIO_EL_COM_H_
|
||||
#define _GMF_AUDIO_EL_COM_H_
|
||||
|
||||
#include "esp_gmf_element.h"
|
||||
#include "esp_gmf_pool.h"
|
||||
#include "esp_gmf_audio_param.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
uint8_t *data;
|
||||
size_t size;
|
||||
size_t buf_length;
|
||||
bool is_released;
|
||||
bool is_done;
|
||||
} sweep_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t in_frame_count;
|
||||
bool is_done;
|
||||
uint32_t src_codec;
|
||||
esp_gmf_info_sound_t src_info;
|
||||
uint8_t *src_data;
|
||||
uint32_t src_size;
|
||||
uint32_t in_acquire_count;
|
||||
uint32_t in_release_count;
|
||||
QueueHandle_t sweep_queue1;
|
||||
QueueHandle_t sweep_queue2;
|
||||
TaskHandle_t task_hd;
|
||||
esp_gmf_pipeline_handle_t pipeline;
|
||||
bool change_info;
|
||||
bool is_sweep_signal;
|
||||
} audio_el_in_test_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t out_codec;
|
||||
esp_gmf_info_sound_t out_info;
|
||||
uint8_t *out_data;
|
||||
uint32_t out_size;
|
||||
uint32_t out_frame_count;
|
||||
uint32_t out_max_size;
|
||||
bool no_need_free;
|
||||
uint32_t out_acquire_count;
|
||||
uint32_t out_release_count;
|
||||
} audio_el_out_test_t;
|
||||
|
||||
typedef struct {
|
||||
esp_gmf_pool_handle_t pool;
|
||||
esp_gmf_pipeline_handle_t pipe;
|
||||
esp_gmf_task_handle_t task;
|
||||
esp_gmf_element_handle_t current_hd[5];
|
||||
int32_t el_cnt;
|
||||
audio_el_in_test_t *in_inst;
|
||||
audio_el_out_test_t *out_inst;
|
||||
uint32_t in_port_num;
|
||||
uint32_t out_port_num;
|
||||
TaskHandle_t cfg_task_hd;
|
||||
EventGroupHandle_t pipe_sync_evt;
|
||||
void (*config_func)(esp_gmf_element_handle_t, void *);
|
||||
bool is_end;
|
||||
} audio_el_res_t;
|
||||
|
||||
void eq_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void fade_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void mixer_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void encoder_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void decoder_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void sonic_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void alc_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void bit_cvt_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void ch_cvt_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
void rate_cvt_config_callback(esp_gmf_element_handle_t self, void *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _GMF_AUDIO_EL_COM_H_ */
|
||||
+1040
File diff suppressed because it is too large
Load Diff
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "gmf_audio_el_com.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SWEEP_DURATION_MS (5000)
|
||||
|
||||
void audio_generate_sweep_signal(sweep_data_t *sweep_data, esp_gmf_info_sound_t *sound_info, uint32_t current_sample,
|
||||
uint32_t total_samples, uint32_t samples_per_chunk, bool *is_done)
|
||||
{
|
||||
const float start_freq = 20.0f;
|
||||
const float end_freq = 20000.0f;
|
||||
const float duration = SWEEP_DURATION_MS / 1000.0f;
|
||||
uint32_t sample_count = 0;
|
||||
for (uint32_t i = 0; i < samples_per_chunk; i++) {
|
||||
if (current_sample >= total_samples) {
|
||||
*is_done = true;
|
||||
break;
|
||||
}
|
||||
float t = (float)current_sample / sound_info->sample_rates;
|
||||
float freq = start_freq + (end_freq - start_freq) * t / duration;
|
||||
float phase = 2.0f * M_PI * freq * t;
|
||||
float sample_value = sinf(phase);
|
||||
for (int ch = 0; ch < sound_info->channels; ch++) {
|
||||
switch (sound_info->bits) {
|
||||
case 16: {
|
||||
int16_t sample = (int16_t)(32767.0f * sample_value);
|
||||
((int16_t *)sweep_data->data)[i * sound_info->channels + ch] = sample;
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
int32_t sample = (int32_t)(8388607.0f * sample_value);
|
||||
uint8_t *ptr = (uint8_t *)sweep_data->data + (i * sound_info->channels + ch) * 3;
|
||||
ptr[0] = sample & 0xFF;
|
||||
ptr[1] = (sample >> 8) & 0xFF;
|
||||
ptr[2] = (sample >> 16) & 0xFF;
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
int32_t sample = (int32_t)(2147483647.0f * sample_value);
|
||||
((int32_t *)sweep_data->data)[i * sound_info->channels + ch] = sample;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ESP_LOGE("AUD_PATTERN", "Unsupported bit depth: %d", sound_info->bits);
|
||||
*is_done = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
current_sample++;
|
||||
sample_count++;
|
||||
}
|
||||
sweep_data->size = sample_count * sound_info->channels * (sound_info->bits / 8);
|
||||
sweep_data->is_released = false;
|
||||
sweep_data->is_done = *is_done;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "esp_gmf_element.h"
|
||||
#include "esp_gmf_pool.h"
|
||||
#include "esp_gmf_oal_mem.h"
|
||||
#include "esp_gmf_oal_thread.h"
|
||||
|
||||
#include "esp_gmf_audio_dec.h"
|
||||
#include "esp_audio_dec_default.h"
|
||||
#include "esp_audio_dec_reg.h"
|
||||
#include "esp_gmf_new_databus.h"
|
||||
#include "esp_gmf_app_setup_peripheral.h"
|
||||
#include "esp_gmf_audio_helper.h"
|
||||
#include "esp_gmf_audio_enc.h"
|
||||
#include "esp_audio_dec_default.h"
|
||||
#include "gmf_loader_setup_defaults.h"
|
||||
#include "gmf_audio_play_com.h"
|
||||
|
||||
static const char *TAG = "GMF_AUDIO_PLAY_COM";
|
||||
|
||||
void play_pause_single_file( esp_gmf_pipeline_handle_t pipe, const char *uri)
|
||||
{
|
||||
ESP_LOGW(TAG, "play_single_file: %s\r\n", uri);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_reset(pipe));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_in_uri(pipe, uri));
|
||||
|
||||
esp_gmf_element_handle_t dec_el = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_get_el_by_name(pipe, "aud_dec", &dec_el));
|
||||
esp_audio_simple_dec_cfg_t *simple_cfg = (esp_audio_simple_dec_cfg_t *)OBJ_GET_CFG(dec_el);
|
||||
TEST_ASSERT_NOT_NULL(simple_cfg);
|
||||
uint32_t type = ESP_AUDIO_TYPE_UNSUPPORT;
|
||||
esp_gmf_audio_helper_get_audio_type_by_uri(uri, &type);
|
||||
esp_gmf_info_sound_t info = {
|
||||
.sample_rates = 48000,
|
||||
.channels = 2,
|
||||
.bits = 16,
|
||||
.format_id = type,
|
||||
};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_dec_reconfig_by_sound_info(dec_el, &info));
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe));
|
||||
|
||||
vTaskDelay(2000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_pause(pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_resume(pipe));
|
||||
}
|
||||
|
||||
void play_loop_single_file(esp_gmf_pipeline_handle_t pipe, esp_audio_type_t type)
|
||||
{
|
||||
ESP_LOGW(TAG, "play_single_file: %d\r\n", type);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_reset(pipe));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe));
|
||||
|
||||
// enc reconfig
|
||||
esp_gmf_element_handle_t enc_handle = NULL;
|
||||
esp_gmf_pipeline_get_el_by_name(pipe, "aud_enc", &enc_handle);
|
||||
esp_gmf_info_sound_t info = {0};
|
||||
info.format_id = type;
|
||||
if (type == ESP_AUDIO_TYPE_G711A || type == ESP_AUDIO_TYPE_G711U) {
|
||||
info.sample_rates = 8000;
|
||||
info.channels = 2;
|
||||
info.bits = 16;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_in_uri(pipe, "/sdcard/test_8000hz_16bit_2ch_10000ms.pcm"));
|
||||
} else {
|
||||
info.sample_rates = 48000;
|
||||
info.channels = 2;
|
||||
info.bits = 16;
|
||||
info.bitrate = 90000;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_in_uri(pipe, "/sdcard/test_48000hz_16bit_2ch_10000ms.pcm"));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_enc_reconfig_by_sound_info(enc_handle, &info));
|
||||
esp_gmf_pipeline_report_info(pipe, ESP_GMF_INFO_SOUND, &info, sizeof(info));
|
||||
|
||||
// dec reconfig
|
||||
esp_gmf_element_handle_t dec_el = NULL;
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_get_el_by_name(pipe, "aud_dec", &dec_el));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_dec_reconfig_by_sound_info(dec_el, &info));
|
||||
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe));
|
||||
|
||||
vTaskDelay(2000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_pause(pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_resume(pipe));
|
||||
}
|
||||
|
||||
void gmf_register_audio_all(esp_gmf_pool_handle_t pool)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, gmf_loader_setup_io_default(pool));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, gmf_loader_setup_audio_codec_default(pool));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, gmf_loader_setup_audio_effects_default(pool));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, gmf_loader_setup_misc_default(pool));
|
||||
}
|
||||
|
||||
void gmf_unregister_audio_all(esp_gmf_pool_handle_t pool)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, gmf_loader_teardown_audio_effects_default(pool));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, gmf_loader_teardown_audio_codec_default(pool));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, gmf_loader_teardown_io_default(pool));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, gmf_loader_teardown_misc_default(pool));
|
||||
}
|
||||
|
||||
void gmf_setup_pipeline_out_dev(esp_gmf_pipeline_handle_t pipe)
|
||||
{
|
||||
esp_gmf_io_handle_t io_handle = NULL;
|
||||
esp_gmf_pipeline_get_out(pipe, &io_handle);
|
||||
TEST_ASSERT_NOT_NULL(io_handle);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_io_codec_dev_set_dev(io_handle, esp_gmf_app_get_playback_handle()));
|
||||
}
|
||||
|
||||
void gmf_setup_pipeline_in_dev(esp_gmf_pipeline_handle_t pipe)
|
||||
{
|
||||
esp_gmf_io_handle_t io_handle = NULL;
|
||||
esp_gmf_pipeline_get_in(pipe, &io_handle);
|
||||
TEST_ASSERT_NOT_NULL(io_handle);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_io_codec_dev_set_dev(io_handle, esp_gmf_app_get_record_handle()));
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_gmf_pipeline.h"
|
||||
#include "esp_gmf_io_codec_dev.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void play_pause_single_file( esp_gmf_pipeline_handle_t pipe, const char *uri);
|
||||
|
||||
void play_loop_single_file(esp_gmf_pipeline_handle_t pipe, esp_audio_type_t type);
|
||||
void gmf_register_audio_all(esp_gmf_pool_handle_t pool);
|
||||
void gmf_unregister_audio_all(esp_gmf_pool_handle_t pool);
|
||||
|
||||
void gmf_setup_pipeline_out_dev(esp_gmf_pipeline_handle_t pipe);
|
||||
void gmf_setup_pipeline_in_dev(esp_gmf_pipeline_handle_t pipe);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
+1129
File diff suppressed because it is too large
Load Diff
+516
@@ -0,0 +1,516 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_bit_defs.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_gmf_element.h"
|
||||
#include "esp_gmf_pipeline.h"
|
||||
#include "esp_gmf_pool.h"
|
||||
#include "esp_gmf_oal_mem.h"
|
||||
#include "esp_gmf_oal_thread.h"
|
||||
#include "esp_gmf_io_http.h"
|
||||
#include "esp_gmf_rate_cvt.h"
|
||||
#include "esp_gmf_audio_enc.h"
|
||||
#include "esp_gmf_app_setup_peripheral.h"
|
||||
#include "esp_gmf_app_unit_test.h"
|
||||
#include "esp_gmf_audio_helper.h"
|
||||
#include "gmf_audio_play_com.h"
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
#include "media_lib_adapter.h"
|
||||
#include "media_lib_mem_trace.h"
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
|
||||
#define SETUP_AUDIO_SAMPLE_RATE 16000
|
||||
#define SETUP_AUDIO_BITS 16
|
||||
#define SETUP_AUDIO_CHANNELS 1
|
||||
#define PIPELINE_BLOCK_BIT BIT(0)
|
||||
|
||||
static const char *TAG = "AUDIO_REC_ELEMENT_TEST";
|
||||
|
||||
static const char *test_enc_format[] = {
|
||||
"aac",
|
||||
"amr",
|
||||
"awb",
|
||||
"pcm",
|
||||
"opus",
|
||||
"adpcm",
|
||||
"g711a",
|
||||
"g711u",
|
||||
"alac",
|
||||
};
|
||||
|
||||
static const char *header_type[] = {
|
||||
"audio/aac",
|
||||
"audio/opus",
|
||||
"audio/pcm",
|
||||
};
|
||||
|
||||
static esp_err_t _pipeline_event(esp_gmf_event_pkt_t *event, void *ctx)
|
||||
{
|
||||
// The warning messages are used to make the content more noticeable.
|
||||
ESP_LOGW(TAG, "CB: RECV Pipeline EVT: el:%s-%p, type:%x, sub:%s, payload:%p, size:%d,%p",
|
||||
"OBJ_GET_TAG(event->from)", event->from, event->type, esp_gmf_event_get_state_str(event->sub),
|
||||
event->payload, event->payload_size, ctx);
|
||||
if ((event->sub == ESP_GMF_EVENT_STATE_STOPPED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_FINISHED)
|
||||
|| (event->sub == ESP_GMF_EVENT_STATE_ERROR)) {
|
||||
if (ctx) {
|
||||
xEventGroupSetBits((EventGroupHandle_t)ctx, PIPELINE_BLOCK_BIT);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t _http_set_content_type_by_format(esp_http_client_handle_t http, uint32_t format)
|
||||
{
|
||||
switch (format) {
|
||||
case ESP_AUDIO_TYPE_AAC:
|
||||
esp_http_client_set_header(http, "Content-Type", header_type[0]);
|
||||
break;
|
||||
case ESP_AUDIO_TYPE_OPUS:
|
||||
esp_http_client_set_header(http, "Content-Type", header_type[1]);
|
||||
break;
|
||||
case ESP_AUDIO_TYPE_PCM:
|
||||
esp_http_client_set_header(http, "Content-Type", header_type[2]);
|
||||
break;
|
||||
default:
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t _http_stream_event_handle(http_stream_event_msg_t *msg)
|
||||
{
|
||||
esp_http_client_handle_t http = (esp_http_client_handle_t)msg->http_client;
|
||||
char len_buf[16];
|
||||
if (msg->event_id == HTTP_STREAM_PRE_REQUEST) {
|
||||
// set header
|
||||
ESP_LOGW(TAG, "[ + ] HTTP client HTTP_STREAM_PRE_REQUEST, length=%d, format:%s", msg->buffer_len, (char *)msg->user_data);
|
||||
esp_http_client_set_method(http, HTTP_METHOD_POST);
|
||||
char dat[10] = {0};
|
||||
snprintf(dat, sizeof(dat), "%d", SETUP_AUDIO_SAMPLE_RATE);
|
||||
esp_http_client_set_header(http, "x-audio-sample-rates", dat);
|
||||
uint32_t fmt = 0;
|
||||
esp_gmf_audio_helper_get_audio_type_by_uri((char *)msg->user_data, &fmt);
|
||||
esp_gmf_err_t ret = _http_set_content_type_by_format(http, fmt);
|
||||
if (ret != ESP_GMF_ERR_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set content type for format: %lx", fmt);
|
||||
return ret;
|
||||
}
|
||||
memset(dat, 0, sizeof(dat));
|
||||
snprintf(dat, sizeof(dat), "%d", SETUP_AUDIO_BITS);
|
||||
esp_http_client_set_header(http, "x-audio-bits", dat);
|
||||
memset(dat, 0, sizeof(dat));
|
||||
snprintf(dat, sizeof(dat), "%d", SETUP_AUDIO_CHANNELS);
|
||||
esp_http_client_set_header(http, "x-audio-channel", dat);
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
if (msg->event_id == HTTP_STREAM_ON_REQUEST) {
|
||||
// write data
|
||||
int wlen = sprintf(len_buf, "%x\r\n", msg->buffer_len);
|
||||
if (esp_http_client_write(http, len_buf, wlen) <= 0) {
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
if (esp_http_client_write(http, msg->buffer, msg->buffer_len) <= 0) {
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
if (esp_http_client_write(http, "\r\n", 2) <= 0) {
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
return msg->buffer_len;
|
||||
}
|
||||
|
||||
if (msg->event_id == HTTP_STREAM_POST_REQUEST) {
|
||||
ESP_LOGW(TAG, "[ + ] HTTP client HTTP_STREAM_POST_REQUEST, write end chunked marker");
|
||||
if (esp_http_client_write(http, "0\r\n\r\n", 5) <= 0) {
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
if (msg->event_id == HTTP_STREAM_FINISH_REQUEST) {
|
||||
ESP_LOGW(TAG, "[ + ] HTTP client HTTP_STREAM_FINISH_REQUEST");
|
||||
char *buf = (char *)calloc(1, 64);
|
||||
assert(buf);
|
||||
int read_len = esp_http_client_read(http, buf, 64);
|
||||
if (read_len <= 0) {
|
||||
free(buf);
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
buf[read_len] = 0;
|
||||
ESP_LOGI(TAG, "Got HTTP Response = %s", (char *)buf);
|
||||
free(buf);
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
ESP_LOGD(TAG, "Unknown event: %d", msg->event_id);
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
TEST_CASE("Recorder, One Pipe, [IIS->ENC->FILE]", "[ESP_GMF_POOL]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("ESP_GMF_PIPELINE", ESP_LOG_DEBUG);
|
||||
// esp_log_level_set("GMF_CACHE", ESP_LOG_DEBUG);
|
||||
// esp_log_level_set("ESP_GMF_AENC", ESP_LOG_DEBUG);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
uint32_t I2S_REC_ENCODER_SAMPLE_RATE = 48000;
|
||||
esp_gmf_app_codec_info_t codec_info = ESP_GMF_APP_CODEC_INFO_DEFAULT();
|
||||
codec_info.record_info.sample_rate = SETUP_AUDIO_SAMPLE_RATE;
|
||||
codec_info.record_info.channel = SETUP_AUDIO_CHANNELS;
|
||||
codec_info.record_info.bits_per_sample = SETUP_AUDIO_BITS;
|
||||
codec_info.play_info.sample_rate = codec_info.record_info.sample_rate;
|
||||
esp_gmf_app_setup_codec_dev(&codec_info);
|
||||
void *sdcard_handle = NULL;
|
||||
esp_gmf_app_setup_sdcard(&sdcard_handle);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_pool_handle_t pool = NULL;
|
||||
esp_gmf_pool_init(&pool);
|
||||
TEST_ASSERT_NOT_NULL(pool);
|
||||
gmf_register_audio_all(pool);
|
||||
|
||||
ESP_GMF_POOL_SHOW_ITEMS(pool);
|
||||
// Create the new elements
|
||||
esp_gmf_pipeline_handle_t pipe = NULL;
|
||||
const char *uri = "/sdcard/esp_gmf_rec1.aac";
|
||||
|
||||
const char *name[] = {"aud_rate_cvt", "aud_ch_cvt", "aud_enc"};
|
||||
esp_gmf_pool_new_pipeline(pool, "io_codec_dev", name, sizeof(name) / sizeof(char *), "io_file", &pipe);
|
||||
TEST_ASSERT_NOT_NULL(pipe);
|
||||
gmf_setup_pipeline_in_dev(pipe);
|
||||
esp_gmf_task_cfg_t cfg = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg.ctx = NULL;
|
||||
cfg.cb = NULL;
|
||||
esp_gmf_task_handle_t work_task = NULL;
|
||||
esp_gmf_task_init(&cfg, &work_task);
|
||||
TEST_ASSERT_NOT_NULL(work_task);
|
||||
|
||||
esp_gmf_pipeline_bind_task(pipe, work_task);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe));
|
||||
esp_gmf_pipeline_set_event(pipe, _pipeline_event, NULL);
|
||||
|
||||
esp_gmf_pipeline_set_out_uri(pipe, uri);
|
||||
esp_gmf_element_handle_t enc_handle = NULL;
|
||||
esp_gmf_pipeline_get_el_by_name(pipe, "aud_enc", &enc_handle);
|
||||
uint32_t audio_type = 0;
|
||||
esp_gmf_audio_helper_get_audio_type_by_uri(uri, &audio_type);
|
||||
esp_gmf_info_sound_t info = {
|
||||
.sample_rates = SETUP_AUDIO_SAMPLE_RATE,
|
||||
.channels = SETUP_AUDIO_CHANNELS,
|
||||
.bits = SETUP_AUDIO_BITS,
|
||||
.bitrate = 90000,
|
||||
.format_id = audio_type,
|
||||
};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_enc_reconfig_by_sound_info(enc_handle, &info));
|
||||
esp_gmf_element_handle_t resp = NULL;
|
||||
esp_gmf_pipeline_get_el_by_name(pipe, "aud_rate_cvt", &resp);
|
||||
esp_ae_rate_cvt_cfg_t *resp_cfg = (esp_ae_rate_cvt_cfg_t *)OBJ_GET_CFG(resp);
|
||||
resp_cfg->src_rate = SETUP_AUDIO_SAMPLE_RATE;
|
||||
if (audio_type == ESP_AUDIO_TYPE_AMRNB) {
|
||||
resp_cfg->dest_rate = 8000;
|
||||
} else if (audio_type == ESP_AUDIO_TYPE_G711U) {
|
||||
resp_cfg->dest_rate = 8000;
|
||||
} else if (audio_type == ESP_AUDIO_TYPE_G711A) {
|
||||
resp_cfg->dest_rate = 8000;
|
||||
} else if (audio_type == ESP_AUDIO_TYPE_AMRWB) {
|
||||
resp_cfg->dest_rate = 16000;
|
||||
} else {
|
||||
resp_cfg->dest_rate = I2S_REC_ENCODER_SAMPLE_RATE;
|
||||
}
|
||||
esp_gmf_pipeline_report_info(pipe, ESP_GMF_INFO_SOUND, &info, sizeof(info));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe));
|
||||
|
||||
vTaskDelay(10000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe));
|
||||
|
||||
esp_gmf_task_deinit(work_task);
|
||||
esp_gmf_pipeline_destroy(pipe);
|
||||
gmf_unregister_audio_all(pool);
|
||||
esp_gmf_pool_deinit(pool);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_app_teardown_codec_dev();
|
||||
esp_gmf_app_teardown_sdcard(sdcard_handle);
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
TEST_CASE("Recorder, One Pipe recoding multiple format, [IIS->ENC->FILE]", "[ESP_GMF_POOL]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("ESP_GMF_PIPELINE", ESP_LOG_DEBUG);
|
||||
// esp_log_level_set("ESP_GMF_RATE_CVT", ESP_LOG_DEBUG);
|
||||
// esp_log_level_set("ESP_GMF_AENC", ESP_LOG_DEBUG);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
|
||||
esp_gmf_app_codec_info_t codec_info = ESP_GMF_APP_CODEC_INFO_DEFAULT();
|
||||
codec_info.record_info.sample_rate = SETUP_AUDIO_SAMPLE_RATE;
|
||||
codec_info.record_info.channel = SETUP_AUDIO_CHANNELS;
|
||||
codec_info.record_info.bits_per_sample = SETUP_AUDIO_BITS;
|
||||
codec_info.play_info.sample_rate = codec_info.record_info.sample_rate;
|
||||
esp_gmf_app_setup_codec_dev(&codec_info);
|
||||
void *sdcard_handle = NULL;
|
||||
esp_gmf_app_setup_sdcard(&sdcard_handle);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_pool_handle_t pool = NULL;
|
||||
esp_gmf_pool_init(&pool);
|
||||
TEST_ASSERT_NOT_NULL(pool);
|
||||
gmf_register_audio_all(pool);
|
||||
ESP_GMF_POOL_SHOW_ITEMS(pool);
|
||||
|
||||
EventGroupHandle_t pipe_sync_evt = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt, return);
|
||||
|
||||
esp_gmf_pipeline_handle_t pipe = NULL;
|
||||
const char *name[] = {"aud_rate_cvt", "aud_enc"};
|
||||
esp_gmf_pool_new_pipeline(pool, "io_codec_dev", name, sizeof(name) / sizeof(char *), "io_file", &pipe);
|
||||
TEST_ASSERT_NOT_NULL(pipe);
|
||||
gmf_setup_pipeline_in_dev(pipe);
|
||||
esp_gmf_task_cfg_t cfg = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg.ctx = NULL;
|
||||
cfg.cb = NULL;
|
||||
cfg.thread.stack = 40 * 1024;
|
||||
esp_gmf_task_handle_t work_task = NULL;
|
||||
esp_gmf_task_init(&cfg, &work_task);
|
||||
TEST_ASSERT_NOT_NULL(work_task);
|
||||
|
||||
esp_gmf_pipeline_bind_task(pipe, work_task);
|
||||
esp_gmf_pipeline_loading_jobs(pipe);
|
||||
esp_gmf_pipeline_set_event(pipe, _pipeline_event, pipe_sync_evt);
|
||||
|
||||
char uri[128] = {0};
|
||||
uint32_t I2S_REC_ENCODER_SAMPLE_RATE = 48000;
|
||||
|
||||
for (int i = 0; i < sizeof(test_enc_format) / sizeof(char *); ++i) {
|
||||
snprintf(uri, 127, "/sdcard/esp_gmf_rec_%02d.%s", i, test_enc_format[i]);
|
||||
esp_gmf_element_handle_t enc_handle = NULL;
|
||||
esp_gmf_pipeline_get_el_by_name(pipe, "aud_enc", &enc_handle);
|
||||
esp_audio_enc_config_t *esp_gmf_enc_cfg = (esp_audio_enc_config_t *)OBJ_GET_CFG(enc_handle);
|
||||
uint32_t audio_type = 0;
|
||||
esp_gmf_audio_helper_get_audio_type_by_uri(uri, &audio_type);
|
||||
esp_gmf_info_sound_t info = {
|
||||
.sample_rates = SETUP_AUDIO_SAMPLE_RATE,
|
||||
.channels = SETUP_AUDIO_CHANNELS,
|
||||
.bits = SETUP_AUDIO_BITS,
|
||||
.format_id = audio_type,
|
||||
};
|
||||
if (audio_type == ESP_AUDIO_TYPE_AMRNB) {
|
||||
info.bitrate = 12200;
|
||||
} else if (audio_type == ESP_AUDIO_TYPE_AMRWB) {
|
||||
info.bitrate = 19850;
|
||||
} else {
|
||||
info.bitrate = 90000;
|
||||
}
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_enc_reconfig_by_sound_info(enc_handle, &info));
|
||||
esp_gmf_pipeline_report_info(pipe, ESP_GMF_INFO_SOUND, &info, sizeof(info));
|
||||
|
||||
esp_gmf_element_handle_t resp = NULL;
|
||||
esp_gmf_pipeline_get_el_by_name(pipe, "aud_rate_cvt", &resp);
|
||||
esp_ae_rate_cvt_cfg_t *resp_cfg = (esp_ae_rate_cvt_cfg_t *)OBJ_GET_CFG(resp);
|
||||
resp_cfg->src_rate = SETUP_AUDIO_SAMPLE_RATE;
|
||||
if (audio_type == ESP_AUDIO_TYPE_AMRNB) {
|
||||
resp_cfg->dest_rate = 8000;
|
||||
} else if (audio_type == ESP_AUDIO_TYPE_G711U) {
|
||||
resp_cfg->dest_rate = 8000;
|
||||
} else if (audio_type == ESP_AUDIO_TYPE_G711A) {
|
||||
resp_cfg->dest_rate = 8000;
|
||||
} else if (audio_type == ESP_AUDIO_TYPE_AMRWB) {
|
||||
resp_cfg->dest_rate = 16000;
|
||||
} else {
|
||||
resp_cfg->dest_rate = I2S_REC_ENCODER_SAMPLE_RATE;
|
||||
}
|
||||
|
||||
ESP_LOGW(TAG, "Recoding file, %s, type:%d\r\n", uri, esp_gmf_enc_cfg->type);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_out_uri(pipe, uri));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe));
|
||||
int cnt = 10;
|
||||
xEventGroupClearBits(pipe_sync_evt, PIPELINE_BLOCK_BIT);
|
||||
while (cnt) {
|
||||
printf(".");
|
||||
EventBits_t ret = xEventGroupWaitBits(pipe_sync_evt, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, 1000 / portTICK_RATE_MS);
|
||||
if ((ret & PIPELINE_BLOCK_BIT) != 0) {
|
||||
cnt = 0;
|
||||
break;
|
||||
}
|
||||
fflush(stdout);
|
||||
cnt--;
|
||||
}
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_reset(pipe));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe));
|
||||
}
|
||||
|
||||
esp_gmf_task_deinit(work_task);
|
||||
esp_gmf_pipeline_destroy(pipe);
|
||||
gmf_unregister_audio_all(pool);
|
||||
esp_gmf_pool_deinit(pool);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
vEventGroupDelete(pipe_sync_evt);
|
||||
esp_gmf_app_teardown_codec_dev();
|
||||
esp_gmf_app_teardown_sdcard(sdcard_handle);
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
// Refer the 'esp_gmf_audio_rec_el_test.c' test_enc_format
|
||||
static const char *recoding_file_path[] = {
|
||||
"/sdcard/esp_gmf_rec_00.aac",
|
||||
"/sdcard/esp_gmf_rec_01.amr",
|
||||
"/sdcard/esp_gmf_rec_02.awb",
|
||||
"/sdcard/esp_gmf_rec_03.pcm",
|
||||
};
|
||||
|
||||
TEST_CASE("Record file for playback, multiple files with One Pipe, [FILE->dec->resample->IIS]", "[ESP_GMF_POOL]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("ESP_GMF_PIPELINE", ESP_LOG_DEBUG);
|
||||
esp_log_level_set("ESP_GMF_POOL", ESP_LOG_DEBUG);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
esp_gmf_app_setup_codec_dev(NULL);
|
||||
void *sdcard_handle = NULL;
|
||||
esp_gmf_app_setup_sdcard(&sdcard_handle);
|
||||
EventGroupHandle_t pipe_sync_evt = xEventGroupCreate();
|
||||
ESP_GMF_NULL_CHECK(TAG, pipe_sync_evt, return);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_pool_handle_t pool = NULL;
|
||||
esp_gmf_pool_init(&pool);
|
||||
TEST_ASSERT_NOT_NULL(pool);
|
||||
gmf_register_audio_all(pool);
|
||||
ESP_GMF_POOL_SHOW_ITEMS(pool);
|
||||
|
||||
esp_gmf_pipeline_handle_t pipe = NULL;
|
||||
const char *name[] = {"aud_dec", "aud_rate_cvt", "aud_ch_cvt"};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_new_pipeline(pool, "io_file", name, sizeof(name) / sizeof(char *), "io_codec_dev", &pipe));
|
||||
TEST_ASSERT_NOT_NULL(pipe);
|
||||
gmf_setup_pipeline_out_dev(pipe);
|
||||
esp_gmf_task_cfg_t cfg = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg.thread.stack = 30 * 1024;
|
||||
esp_gmf_task_handle_t work_task = NULL;
|
||||
esp_gmf_task_init(&cfg, &work_task);
|
||||
TEST_ASSERT_NOT_NULL(work_task);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_bind_task(pipe, work_task));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_event(pipe, _pipeline_event, pipe_sync_evt));
|
||||
|
||||
for (int i = 0; i < sizeof(recoding_file_path) / sizeof(char *); ++i) {
|
||||
play_pause_single_file(pipe, recoding_file_path[i]);
|
||||
xEventGroupWaitBits(pipe_sync_evt, PIPELINE_BLOCK_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe));
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_task_deinit(work_task));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_destroy(pipe));
|
||||
gmf_unregister_audio_all(pool);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pool_deinit(pool));
|
||||
vEventGroupDelete(pipe_sync_evt);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_app_teardown_codec_dev();
|
||||
esp_gmf_app_teardown_sdcard(sdcard_handle);
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
TEST_CASE("Recorder, One Pipe, [IIS->ENC->HTTP]", "[ESP_GMF_POOL][ignore][leaks=10000]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("ESP_GMF_PIPELINE", ESP_LOG_DEBUG);
|
||||
esp_log_level_set("ESP_GMF_POOL", ESP_LOG_DEBUG);
|
||||
esp_gmf_app_test_case_uses_tcpip();
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
esp_gmf_app_wifi_connect();
|
||||
esp_gmf_app_codec_info_t codec_info = ESP_GMF_APP_CODEC_INFO_DEFAULT();
|
||||
codec_info.record_info.sample_rate = SETUP_AUDIO_SAMPLE_RATE;
|
||||
codec_info.record_info.channel = SETUP_AUDIO_CHANNELS;
|
||||
codec_info.record_info.bits_per_sample = SETUP_AUDIO_BITS;
|
||||
codec_info.play_info.sample_rate = codec_info.record_info.sample_rate;
|
||||
esp_gmf_app_setup_codec_dev(&codec_info);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_pool_handle_t pool = NULL;
|
||||
esp_gmf_pool_init(&pool);
|
||||
TEST_ASSERT_NOT_NULL(pool);
|
||||
gmf_register_audio_all(pool);
|
||||
ESP_GMF_POOL_SHOW_ITEMS(pool);
|
||||
|
||||
// Create the new elements
|
||||
esp_gmf_pipeline_handle_t pipe = NULL;
|
||||
const char *name[] = {"aud_enc"};
|
||||
esp_gmf_pool_new_pipeline(pool, "io_codec_dev", name, sizeof(name) / sizeof(char *), "io_http", &pipe);
|
||||
TEST_ASSERT_NOT_NULL(pipe);
|
||||
gmf_setup_pipeline_in_dev(pipe);
|
||||
const char *rec_type = ".aac";
|
||||
|
||||
esp_gmf_element_handle_t enc_handle = NULL;
|
||||
esp_gmf_pipeline_get_el_by_name(pipe, "aud_enc", &enc_handle);
|
||||
uint32_t audio_type = ESP_AUDIO_TYPE_AAC;
|
||||
esp_gmf_audio_helper_get_audio_type_by_uri(rec_type, &audio_type);
|
||||
esp_gmf_info_sound_t info = {
|
||||
.sample_rates = SETUP_AUDIO_SAMPLE_RATE,
|
||||
.channels = SETUP_AUDIO_CHANNELS,
|
||||
.bits = SETUP_AUDIO_BITS,
|
||||
.bitrate = 90000,
|
||||
.format_id = audio_type,
|
||||
};
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_audio_enc_reconfig_by_sound_info(enc_handle, &info));
|
||||
esp_gmf_pipeline_report_info(pipe, ESP_GMF_INFO_SOUND, &info, sizeof(info));
|
||||
|
||||
esp_gmf_io_handle_t http_out = NULL;
|
||||
esp_gmf_pipeline_get_out(pipe, &http_out);
|
||||
http_io_cfg_t *http_cfg = (http_io_cfg_t *)OBJ_GET_CFG(http_out);
|
||||
http_cfg->user_data = (void *)rec_type;
|
||||
http_cfg->event_handle = _http_stream_event_handle;
|
||||
|
||||
esp_gmf_task_cfg_t cfg = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg.ctx = NULL;
|
||||
cfg.cb = NULL;
|
||||
esp_gmf_task_handle_t work_task = NULL;
|
||||
esp_gmf_task_init(&cfg, &work_task);
|
||||
TEST_ASSERT_NOT_NULL(work_task);
|
||||
|
||||
esp_gmf_pipeline_bind_task(pipe, work_task);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_loading_jobs(pipe));
|
||||
esp_gmf_pipeline_set_event(pipe, _pipeline_event, NULL);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_set_out_uri(pipe, "http://192.168.31.28:8000/upload"));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(pipe));
|
||||
|
||||
vTaskDelay(15000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(pipe));
|
||||
esp_gmf_task_deinit(work_task);
|
||||
esp_gmf_pipeline_destroy(pipe);
|
||||
gmf_unregister_audio_all(pool);
|
||||
esp_gmf_pool_deinit(pool);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
esp_gmf_app_teardown_codec_dev();
|
||||
esp_gmf_app_wifi_disconnect();
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_gmf_bit_cvt.h"
|
||||
#include "esp_gmf_ch_cvt.h"
|
||||
#include "esp_gmf_eq.h"
|
||||
#include "esp_gmf_alc.h"
|
||||
#include "esp_gmf_fade.h"
|
||||
#include "esp_gmf_mixer.h"
|
||||
#include "esp_gmf_rate_cvt.h"
|
||||
#include "esp_gmf_sonic.h"
|
||||
#include "esp_gmf_interleave.h"
|
||||
#include "esp_gmf_deinterleave.h"
|
||||
#include "esp_gmf_audio_enc.h"
|
||||
#include "esp_gmf_audio_dec.h"
|
||||
|
||||
#include "esp_gmf_io_embed_flash.h"
|
||||
#include "esp_gmf_io_http.h"
|
||||
#include "esp_gmf_io_file.h"
|
||||
#include "esp_gmf_io_i2s_pdm.h"
|
||||
|
||||
#include "esp_gmf_copier.h"
|
||||
|
||||
void test_esp_gmf_alc_if()
|
||||
{
|
||||
esp_ae_alc_cfg_t config = {.channel = 2};
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Set gain function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_set_gain(NULL, 0, 10), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_set_gain(handle, config.channel + 1, 10), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_set_gain(handle, config.channel - 1, -10), ESP_GMF_ERR_OK);
|
||||
// Get gain function test
|
||||
int8_t gain = 0;
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_get_gain(NULL, 0, &gain), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_get_gain(handle, 0, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_get_gain(handle, config.channel + 1, &gain), ESP_GMF_ERR_INVALID_ARG);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_alc_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_bit_cvt_if()
|
||||
{
|
||||
esp_ae_bit_cvt_cfg_t config = DEFAULT_ESP_GMF_BIT_CVT_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_bit_cvt_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_bit_cvt_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_bit_cvt_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_ch_cvt_if()
|
||||
{
|
||||
esp_ae_ch_cvt_cfg_t config = DEFAULT_ESP_GMF_CH_CVT_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_ch_cvt_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_ch_cvt_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Set dest channel function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_ch_cvt_set_dest_channel(NULL, 1), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_ch_cvt_set_dest_channel(handle, 1), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_ch_cvt_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_deinterleave_if()
|
||||
{
|
||||
esp_gmf_deinterleave_cfg config = DEFAULT_ESP_GMF_DEINTERLEAVE_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_deinterleave_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_deinterleave_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_deinterleave_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_eq_if()
|
||||
{
|
||||
esp_ae_eq_cfg_t config = DEFAULT_ESP_GMF_EQ_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
esp_ae_eq_filter_para_t para = {0};
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_eq_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_eq_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Set para function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_eq_set_para(NULL, 0, ¶), ESP_GMF_ERR_INVALID_ARG);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_eq_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_fade_if()
|
||||
{
|
||||
esp_ae_fade_cfg_t config = DEFAULT_ESP_GMF_FADE_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
esp_ae_fade_mode_t mode = ESP_AE_FADE_MODE_INVALID;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Set mode function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_set_mode(NULL, 0), ESP_GMF_ERR_INVALID_ARG);
|
||||
// Get mode function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_get_mode(NULL, &mode), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_get_mode(handle, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_get_mode(handle, &mode), ESP_GMF_ERR_OK);
|
||||
// Set weight function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_reset_weight(NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_reset_weight(handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_fade_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_interleave_if()
|
||||
{
|
||||
esp_gmf_interleave_cfg config = DEFAULT_ESP_GMF_INTERLEAVE_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_interleave_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_interleave_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_interleave_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_mixer_if()
|
||||
{
|
||||
esp_ae_mixer_cfg_t config = DEFAULT_ESP_GMF_MIXER_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
esp_ae_mixer_mode_t mode = ESP_AE_MIXER_MODE_INVALID;
|
||||
uint32_t sample_rate = 48000;
|
||||
uint8_t channel = 2;
|
||||
uint8_t bits = 16;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_mixer_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_mixer_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Set mode function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_mixer_set_mode(NULL, 0, mode), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_mixer_set_mode(handle, config.src_num + 1, mode), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_mixer_set_mode(handle, 0, mode), ESP_GMF_ERR_OK);
|
||||
// Set audio info function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_mixer_set_audio_info(NULL, sample_rate, channel, bits), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_mixer_set_audio_info(handle, sample_rate, channel, bits), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_mixer_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_rate_cvt_if()
|
||||
{
|
||||
esp_ae_rate_cvt_cfg_t config = DEFAULT_ESP_GMF_RATE_CVT_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
uint32_t sample_rate = 48000;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_rate_cvt_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_rate_cvt_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Set mode function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_rate_cvt_set_dest_rate(NULL, sample_rate), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_rate_cvt_set_dest_rate(handle, sample_rate), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_rate_cvt_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_sonic_if()
|
||||
{
|
||||
esp_ae_sonic_cfg_t config = DEFAULT_ESP_GMF_SONIC_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
float speed = 1.0;
|
||||
float pitch = 1.0;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Set speed function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_set_speed(NULL, speed), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_set_speed(handle, speed), ESP_GMF_ERR_OK);
|
||||
// Get speed function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_get_speed(NULL, &speed), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_get_speed(handle, &speed), ESP_GMF_ERR_OK);
|
||||
// Set pitch function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_set_pitch(NULL, pitch), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_set_pitch(handle, pitch), ESP_GMF_ERR_OK);
|
||||
// Get pitch function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_get_pitch(NULL, &pitch), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_get_pitch(handle, &pitch), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_sonic_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, OBJ_GET_CFG(handle));
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_dec_if()
|
||||
{
|
||||
esp_audio_simple_dec_cfg_t config = DEFAULT_ESP_GMF_AUDIO_DEC_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_audio_dec_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_audio_dec_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_audio_dec_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
esp_audio_simple_dec_cfg_t *cfg = OBJ_GET_CFG(handle);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, cfg);
|
||||
TEST_ASSERT_EQUAL(cfg->dec_type, ESP_AUDIO_SIMPLE_DEC_TYPE_NONE);
|
||||
TEST_ASSERT_EQUAL(cfg->dec_cfg, NULL);
|
||||
TEST_ASSERT_EQUAL(cfg->cfg_size, 0);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_enc_if()
|
||||
{
|
||||
esp_audio_enc_config_t config = DEFAULT_ESP_GMF_AUDIO_ENC_CONFIG();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_audio_enc_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_audio_enc_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
// Test for config is NULL, will create a default config
|
||||
TEST_ASSERT_EQUAL(esp_gmf_audio_enc_init(NULL, &handle), ESP_GMF_ERR_OK);
|
||||
esp_audio_enc_config_t *cfg = OBJ_GET_CFG(handle);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, cfg);
|
||||
TEST_ASSERT_EQUAL(cfg->type, ESP_AUDIO_TYPE_UNSUPPORT);
|
||||
TEST_ASSERT_EQUAL(cfg->cfg, NULL);
|
||||
TEST_ASSERT_EQUAL(cfg->cfg_sz, 0);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_io_embed_flash_if()
|
||||
{
|
||||
embed_flash_io_cfg_t config = EMBED_FLASH_CFG_DEFAULT();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
const embed_item_info_t context = {0};
|
||||
int max_num = 3;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_embed_flash_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_embed_flash_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Set context function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_embed_flash_set_context(NULL, &context, max_num), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_embed_flash_set_context(handle, NULL, max_num), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_embed_flash_set_context(handle, &context, max_num), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_io_file_if()
|
||||
{
|
||||
file_io_cfg_t config = FILE_IO_CFG_DEFAULT();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_file_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
config.dir = ESP_GMF_IO_DIR_NONE;
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_file_init(&config, &handle), ESP_GMF_ERR_NOT_SUPPORT);
|
||||
config.dir = ESP_GMF_IO_DIR_READER;
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_file_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_io_http_if()
|
||||
{
|
||||
http_io_cfg_t config = HTTP_STREAM_CFG_DEFAULT();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
const char *cert = "test";
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_http_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
config.dir = ESP_GMF_IO_DIR_NONE;
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_http_init(&config, &handle), ESP_GMF_ERR_NOT_SUPPORT);
|
||||
config.dir = ESP_GMF_IO_DIR_READER;
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_http_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Reset function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_http_reset(NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_http_reset(handle), ESP_GMF_ERR_OK);
|
||||
// Set server cert function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_http_set_server_cert(NULL, cert), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_http_set_server_cert(handle, cert), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_io_i2s_if()
|
||||
{
|
||||
i2s_pdm_io_cfg_t config = ESP_GMF_IO_I2S_PDM_CFG_DEFAULT();
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_i2s_pdm_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
config.dir = ESP_GMF_IO_DIR_NONE;
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_i2s_pdm_init(&config, &handle), ESP_GMF_ERR_NOT_SUPPORT);
|
||||
config.dir = ESP_GMF_IO_DIR_READER;
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_i2s_pdm_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
void test_esp_gmf_copier_if()
|
||||
{
|
||||
esp_gmf_copier_cfg_t config;
|
||||
esp_gmf_obj_handle_t handle;
|
||||
// Initialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_copier_init(&config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
TEST_ASSERT_EQUAL(esp_gmf_copier_init(&config, &handle), ESP_GMF_ERR_OK);
|
||||
// Deinitialize function test
|
||||
TEST_ASSERT_EQUAL(esp_gmf_obj_delete(handle), ESP_GMF_ERR_OK);
|
||||
}
|
||||
|
||||
TEST_CASE("Test element if check", "[ESP_GMF_IF_CHECK]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
test_esp_gmf_alc_if();
|
||||
test_esp_gmf_bit_cvt_if();
|
||||
test_esp_gmf_ch_cvt_if();
|
||||
test_esp_gmf_deinterleave_if();
|
||||
test_esp_gmf_eq_if();
|
||||
test_esp_gmf_fade_if();
|
||||
test_esp_gmf_interleave_if();
|
||||
test_esp_gmf_mixer_if();
|
||||
test_esp_gmf_rate_cvt_if();
|
||||
test_esp_gmf_sonic_if();
|
||||
test_esp_gmf_dec_if();
|
||||
test_esp_gmf_enc_if();
|
||||
test_esp_gmf_io_embed_flash_if();
|
||||
test_esp_gmf_io_file_if();
|
||||
test_esp_gmf_io_http_if();
|
||||
test_esp_gmf_io_i2s_if();
|
||||
test_esp_gmf_copier_if();
|
||||
}
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_gmf_data_bus.h"
|
||||
#include "esp_gmf_video_element.h"
|
||||
#include "esp_gmf_video_scale.h"
|
||||
#include "esp_gmf_video_crop.h"
|
||||
#include "esp_gmf_video_rotate.h"
|
||||
#include "esp_gmf_video_color_convert.h"
|
||||
|
||||
#define TEST_MAX_EL_NUM (4)
|
||||
#define TEST_MAX_IMG_LENGTH (640 * 480 * 3)
|
||||
#define TEST_TICK_DELAY (0)
|
||||
static esp_gmf_obj_handle_t obj_hd_pool[TEST_MAX_EL_NUM] = {NULL};
|
||||
static uint8_t *test_buffer = NULL;
|
||||
static uint8_t *test_buffer1 = NULL;
|
||||
|
||||
static const char *TAG = "IMGFX_SCALE_TEST";
|
||||
|
||||
void esp_gmf_destory_obj_cfg_pool()
|
||||
{
|
||||
for (size_t i = 0; i < TEST_MAX_EL_NUM; i++) {
|
||||
esp_gmf_obj_delete(obj_hd_pool[i]);
|
||||
obj_hd_pool[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_gmf_err_t esp_gmf_create_obj_cfg_pool()
|
||||
{
|
||||
esp_gmf_job_err_t ret = ESP_GMF_JOB_ERR_OK;
|
||||
esp_imgfx_scale_cfg_t scale_cfg = {
|
||||
.in_pixel_fmt = ESP_IMGFX_PIXEL_FMT_RGB888,
|
||||
.in_res = {640, 480},
|
||||
.scale_res = {320, 240},
|
||||
.filter_type = ESP_IMGFX_SCALE_FILTER_TYPE_BILINEAR};
|
||||
ret = esp_gmf_video_scale_init(&scale_cfg, &obj_hd_pool[0]);
|
||||
ESP_GMF_RET_ON_NOT_OK(TAG, ret, { goto _cfg_free;}, "Failed to append scale obj to pool");
|
||||
esp_imgfx_crop_cfg_t crop_cfg = {
|
||||
.in_res = {100, 100},
|
||||
.in_pixel_fmt = ESP_IMGFX_PIXEL_FMT_RGB888,
|
||||
.cropped_res = {50, 50},
|
||||
.x_pos = 25,
|
||||
.y_pos = 25};
|
||||
ret = esp_gmf_video_crop_init(&crop_cfg, &obj_hd_pool[1]);
|
||||
ESP_GMF_RET_ON_NOT_OK(TAG, ret, { goto _cfg_free;}, "Failed to append crop obj to pool");
|
||||
esp_imgfx_rotate_cfg_t rotate_cfg = {
|
||||
.in_pixel_fmt = ESP_IMGFX_PIXEL_FMT_RGB888,
|
||||
.in_res = {.width = 256, .height = 256},
|
||||
.degree = 90};
|
||||
ret = esp_gmf_video_rotate_init(&rotate_cfg, &obj_hd_pool[2]);
|
||||
ESP_GMF_RET_ON_NOT_OK(TAG, ret, { goto _cfg_free;}, "Failed to append rotate obj to pool");
|
||||
esp_imgfx_color_convert_cfg_t color_convert_cfg = {
|
||||
.in_res = {640, 480},
|
||||
.in_pixel_fmt = ESP_IMGFX_PIXEL_FMT_RGB565_LE,
|
||||
.out_pixel_fmt = ESP_IMGFX_PIXEL_FMT_RGB888,
|
||||
.color_space_std = ESP_IMGFX_COLOR_SPACE_STD_BT601};
|
||||
ret = esp_gmf_video_color_convert_init(&color_convert_cfg, &obj_hd_pool[3]);
|
||||
ESP_GMF_RET_ON_NOT_OK(TAG, ret, { goto _cfg_free;}, "Failed to append color convert obj to pool");
|
||||
return ret;
|
||||
_cfg_free:
|
||||
esp_gmf_destory_obj_cfg_pool();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_gmf_err_t event_cb(esp_gmf_event_pkt_t *evt, void *ctx)
|
||||
{
|
||||
ESP_GMF_NULL_CHECK(TAG, ctx, return ESP_GMF_ERR_INVALID_ARG);
|
||||
ESP_GMF_NULL_CHECK(TAG, evt, return ESP_GMF_ERR_INVALID_ARG);
|
||||
if ((evt->type != ESP_GMF_EVT_TYPE_REPORT_INFO)
|
||||
|| (evt->sub != ESP_GMF_INFO_VIDEO)
|
||||
|| (evt->payload == NULL)) {
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
esp_gmf_info_video_t *info = (esp_gmf_info_video_t *)evt->payload;
|
||||
// Check received info
|
||||
esp_gmf_info_video_t get_info = {0};
|
||||
esp_gmf_video_el_get_src_info(ctx, &get_info);
|
||||
TEST_ASSERT_EQUAL(info->fps, get_info.fps);
|
||||
TEST_ASSERT_EQUAL(info->bitrate, get_info.bitrate);
|
||||
const char *tag = OBJ_GET_TAG(ctx);
|
||||
if (strcmp(tag, "vid_scale") == 0) {
|
||||
esp_imgfx_scale_cfg_t *cfg = (esp_imgfx_scale_cfg_t *)OBJ_GET_CFG(ctx);
|
||||
TEST_ASSERT_EQUAL(info->width, cfg->scale_res.width);
|
||||
TEST_ASSERT_EQUAL(info->height, cfg->scale_res.height);
|
||||
TEST_ASSERT_EQUAL(info->format_id, cfg->in_pixel_fmt);
|
||||
} else if (strcmp(tag, "vid_crop") == 0) {
|
||||
esp_imgfx_crop_cfg_t *cfg = (esp_imgfx_crop_cfg_t *)OBJ_GET_CFG(ctx);
|
||||
TEST_ASSERT_EQUAL(info->width, cfg->cropped_res.width);
|
||||
TEST_ASSERT_EQUAL(info->height, cfg->cropped_res.height);
|
||||
TEST_ASSERT_EQUAL(info->format_id, cfg->in_pixel_fmt);
|
||||
} else if (strcmp(tag, "vid_rotate") == 0) {
|
||||
esp_imgfx_rotate_cfg_t *cfg = (esp_imgfx_rotate_cfg_t *)OBJ_GET_CFG(ctx);
|
||||
if (cfg->degree % 90 == 0
|
||||
|| cfg->degree % 270 == 0) {
|
||||
TEST_ASSERT_EQUAL(info->width, cfg->in_res.height);
|
||||
TEST_ASSERT_EQUAL(info->height, cfg->in_res.width);
|
||||
} else {
|
||||
TEST_ASSERT_EQUAL(info->width, cfg->in_res.width);
|
||||
TEST_ASSERT_EQUAL(info->height, cfg->in_res.height);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(info->format_id, cfg->in_pixel_fmt);
|
||||
} else if (strcmp(tag, "vid_color_cvt") == 0) {
|
||||
esp_imgfx_color_convert_cfg_t *cfg = (esp_imgfx_color_convert_cfg_t *)OBJ_GET_CFG(ctx);
|
||||
TEST_ASSERT_EQUAL(info->width, cfg->in_res.width);
|
||||
TEST_ASSERT_EQUAL(info->height, cfg->in_res.height);
|
||||
TEST_ASSERT_EQUAL(info->format_id, cfg->out_pixel_fmt);
|
||||
} else {
|
||||
return ESP_GMF_ERR_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Event callback");
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t imgfx_acquire_read(void *handle, esp_gmf_data_bus_block_t *blk, int wanted_size, int block_ticks)
|
||||
{
|
||||
blk->buf = test_buffer;
|
||||
blk->buf_length = TEST_MAX_IMG_LENGTH;
|
||||
blk->valid_size = wanted_size;
|
||||
memset(blk->buf, 1, wanted_size);
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t imgfx_release_read(void *handle, esp_gmf_data_bus_block_t *blk, int block_ticks)
|
||||
{
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t imgfx_acquire_write(void *handle, esp_gmf_data_bus_block_t *blk, int wanted_size, int block_ticks)
|
||||
{
|
||||
blk->buf = test_buffer1;
|
||||
blk->buf_length = TEST_MAX_IMG_LENGTH;
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t imgfx_release_write(void *handle, esp_gmf_data_bus_block_t *blk, int block_ticks)
|
||||
{
|
||||
ESP_LOGI(TAG, "Output size %d", blk->valid_size);
|
||||
return ESP_GMF_ERR_OK;
|
||||
}
|
||||
|
||||
TEST_CASE("Test for all software video effects", "[ESP_GMF_Effects]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
esp_gmf_port_handle_t in_port = NULL;
|
||||
esp_gmf_port_handle_t out_port = NULL;
|
||||
esp_gmf_obj_handle_t obj_hd = {NULL};
|
||||
esp_gmf_info_video_t info = {
|
||||
.fps = 30,
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
.format_id = ESP_IMGFX_PIXEL_FMT_RGB888,
|
||||
.bitrate = 1000000,
|
||||
};
|
||||
esp_gmf_event_pkt_t event_pkt = {
|
||||
.from = NULL,
|
||||
.type = ESP_GMF_EVT_TYPE_REPORT_INFO,
|
||||
.sub = ESP_GMF_INFO_VIDEO,
|
||||
.payload = &info,
|
||||
.payload_size = sizeof(info),
|
||||
};
|
||||
// Create obj handle and cfg pool
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_create_obj_cfg_pool());
|
||||
test_buffer = (uint8_t *)malloc(TEST_MAX_IMG_LENGTH);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, test_buffer);
|
||||
test_buffer1 = (uint8_t *)malloc(TEST_MAX_IMG_LENGTH);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, test_buffer1);
|
||||
|
||||
for (size_t test_count = 0; test_count < 5; test_count++) {
|
||||
for (size_t el_index = 0; el_index < TEST_MAX_EL_NUM; el_index++) {
|
||||
// New obj
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_obj_dupl(obj_hd_pool[el_index], &obj_hd));
|
||||
// Print obj tag
|
||||
ESP_LOGE(TAG, "%s-%d,obj_hd:%p", (OBJ_GET_TAG(obj_hd)), __LINE__, obj_hd);
|
||||
// Create in/out port
|
||||
in_port = NEW_ESP_GMF_PORT_IN_BLOCK(imgfx_acquire_read, imgfx_release_read, NULL, NULL, TEST_MAX_IMG_LENGTH, TEST_TICK_DELAY);
|
||||
out_port = NEW_ESP_GMF_PORT_OUT_BLOCK(imgfx_acquire_write, imgfx_release_write, NULL, NULL, TEST_MAX_IMG_LENGTH, TEST_TICK_DELAY);
|
||||
// Register in/out port
|
||||
esp_gmf_element_register_in_port(obj_hd, in_port);
|
||||
esp_gmf_element_register_out_port(obj_hd, out_port);
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
// set event callback
|
||||
esp_gmf_element_set_event_func(obj_hd, event_cb, obj_hd);
|
||||
// report info
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_receive_event(obj_hd, &event_pkt, NULL));
|
||||
// Open obj
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_process_open(obj_hd, NULL));
|
||||
// Check received info
|
||||
esp_gmf_info_video_t get_info = {0};
|
||||
esp_gmf_video_el_get_src_info(obj_hd, &get_info);
|
||||
TEST_ASSERT_EQUAL(info.fps, get_info.fps);
|
||||
TEST_ASSERT_EQUAL(info.width, get_info.width);
|
||||
TEST_ASSERT_EQUAL(info.height, get_info.height);
|
||||
TEST_ASSERT_EQUAL(info.format_id, get_info.format_id);
|
||||
TEST_ASSERT_EQUAL(info.bitrate, get_info.bitrate);
|
||||
// Run
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_process_running(obj_hd, NULL));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_process_running(obj_hd, NULL));
|
||||
// Close obj
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_process_close(obj_hd, NULL));
|
||||
}
|
||||
// Delete obj: port will be deleted when obj handle pool is destroyed
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_obj_delete(obj_hd));
|
||||
}
|
||||
}
|
||||
// free buffer
|
||||
free(test_buffer);
|
||||
free(test_buffer1);
|
||||
// Destroy obj handle and cfg pool
|
||||
esp_gmf_destory_obj_cfg_pool();
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
TEST_CASE("ERROR: Input load is NULL", "[ESP_GMF_Effects]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
esp_gmf_port_handle_t in_port = NULL;
|
||||
esp_gmf_port_handle_t out_port = NULL;
|
||||
esp_gmf_obj_handle_t obj_hd = {NULL};
|
||||
// Create obj handle and cfg pool
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_create_obj_cfg_pool());
|
||||
test_buffer = (uint8_t *)malloc(TEST_MAX_IMG_LENGTH);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, test_buffer);
|
||||
test_buffer1 = (uint8_t *)malloc(TEST_MAX_IMG_LENGTH);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, test_buffer1);
|
||||
|
||||
for (size_t el_index = 0; el_index < TEST_MAX_EL_NUM; el_index++) {
|
||||
// New obj
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_obj_dupl(obj_hd_pool[el_index], &obj_hd));
|
||||
// Print obj tag
|
||||
ESP_LOGE(TAG, "%s-%d,obj_hd:%p", (OBJ_GET_TAG(obj_hd)), __LINE__, obj_hd);
|
||||
// Create in/out port
|
||||
in_port = NEW_ESP_GMF_PORT_IN_BLOCK(NULL, NULL, NULL, NULL, TEST_MAX_IMG_LENGTH, TEST_TICK_DELAY);
|
||||
out_port = NEW_ESP_GMF_PORT_OUT_BLOCK(NULL, NULL, NULL, NULL, TEST_MAX_IMG_LENGTH, TEST_TICK_DELAY);
|
||||
|
||||
uint32_t fake_reader_handle;
|
||||
esp_gmf_port_set_writer(in_port, (void *)&fake_reader_handle);
|
||||
// Register in/out port
|
||||
esp_gmf_element_register_in_port(obj_hd, in_port);
|
||||
esp_gmf_element_register_out_port(obj_hd, out_port);
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
// Open obj
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_process_open(obj_hd, NULL));
|
||||
// Run obj
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_FAIL, esp_gmf_element_process_running(obj_hd, NULL));
|
||||
// Close obj
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_element_process_close(obj_hd, NULL));
|
||||
}
|
||||
// Delete obj: port will be deleted when obj handle pool is destroyed
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_obj_delete(obj_hd));
|
||||
}
|
||||
// free buffer
|
||||
free(test_buffer);
|
||||
free(test_buffer1);
|
||||
// Destroy obj handle and cfg pool
|
||||
esp_gmf_destory_obj_cfg_pool();
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
+955
@@ -0,0 +1,955 @@
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "esp_gmf_video_ppa.h"
|
||||
#include "esp_gmf_video_enc.h"
|
||||
#include "esp_gmf_video_dec.h"
|
||||
#include "esp_gmf_video_fps_cvt.h"
|
||||
#include "esp_gmf_video_overlay.h"
|
||||
#include "esp_gmf_pool.h"
|
||||
#include "esp_video_enc_default.h"
|
||||
#include "esp_video_dec_default.h"
|
||||
#include "esp_video_codec_utils.h"
|
||||
#include "gmf_video_pattern.h"
|
||||
#include "esp_gmf_video_param.h"
|
||||
#include "esp_gmf_caps_def.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_gmf_video_scale.h"
|
||||
#include "esp_gmf_video_crop.h"
|
||||
#include "esp_gmf_video_rotate.h"
|
||||
#include "esp_gmf_video_color_convert.h"
|
||||
#include "gmf_loader_setup_defaults.h"
|
||||
|
||||
#define TAG "VID_EL_TEST"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#define TEST_PATTERN_WIDTH (1280)
|
||||
#define TEST_PATTERN_HEIGHT (720)
|
||||
#else
|
||||
#define TEST_PATTERN_WIDTH (320)
|
||||
#define TEST_PATTERN_HEIGHT (240)
|
||||
#endif
|
||||
#define TEST_PATTERN_VERTICAL (false)
|
||||
#define TEST_PATTERN_BAR_COUNT (8)
|
||||
#define TEST_VIDEO_ALIGNMENT (128)
|
||||
|
||||
#define SAFE_FREE(ptr) if (ptr) { \
|
||||
esp_gmf_oal_free(ptr); \
|
||||
ptr = NULL; \
|
||||
}
|
||||
|
||||
#define ELEMS(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#define VIDEO_EL_MAX_STACK_SIZE (40 * 1024)
|
||||
|
||||
typedef struct {
|
||||
// Src information
|
||||
uint32_t in_frame_count;
|
||||
uint32_t src_codec;
|
||||
esp_gmf_video_resolution_t src_res;
|
||||
uint8_t *src_pixel;
|
||||
uint32_t src_size;
|
||||
uint8_t *src_copy;
|
||||
|
||||
// Overlay information
|
||||
uint8_t *overlay_data;
|
||||
uint32_t overlay_size;
|
||||
esp_gmf_video_resolution_t overlay_res;
|
||||
|
||||
// Out information
|
||||
uint16_t rotate_degree;
|
||||
uint32_t out_codec;
|
||||
esp_gmf_video_resolution_t out_res;
|
||||
uint8_t *out_pixel;
|
||||
uint32_t out_size;
|
||||
uint32_t out_frame_count;
|
||||
uint32_t out_max_size;
|
||||
bool no_need_free;
|
||||
} video_el_test_t;
|
||||
|
||||
typedef struct {
|
||||
esp_gmf_pool_handle_t pool;
|
||||
esp_gmf_pipeline_handle_t pipe;
|
||||
esp_gmf_task_handle_t task;
|
||||
esp_gmf_element_handle_t convert_hd;
|
||||
esp_gmf_element_handle_t enc_hd;
|
||||
esp_gmf_element_handle_t rate_hd;
|
||||
esp_gmf_element_handle_t overlay_hd;
|
||||
esp_gmf_element_handle_t dec_hd;
|
||||
} convert_res_t;
|
||||
|
||||
static video_el_test_t video_el_inst;
|
||||
|
||||
static esp_gmf_element_handle_t get_element_by_caps_from_pool(esp_gmf_pool_handle_t pool, uint64_t caps_cc)
|
||||
{
|
||||
const void *iter = NULL;
|
||||
esp_gmf_element_handle_t element = NULL;
|
||||
while (esp_gmf_pool_iterate_element(pool, &iter, &element) == ESP_GMF_ERR_OK) {
|
||||
const esp_gmf_cap_t *caps = NULL;
|
||||
esp_gmf_element_get_caps(element, &caps);
|
||||
while (caps) {
|
||||
if (caps->cap_eightcc == caps_cc) {
|
||||
return element;
|
||||
}
|
||||
caps = caps->next;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static esp_gmf_element_handle_t get_element_by_caps_from_pipe(esp_gmf_pipeline_handle_t pipe, uint64_t caps_cc)
|
||||
{
|
||||
const esp_gmf_cap_t *caps = NULL;
|
||||
esp_gmf_element_handle_t element = NULL;
|
||||
esp_gmf_pipeline_get_head_el(pipe, &element);
|
||||
|
||||
for (; element; esp_gmf_pipeline_get_next_el(pipe, element, &element)) {
|
||||
esp_gmf_element_get_caps(element, &caps);
|
||||
for (; caps; caps = caps->next) {
|
||||
if (caps->cap_eightcc == caps_cc) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void get_pattern_info(pattern_info_t *info, bool is_out)
|
||||
{
|
||||
if (is_out == false) {
|
||||
info->format_id = video_el_inst.src_codec;
|
||||
info->res = video_el_inst.src_res;
|
||||
info->pixel = video_el_inst.src_pixel;
|
||||
info->data_size = video_el_inst.src_size;
|
||||
info->bar_count = TEST_PATTERN_BAR_COUNT;
|
||||
info->vertical = TEST_PATTERN_VERTICAL;
|
||||
} else {
|
||||
info->format_id = video_el_inst.out_codec;
|
||||
info->res = video_el_inst.out_res;
|
||||
info->pixel = video_el_inst.out_pixel;
|
||||
info->data_size = video_el_inst.out_size;
|
||||
info->bar_count = TEST_PATTERN_BAR_COUNT;
|
||||
if (video_el_inst.rotate_degree == 90 || video_el_inst.rotate_degree == 270) {
|
||||
info->vertical = !TEST_PATTERN_VERTICAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int allocate_src_pattern(uint32_t src_codec, bool copy)
|
||||
{
|
||||
video_el_inst.src_res.width = TEST_PATTERN_WIDTH;
|
||||
video_el_inst.src_res.height = TEST_PATTERN_HEIGHT;
|
||||
video_el_inst.src_codec = src_codec;
|
||||
esp_video_codec_resolution_t res = {
|
||||
.width = video_el_inst.src_res.width,
|
||||
.height = video_el_inst.src_res.height,
|
||||
};
|
||||
video_el_inst.src_size = esp_video_codec_get_image_size((esp_video_codec_pixel_fmt_t)src_codec, &res);
|
||||
video_el_inst.src_pixel = esp_gmf_oal_malloc_align(TEST_VIDEO_ALIGNMENT, video_el_inst.src_size);
|
||||
if (video_el_inst.src_pixel == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pattern_info_t pattern_info = {};
|
||||
get_pattern_info(&pattern_info, false);
|
||||
gen_pattern_color_bar(&pattern_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_result_pattern(void)
|
||||
{
|
||||
pattern_info_t src_info = {};
|
||||
pattern_info_t out_info = {};
|
||||
get_pattern_info(&src_info, false);
|
||||
get_pattern_info(&out_info, true);
|
||||
draw_convert_result(&src_info, &out_info);
|
||||
}
|
||||
|
||||
static void free_video_el_inst(void)
|
||||
{
|
||||
SAFE_FREE(video_el_inst.src_pixel);
|
||||
SAFE_FREE(video_el_inst.overlay_data);
|
||||
if (video_el_inst.no_need_free == false) {
|
||||
SAFE_FREE(video_el_inst.out_pixel);
|
||||
}
|
||||
video_el_inst.out_max_size = 0;
|
||||
video_el_inst.out_pixel = NULL;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t in_acquire(void *handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)
|
||||
{
|
||||
load->pts = video_el_inst.in_frame_count * 100;
|
||||
load->buf = video_el_inst.src_pixel;
|
||||
load->valid_size = video_el_inst.src_size;
|
||||
load->buf_length = load->valid_size;
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t in_release(void *handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)
|
||||
{
|
||||
video_el_inst.in_frame_count++;
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t overlay_acquire(void *handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)
|
||||
{
|
||||
load->pts = 255;
|
||||
load->buf = video_el_inst.overlay_data;
|
||||
load->valid_size = video_el_inst.overlay_size;
|
||||
load->buf_length = video_el_inst.overlay_size;
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t overlay_release(void *handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)
|
||||
{
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t out_acquire(void *handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)
|
||||
{
|
||||
if (load->buf) {
|
||||
video_el_inst.no_need_free = true;
|
||||
} else {
|
||||
if (wanted_size > video_el_inst.out_max_size) {
|
||||
SAFE_FREE(video_el_inst.out_pixel);
|
||||
uint8_t *new_buf = esp_gmf_oal_malloc_align(TEST_VIDEO_ALIGNMENT, wanted_size + TEST_VIDEO_ALIGNMENT);
|
||||
if (new_buf == NULL) {
|
||||
ESP_LOGE(TAG, "Fail to allocate %d bytes for output buffer", (int)wanted_size + TEST_VIDEO_ALIGNMENT);
|
||||
return -1;
|
||||
}
|
||||
video_el_inst.out_pixel = new_buf;
|
||||
video_el_inst.out_max_size = wanted_size;
|
||||
}
|
||||
load->buf = video_el_inst.out_pixel;
|
||||
load->buf_length = video_el_inst.out_max_size;
|
||||
}
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static esp_gmf_err_io_t out_release(void *handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)
|
||||
{
|
||||
video_el_inst.out_pixel = load->buf;
|
||||
video_el_inst.out_size = load->valid_size;
|
||||
ESP_LOGI(TAG, "Out frame %d size %d", (int)video_el_inst.out_frame_count, (int)video_el_inst.out_size);
|
||||
video_el_inst.out_frame_count++;
|
||||
// FIXME: why add this ugly code
|
||||
if (video_el_inst.no_need_free == false) {
|
||||
load->buf = NULL;
|
||||
}
|
||||
return ESP_GMF_IO_OK;
|
||||
}
|
||||
|
||||
static int prepare_pool(convert_res_t *res)
|
||||
{
|
||||
memset(res, 0, sizeof(*res));
|
||||
esp_gmf_pool_init(&res->pool);
|
||||
if (res->pool == NULL) {
|
||||
return -1;
|
||||
}
|
||||
gmf_loader_setup_video_codec_default(res->pool);
|
||||
gmf_loader_setup_video_effects_default(res->pool);
|
||||
ESP_GMF_POOL_SHOW_ITEMS(res->pool);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prepare_convert_pipeline(convert_res_t *res, const char **elements)
|
||||
{
|
||||
int n = 0;
|
||||
const char **header = elements;
|
||||
while (*header) {
|
||||
n++;
|
||||
header++;
|
||||
}
|
||||
esp_gmf_pool_new_pipeline(res->pool, NULL, elements, n, NULL, &res->pipe);
|
||||
if (res->pipe == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set input and output buffer
|
||||
esp_gmf_port_handle_t in_port = NEW_ESP_GMF_PORT_IN_BLOCK(in_acquire, in_release, NULL, NULL, 0, ESP_GMF_MAX_DELAY);
|
||||
esp_gmf_pipeline_reg_el_port(res->pipe, elements[0], ESP_GMF_IO_DIR_READER, in_port);
|
||||
// Use byte block to avoid malloc again
|
||||
esp_gmf_port_handle_t out_port = NEW_ESP_GMF_PORT_OUT_BLOCK(out_acquire, out_release, NULL, NULL, 0, ESP_GMF_MAX_DELAY);
|
||||
esp_gmf_pipeline_reg_el_port(res->pipe, elements[n - 1], ESP_GMF_IO_DIR_WRITER, out_port);
|
||||
|
||||
esp_gmf_task_cfg_t cfg = DEFAULT_ESP_GMF_TASK_CONFIG();
|
||||
cfg.thread.stack_in_ext = true;
|
||||
cfg.thread.stack = VIDEO_EL_MAX_STACK_SIZE;
|
||||
esp_gmf_task_init(&cfg, &res->task);
|
||||
if (res->task == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
esp_gmf_pipeline_bind_task(res->pipe, res->task);
|
||||
esp_gmf_pipeline_loading_jobs(res->pipe);
|
||||
|
||||
esp_gmf_pipeline_get_el_by_name(res->pipe, "vid_ppa", &res->convert_hd);
|
||||
esp_gmf_pipeline_get_el_by_name(res->pipe, "vid_enc", &res->enc_hd);
|
||||
esp_gmf_pipeline_get_el_by_name(res->pipe, "vid_fps_cvt", &res->rate_hd);
|
||||
esp_gmf_pipeline_get_el_by_name(res->pipe, "vid_overlay", &res->overlay_hd);
|
||||
esp_gmf_pipeline_get_el_by_name(res->pipe, "vid_dec", &res->dec_hd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void release_convert_pipeline(convert_res_t *res)
|
||||
{
|
||||
if (res->pipe) {
|
||||
esp_gmf_pipeline_stop(res->pipe);
|
||||
}
|
||||
if (res->task) {
|
||||
esp_gmf_task_deinit(res->task);
|
||||
}
|
||||
if (res->pipe) {
|
||||
esp_gmf_pipeline_destroy(res->pipe);
|
||||
}
|
||||
gmf_loader_teardown_video_codec_default(res->pool);
|
||||
gmf_loader_teardown_video_effects_default(res->pool);
|
||||
esp_gmf_pool_deinit(res->pool);
|
||||
}
|
||||
|
||||
static int test_color_convert(convert_res_t *res, uint32_t convert_pair[][2], int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
// Gen pattern
|
||||
allocate_src_pattern(convert_pair[i][0], false);
|
||||
video_el_inst.out_res = video_el_inst.src_res;
|
||||
video_el_inst.out_codec = convert_pair[i][1];
|
||||
esp_gmf_info_video_t info = {
|
||||
.format_id = convert_pair[i][0],
|
||||
.width = TEST_PATTERN_WIDTH,
|
||||
.height = TEST_PATTERN_HEIGHT,
|
||||
};
|
||||
esp_gmf_element_handle_t convert_hd;
|
||||
convert_hd = get_element_by_caps_from_pipe(res->pipe, ESP_GMF_CAPS_VIDEO_COLOR_CONVERT);
|
||||
esp_gmf_video_param_set_dst_format(convert_hd, convert_pair[i][1]);
|
||||
esp_gmf_pipeline_report_info(res->pipe, ESP_GMF_INFO_VIDEO, &info, sizeof(info));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(res->pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(res->pipe));
|
||||
show_result_pattern();
|
||||
free_video_el_inst();
|
||||
esp_gmf_pipeline_reset(res->pipe);
|
||||
esp_gmf_pipeline_loading_jobs(res->pipe);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32P4
|
||||
TEST_CASE("Color convert HW", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_ppa", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, (const char **)name));
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_OUYY_EVYY},
|
||||
{ESP_FOURCC_OUYY_EVYY, ESP_FOURCC_RGB16},
|
||||
};
|
||||
test_color_convert(&res, convert_pair, ELEMS(convert_pair));
|
||||
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Color convert SW", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_color_cvt", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, (const char **)name));
|
||||
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_OUYY_EVYY},
|
||||
{ESP_FOURCC_OUYY_EVYY, ESP_FOURCC_RGB16},
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_BGR16},
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_RGB24},
|
||||
};
|
||||
test_color_convert(&res, convert_pair, ELEMS(convert_pair));
|
||||
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
TEST_CASE("Color convert by caps", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
esp_gmf_element_handle_t element;
|
||||
element = get_element_by_caps_from_pool(res.pool, ESP_GMF_CAPS_VIDEO_COLOR_CONVERT);
|
||||
const char *name[] = {OBJ_GET_TAG(element), NULL};
|
||||
printf("Get element name %s\n", OBJ_GET_TAG(element));
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, (const char **)name));
|
||||
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_OUYY_EVYY},
|
||||
{ESP_FOURCC_OUYY_EVYY, ESP_FOURCC_RGB16},
|
||||
};
|
||||
test_color_convert(&res, convert_pair, ELEMS(convert_pair));
|
||||
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
static int test_scale(convert_res_t *res, uint32_t convert_pair[][2], int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
// Gen pattern
|
||||
allocate_src_pattern(convert_pair[i][0], false);
|
||||
video_el_inst.out_res.width = video_el_inst.src_res.width >> 1;
|
||||
video_el_inst.out_res.height = video_el_inst.src_res.height >> 1;
|
||||
video_el_inst.out_codec = convert_pair[i][1];
|
||||
esp_gmf_element_handle_t convert_hd;
|
||||
convert_hd = get_element_by_caps_from_pipe(res->pipe, ESP_GMF_CAPS_VIDEO_COLOR_CONVERT);
|
||||
esp_gmf_video_param_set_dst_format(convert_hd, convert_pair[i][1]);
|
||||
esp_gmf_element_handle_t scale_hd;
|
||||
scale_hd = get_element_by_caps_from_pipe(res->pipe, ESP_GMF_CAPS_VIDEO_SCALE);
|
||||
esp_gmf_video_param_set_dst_resolution(scale_hd, &video_el_inst.out_res);
|
||||
|
||||
esp_gmf_info_video_t info = {
|
||||
.format_id = convert_pair[i][0],
|
||||
.width = TEST_PATTERN_WIDTH,
|
||||
.height = TEST_PATTERN_HEIGHT,
|
||||
};
|
||||
|
||||
esp_gmf_pipeline_report_info(res->pipe, ESP_GMF_INFO_VIDEO, &info, sizeof(info));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(res->pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(res->pipe));
|
||||
show_result_pattern();
|
||||
free_video_el_inst();
|
||||
esp_gmf_pipeline_reset(res->pipe);
|
||||
esp_gmf_pipeline_loading_jobs(res->pipe);
|
||||
esp_cpu_clear_watchpoint(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32P4
|
||||
TEST_CASE("Scale HW", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_ppa", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, (const char **)name));
|
||||
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_OUYY_EVYY},
|
||||
{ESP_FOURCC_OUYY_EVYY, ESP_FOURCC_RGB16},
|
||||
};
|
||||
test_scale(&res, convert_pair, ELEMS(convert_pair));
|
||||
|
||||
// Clearup resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Scale SW", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_scale", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, (const char **)name));
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_RGB16},
|
||||
{ESP_FOURCC_RGB24, ESP_FOURCC_RGB24},
|
||||
};
|
||||
test_scale(&res, convert_pair, ELEMS(convert_pair));
|
||||
|
||||
// Clearup resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
static int test_rotate(convert_res_t *res, uint32_t convert_pair[][2], int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
// Gen pattern
|
||||
allocate_src_pattern(convert_pair[i][0], false);
|
||||
video_el_inst.out_res.width = video_el_inst.src_res.height;
|
||||
video_el_inst.out_res.height = video_el_inst.src_res.width;
|
||||
video_el_inst.out_codec = convert_pair[i][1];
|
||||
video_el_inst.rotate_degree = i & 1 ? 90 : 270;
|
||||
|
||||
esp_gmf_element_handle_t convert_hd;
|
||||
convert_hd = get_element_by_caps_from_pipe(res->pipe, ESP_GMF_CAPS_VIDEO_COLOR_CONVERT);
|
||||
esp_gmf_video_param_set_dst_format(convert_hd, convert_pair[i][1]);
|
||||
esp_gmf_element_handle_t rotate_hd;
|
||||
rotate_hd = get_element_by_caps_from_pipe(res->pipe, ESP_GMF_CAPS_VIDEO_ROTATE);
|
||||
esp_gmf_video_param_set_rotate_angle(rotate_hd, video_el_inst.rotate_degree);
|
||||
esp_gmf_video_param_set_dst_resolution(rotate_hd, &video_el_inst.out_res);
|
||||
|
||||
esp_gmf_info_video_t info = {
|
||||
.format_id = convert_pair[i][0],
|
||||
.width = TEST_PATTERN_WIDTH,
|
||||
.height = TEST_PATTERN_HEIGHT,
|
||||
};
|
||||
|
||||
esp_gmf_pipeline_report_info(res->pipe, ESP_GMF_INFO_VIDEO, &info, sizeof(info));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(res->pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(res->pipe));
|
||||
show_result_pattern();
|
||||
free_video_el_inst();
|
||||
esp_gmf_pipeline_reset(res->pipe);
|
||||
esp_gmf_pipeline_loading_jobs(res->pipe);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32P4
|
||||
TEST_CASE("Rotate HW", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_ppa", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, name));
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_OUYY_EVYY},
|
||||
{ESP_FOURCC_OUYY_EVYY, ESP_FOURCC_RGB16},
|
||||
};
|
||||
test_rotate(&res, convert_pair, ELEMS(convert_pair));
|
||||
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Rotate SW", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_rotate", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, (const char **)name));
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_RGB16},
|
||||
};
|
||||
test_rotate(&res, convert_pair, ELEMS(convert_pair));
|
||||
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
static int test_crop(convert_res_t *res, uint32_t convert_pair[][2], int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
// Gen pattern
|
||||
allocate_src_pattern(convert_pair[i][0], false);
|
||||
video_el_inst.out_res.width = video_el_inst.src_res.width >> 1;
|
||||
video_el_inst.out_res.height = video_el_inst.src_res.height >> 1;
|
||||
video_el_inst.out_codec = convert_pair[i][1];
|
||||
|
||||
esp_gmf_video_rgn_t crop_rgn = {
|
||||
.x = video_el_inst.src_res.width >> 2,
|
||||
.y = video_el_inst.src_res.height >> 2,
|
||||
.width = video_el_inst.out_res.width,
|
||||
.height = video_el_inst.out_res.height,
|
||||
};
|
||||
esp_gmf_element_handle_t convert_hd;
|
||||
convert_hd = get_element_by_caps_from_pipe(res->pipe, ESP_GMF_CAPS_VIDEO_COLOR_CONVERT);
|
||||
esp_gmf_video_param_set_dst_format(convert_hd, convert_pair[i][1]);
|
||||
|
||||
esp_gmf_element_handle_t crop_hd;
|
||||
crop_hd = get_element_by_caps_from_pipe(res->pipe, ESP_GMF_CAPS_VIDEO_CROP);
|
||||
esp_gmf_video_param_set_cropped_region(crop_hd, &crop_rgn);
|
||||
esp_gmf_video_param_set_dst_resolution(crop_hd, &video_el_inst.out_res);
|
||||
|
||||
esp_gmf_info_video_t info = {
|
||||
.format_id = convert_pair[i][0],
|
||||
.width = TEST_PATTERN_WIDTH,
|
||||
.height = TEST_PATTERN_HEIGHT,
|
||||
};
|
||||
|
||||
esp_gmf_pipeline_report_info(res->pipe, ESP_GMF_INFO_VIDEO, &info, sizeof(info));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(res->pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(res->pipe));
|
||||
show_result_pattern();
|
||||
free_video_el_inst();
|
||||
esp_gmf_pipeline_reset(res->pipe);
|
||||
esp_gmf_pipeline_loading_jobs(res->pipe);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32P4
|
||||
TEST_CASE("Crop HW", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_ppa", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, name));
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_OUYY_EVYY},
|
||||
{ESP_FOURCC_OUYY_EVYY, ESP_FOURCC_RGB16},
|
||||
};
|
||||
test_crop(&res, convert_pair, ELEMS(convert_pair));
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Crop only SW", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
|
||||
const char *name[] = {"vid_crop", NULL};
|
||||
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, name));
|
||||
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_RGB16},
|
||||
// { ESP_FOURCC_RGB24, ESP_FOURCC_RGB16 },
|
||||
};
|
||||
test_crop(&res, convert_pair, ELEMS(convert_pair));
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
TEST_CASE("Encoder only", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_enc", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, name));
|
||||
|
||||
uint32_t convert_pair[][2] = {
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
{ESP_FOURCC_OUYY_EVYY, ESP_FOURCC_H264},
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_MJPG},
|
||||
#else
|
||||
{ESP_FOURCC_RGB24, ESP_FOURCC_MJPG},
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
{ESP_FOURCC_YUV420P, ESP_FOURCC_H264},
|
||||
#endif /* CON FIG_IDF_TARGET_ESP32S3 */
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32P4 */
|
||||
};
|
||||
for (int i = 0; i < ELEMS(convert_pair); i++) {
|
||||
// Gen pattern
|
||||
allocate_src_pattern(convert_pair[i][0], false);
|
||||
video_el_inst.out_res = video_el_inst.src_res;
|
||||
video_el_inst.out_codec = convert_pair[i][1];
|
||||
|
||||
esp_gmf_info_video_t info = {
|
||||
.format_id = convert_pair[i][0],
|
||||
.width = TEST_PATTERN_WIDTH,
|
||||
.height = TEST_PATTERN_HEIGHT,
|
||||
.fps = 10,
|
||||
};
|
||||
// esp_gmf_video_enc_set_dst_codec(res.enc_hd, convert_pair[i][1]);
|
||||
esp_gmf_video_param_set_dst_codec(res.enc_hd, convert_pair[i][1]);
|
||||
esp_gmf_pipeline_report_info(res.pipe, ESP_GMF_INFO_VIDEO, &info, sizeof(info));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(res.pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(res.pipe));
|
||||
free_video_el_inst();
|
||||
esp_gmf_pipeline_reset(res.pipe);
|
||||
esp_gmf_pipeline_loading_jobs(res.pipe);
|
||||
}
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
TEST_CASE("FPS convert only", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_fps_cvt", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, name));
|
||||
uint32_t convert_pair[][2] = {
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_MJPG},
|
||||
};
|
||||
for (int i = 0; i < ELEMS(convert_pair); i++) {
|
||||
// Gen pattern
|
||||
allocate_src_pattern(convert_pair[i][0], false);
|
||||
video_el_inst.out_res = video_el_inst.src_res;
|
||||
video_el_inst.out_codec = convert_pair[i][1];
|
||||
esp_gmf_info_video_t info = {
|
||||
.format_id = convert_pair[i][0],
|
||||
.width = TEST_PATTERN_WIDTH,
|
||||
.height = TEST_PATTERN_HEIGHT,
|
||||
.fps = 10,
|
||||
};
|
||||
// esp_gmf_video_fps_cvt_set_fps(res.rate_hd, 5);
|
||||
esp_gmf_video_param_set_fps(res.rate_hd, 5);
|
||||
esp_gmf_pipeline_report_info(res.pipe, ESP_GMF_INFO_VIDEO, &info, sizeof(info));
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(res.pipe));
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(res.pipe));
|
||||
free_video_el_inst();
|
||||
esp_gmf_pipeline_reset(res.pipe);
|
||||
esp_gmf_pipeline_loading_jobs(res.pipe);
|
||||
}
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
TEST_CASE("Overlay Test", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_overlay", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, name));
|
||||
|
||||
allocate_src_pattern(ESP_FOURCC_RGB16, false);
|
||||
|
||||
// Create overlay buffer
|
||||
video_el_inst.overlay_res.width = video_el_inst.src_res.width / 2;
|
||||
video_el_inst.overlay_res.height = video_el_inst.src_res.height / 2;
|
||||
esp_video_codec_resolution_t overlay_res = {
|
||||
.width = video_el_inst.overlay_res.width,
|
||||
.height = video_el_inst.overlay_res.height,
|
||||
};
|
||||
video_el_inst.overlay_size = esp_video_codec_get_image_size((esp_video_codec_pixel_fmt_t)ESP_FOURCC_RGB16,
|
||||
(esp_video_codec_resolution_t *)&overlay_res);
|
||||
video_el_inst.overlay_data = esp_gmf_oal_malloc_align(TEST_VIDEO_ALIGNMENT, video_el_inst.overlay_size);
|
||||
TEST_ASSERT_NOT_NULL(video_el_inst.src_pixel);
|
||||
pattern_info_t pattern_info = {
|
||||
.format_id = ESP_FOURCC_RGB16,
|
||||
.res = video_el_inst.overlay_res,
|
||||
.pixel = video_el_inst.overlay_data,
|
||||
.data_size = video_el_inst.overlay_size,
|
||||
.bar_count = TEST_PATTERN_BAR_COUNT / 2,
|
||||
.vertical = !TEST_PATTERN_VERTICAL,
|
||||
};
|
||||
gen_pattern_color_bar(&pattern_info);
|
||||
|
||||
video_el_inst.out_res = video_el_inst.src_res;
|
||||
video_el_inst.out_codec = ESP_FOURCC_RGB16;
|
||||
|
||||
esp_gmf_overlay_rgn_info_t rgn = {
|
||||
.format_id = ESP_FOURCC_RGB16,
|
||||
.dst_rgn = {
|
||||
.x = video_el_inst.src_res.width / 4,
|
||||
.y = video_el_inst.src_res.height / 4,
|
||||
.width = video_el_inst.overlay_res.width,
|
||||
.height = video_el_inst.overlay_res.height,
|
||||
},
|
||||
};
|
||||
// esp_gmf_video_overlay_set_rgn(res.overlay_hd, &rgn);
|
||||
esp_gmf_video_param_set_overlay_rgn(res.overlay_hd, &rgn);
|
||||
|
||||
esp_gmf_port_handle_t overlay_port = NEW_ESP_GMF_PORT_IN_BLOCK(overlay_acquire, overlay_release, NULL, NULL, 0, ESP_GMF_MAX_DELAY);
|
||||
// esp_gmf_video_overlay_set_overlay_port(res.overlay_hd, overlay_port);
|
||||
esp_gmf_video_param_set_overlay_port(res.overlay_hd, overlay_port);
|
||||
// esp_gmf_video_overlay_enable(res.overlay_hd, true);
|
||||
esp_gmf_video_param_overlay_enable(res.overlay_hd, true);
|
||||
|
||||
esp_gmf_info_video_t info = {
|
||||
.format_id = ESP_FOURCC_RGB16,
|
||||
.width = TEST_PATTERN_WIDTH,
|
||||
.height = TEST_PATTERN_HEIGHT,
|
||||
.fps = 10,
|
||||
};
|
||||
esp_gmf_pipeline_report_info(res.pipe, ESP_GMF_INFO_VIDEO, &info, sizeof(info));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(res.pipe));
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(res.pipe));
|
||||
show_result_pattern();
|
||||
|
||||
free_video_el_inst();
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
if (overlay_port) {
|
||||
esp_gmf_port_deinit(overlay_port);
|
||||
}
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
|
||||
TEST_CASE("Encoder to Decode", "[ESP_GMF_VIDEO]")
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_add_default_adapter();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
convert_res_t res;
|
||||
memset(&video_el_inst, 0, sizeof(video_el_test_t));
|
||||
prepare_pool(&res);
|
||||
const char *name[] = {"vid_enc", "vid_dec", NULL};
|
||||
TEST_ASSERT_EQUAL(0, prepare_convert_pipeline(&res, name));
|
||||
|
||||
uint32_t convert_pair[][3] = {
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
{ESP_FOURCC_OUYY_EVYY, ESP_FOURCC_H264, ESP_FOURCC_YUV420P},
|
||||
{ESP_FOURCC_RGB16, ESP_FOURCC_MJPG, ESP_FOURCC_RGB16},
|
||||
#else
|
||||
{ESP_FOURCC_RGB24, ESP_FOURCC_MJPG, ESP_FOURCC_RGB16},
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
{ESP_FOURCC_YUV420P, ESP_FOURCC_H264, ESP_FOURCC_YUV420P},
|
||||
#endif /* CON FIG_IDF_TARGET_ESP32S3 */
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32P4 */
|
||||
};
|
||||
for (int i = 0; i < ELEMS(convert_pair); i++) {
|
||||
// Gen pattern
|
||||
allocate_src_pattern(convert_pair[i][0], false);
|
||||
video_el_inst.out_res = video_el_inst.src_res;
|
||||
video_el_inst.out_codec = convert_pair[i][2];
|
||||
|
||||
esp_gmf_info_video_t info = {
|
||||
.format_id = convert_pair[i][0],
|
||||
.width = TEST_PATTERN_WIDTH,
|
||||
.height = TEST_PATTERN_HEIGHT,
|
||||
.fps = 10,
|
||||
};
|
||||
// esp_gmf_video_enc_set_dst_codec(res.enc_hd, convert_pair[i][1]);
|
||||
esp_gmf_video_param_set_dst_codec(res.enc_hd, convert_pair[i][1]);
|
||||
esp_gmf_pipeline_report_info(res.pipe, ESP_GMF_INFO_VIDEO, &info, sizeof(info));
|
||||
// Set decoder information
|
||||
// esp_gmf_video_dec_set_dst_format(res.dec_hd, convert_pair[i][2]);
|
||||
esp_gmf_video_param_set_dst_format(res.dec_hd, convert_pair[i][2]);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_run(res.pipe));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
TEST_ASSERT_EQUAL(ESP_GMF_ERR_OK, esp_gmf_pipeline_stop(res.pipe));
|
||||
show_result_pattern();
|
||||
free_video_el_inst();
|
||||
esp_gmf_pipeline_reset(res.pipe);
|
||||
esp_gmf_pipeline_loading_jobs(res.pipe);
|
||||
}
|
||||
// Clear up resources
|
||||
release_convert_pipeline(&res);
|
||||
|
||||
#ifdef MEDIA_LIB_MEM_TEST
|
||||
media_lib_stop_mem_trace();
|
||||
#endif /* MEDIA_LIB_MEM_TEST */
|
||||
ESP_GMF_MEM_SHOW(TAG);
|
||||
}
|
||||
+558
@@ -0,0 +1,558 @@
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_fourcc.h"
|
||||
#include "esp_gmf_video_types.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GET_RGB565_R(x) (((((x) >> 11) & 0x1F) << 3) | (((x) >> 8) & 0x07))
|
||||
#define GET_RGB565_G(x) (((((x) >> 5) & 0x3F) << 2) | (((x) >> 3) & 0x03))
|
||||
#define GET_RGB565_B(x) ((((x) & 0x1F) << 3) | (((x) & 0x1C) >> 2))
|
||||
#define SWAP_EDIAN(x) (((x) << 8) | ((x) >> 8))
|
||||
#define CLAMP(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))
|
||||
|
||||
typedef struct {
|
||||
uint32_t format_id;
|
||||
esp_gmf_video_resolution_t res;
|
||||
uint8_t *pixel;
|
||||
uint32_t data_size;
|
||||
bool vertical;
|
||||
uint8_t bar_count;
|
||||
} pattern_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t y;
|
||||
uint8_t u;
|
||||
uint8_t v;
|
||||
} yuv_pixel_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} rgb888_pixel_t;
|
||||
|
||||
static int gen_pattern_color_bar(pattern_info_t *info)
|
||||
{
|
||||
uint8_t *pixel = info->pixel;
|
||||
bool vertical = info->vertical;
|
||||
uint8_t n = info->bar_count;
|
||||
|
||||
switch (info->format_id) {
|
||||
case ESP_FOURCC_BGR24: {
|
||||
rgb888_pixel_t *color = (rgb888_pixel_t *)malloc(n * sizeof(rgb888_pixel_t));
|
||||
if (color == NULL) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
color[i].r = (uint16_t)(rand() & 0xFF);
|
||||
color[i].g = (uint16_t)(rand() & 0xFF);
|
||||
color[i].g = (uint16_t)(rand() & 0xFF);
|
||||
}
|
||||
if (vertical) {
|
||||
uint32_t bar_w = info->res.width / n;
|
||||
uint32_t last_bar_w = info->res.width - bar_w * (n - 1);
|
||||
for (int y = 0; y < info->res.height; y++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
int points = (i == n - 1 ? last_bar_w : bar_w);
|
||||
for (int x = 0; x < points; x++) {
|
||||
*(pixel++) = color[i].b;
|
||||
*(pixel++) = color[i].g;
|
||||
*(pixel++) = color[i].r;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t bar_h = info->res.height / n;
|
||||
uint32_t last_bar_h = info->res.height - bar_h * (n - 1);
|
||||
for (int i = 0; i < n; i++) {
|
||||
int points = (i == n - 1 ? last_bar_h : bar_h) * info->res.width;
|
||||
for (int x = 0; x < points; x++) {
|
||||
*(pixel++) = color[i].b;
|
||||
*(pixel++) = color[i].g;
|
||||
*(pixel++) = color[i].r;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(color);
|
||||
} break;
|
||||
case ESP_FOURCC_RGB24: {
|
||||
rgb888_pixel_t *color = (rgb888_pixel_t *)malloc(n * sizeof(rgb888_pixel_t));
|
||||
if (color == NULL) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
color[i].r = (uint8_t)(rand() & 0xFF);
|
||||
color[i].g = (uint8_t)(rand() & 0xFF);
|
||||
color[i].g = (uint8_t)(rand() & 0xFF);
|
||||
}
|
||||
if (vertical) {
|
||||
uint32_t bar_w = info->res.width / n;
|
||||
uint32_t last_bar_w = info->res.width - bar_w * (n - 1);
|
||||
for (int y = 0; y < info->res.height; y++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
int points = (i == n - 1 ? last_bar_w : bar_w);
|
||||
for (int x = 0; x < points; x++) {
|
||||
*(pixel++) = color[i].r;
|
||||
*(pixel++) = color[i].g;
|
||||
*(pixel++) = color[i].b;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t bar_h = info->res.height / n;
|
||||
uint32_t last_bar_h = info->res.height - bar_h * (n - 1);
|
||||
for (int i = 0; i < n; i++) {
|
||||
int points = (i == n - 1 ? last_bar_h : bar_h) * info->res.width;
|
||||
for (int x = 0; x < points; x++) {
|
||||
*(pixel++) = color[i].r;
|
||||
*(pixel++) = color[i].g;
|
||||
*(pixel++) = color[i].b;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(color);
|
||||
} break;
|
||||
|
||||
case ESP_FOURCC_RGB16:
|
||||
case ESP_FOURCC_RGB16_BE: {
|
||||
uint16_t *color = (uint16_t *)malloc(n * sizeof(uint16_t));
|
||||
if (color == NULL) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
color[i] = (uint16_t)(rand() & 0xFFFF);
|
||||
}
|
||||
uint16_t *pixel16 = (uint16_t *)pixel;
|
||||
if (vertical) {
|
||||
uint32_t bar_w = info->res.width / n;
|
||||
uint32_t last_bar_w = info->res.width - bar_w * (n - 1);
|
||||
for (int y = 0; y < info->res.height; y++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
int points = (i == n - 1 ? last_bar_w : bar_w);
|
||||
for (int x = 0; x < points; x++) {
|
||||
*(pixel16++) = color[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t bar_h = info->res.height / n;
|
||||
uint32_t last_bar_h = info->res.height - bar_h * (n - 1);
|
||||
for (int i = 0; i < n; i++) {
|
||||
int points = (i == n - 1 ? last_bar_h : bar_h) * info->res.width;
|
||||
for (int x = 0; x < points; x++) {
|
||||
*(pixel16++) = color[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
free(color);
|
||||
} break;
|
||||
case ESP_FOURCC_YUV420P: {
|
||||
yuv_pixel_t *color = (yuv_pixel_t *)malloc(n * sizeof(yuv_pixel_t));
|
||||
if (color == NULL) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
color[i].y = (uint8_t)(rand() & 0xFF);
|
||||
color[i].u = (uint8_t)(rand() & 0xFF);
|
||||
color[i].v = (uint8_t)(rand() & 0xFF);
|
||||
}
|
||||
if (vertical) {
|
||||
uint32_t bar_w = (info->res.width / n) >> 1 << 1;
|
||||
uint32_t last_bar_w = info->res.width - bar_w * (n - 1);
|
||||
// Fill Y firstly
|
||||
for (int y = 0; y < info->res.height; y++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t bytes = (i == n - 1 ? last_bar_w : bar_w);
|
||||
memset(pixel, color[i].y, bytes);
|
||||
pixel += bytes;
|
||||
}
|
||||
}
|
||||
// Fill U
|
||||
for (int y = 0; y < info->res.height >> 1; y++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t bytes = (i == n - 1 ? last_bar_w : bar_w) >> 1;
|
||||
memset(pixel, color[i].u, bytes);
|
||||
pixel += bytes;
|
||||
}
|
||||
}
|
||||
// Fill V
|
||||
for (int y = 0; y < info->res.height >> 1; y++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t bytes = (i == n - 1 ? last_bar_w : bar_w) >> 1;
|
||||
memset(pixel, color[i].v, bytes);
|
||||
pixel += bytes;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t bar_h = (info->res.height / n) >> 1 << 1;
|
||||
uint32_t last_bar_h = info->res.height - bar_h * (n - 1);
|
||||
// Fill Y firstly
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t bytes = (i == n - 1 ? last_bar_h : bar_h) * info->res.width;
|
||||
memset(pixel, color[i].y, bytes);
|
||||
pixel += bytes;
|
||||
}
|
||||
// Fill U
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t bytes = (i == n - 1 ? last_bar_h : bar_h) * info->res.width >> 2;
|
||||
memset(pixel, color[i].u, bytes);
|
||||
pixel += bytes;
|
||||
}
|
||||
// Fill V
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t bytes = (i == n - 1 ? last_bar_h : bar_h) * info->res.width >> 2;
|
||||
memset(pixel, color[i].v, bytes);
|
||||
pixel += bytes;
|
||||
}
|
||||
}
|
||||
free(color);
|
||||
} break;
|
||||
case ESP_FOURCC_UYVY: {
|
||||
yuv_pixel_t *color = (yuv_pixel_t *)malloc(n * sizeof(yuv_pixel_t));
|
||||
if (color == NULL) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
color[i].y = (uint8_t)(rand() & 0xFF);
|
||||
color[i].u = (uint8_t)(rand() & 0xFF);
|
||||
color[i].v = (uint8_t)(rand() & 0xFF);
|
||||
}
|
||||
if (vertical) {
|
||||
uint32_t bar_w = (info->res.width / n) >> 1 << 1;
|
||||
// Fill Y firstly
|
||||
for (int y = 0; y < info->res.height; y++) {
|
||||
int bar_filled = 0;
|
||||
int i = 0;
|
||||
for (int x = 0; x < (info->res.width >> 1); x++) {
|
||||
*pixel++ = color[i].u;
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].v;
|
||||
*pixel++ = color[i].y;
|
||||
bar_filled += 2;
|
||||
if (bar_filled >= bar_w) {
|
||||
bar_filled = 0;
|
||||
if (i < n - 1) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t bar_h = (info->res.height / n) >> 1 << 1;
|
||||
uint32_t last_bar_h = info->res.height - bar_h * (n - 1);
|
||||
// Fill Y firstly
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t bytes = (i == n - 1 ? last_bar_h : bar_h) * info->res.width * 3 / 2;
|
||||
while (bytes > 0) {
|
||||
*pixel++ = color[i].u;
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].v;
|
||||
*pixel++ = color[i].y;
|
||||
bytes -= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(color);
|
||||
} break;
|
||||
case ESP_FOURCC_YUYV: {
|
||||
yuv_pixel_t *color = (yuv_pixel_t *)malloc(n * sizeof(yuv_pixel_t));
|
||||
if (color == NULL) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
color[i].y = (uint8_t)(rand() & 0xFF);
|
||||
color[i].u = (uint8_t)(rand() & 0xFF);
|
||||
color[i].v = (uint8_t)(rand() & 0xFF);
|
||||
}
|
||||
if (vertical) {
|
||||
uint32_t bar_w = (info->res.width / n) >> 1 << 1;
|
||||
// Fill Y firstly
|
||||
for (int y = 0; y < info->res.height; y++) {
|
||||
int bar_filled = 0;
|
||||
int i = 0;
|
||||
for (int x = 0; x < (info->res.width >> 1); x++) {
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].u;
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].v;
|
||||
bar_filled += 2;
|
||||
if (bar_filled >= bar_w) {
|
||||
bar_filled = 0;
|
||||
if (i < n - 1) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t bar_h = (info->res.height / n) >> 1 << 1;
|
||||
uint32_t last_bar_h = info->res.height - bar_h * (n - 1);
|
||||
// Fill Y firstly
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t bytes = (i == n - 1 ? last_bar_h : bar_h) * info->res.width * 3 / 2;
|
||||
while (bytes > 0) {
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].u;
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].v;
|
||||
bytes -= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(color);
|
||||
} break;
|
||||
case ESP_FOURCC_OUYY_EVYY: {
|
||||
yuv_pixel_t *color = (yuv_pixel_t *)malloc(n * sizeof(yuv_pixel_t));
|
||||
if (color == NULL) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
color[i].y = (uint8_t)(rand() & 0xFF);
|
||||
color[i].u = (uint8_t)(rand() & 0xFF);
|
||||
color[i].v = (uint8_t)(rand() & 0xFF);
|
||||
}
|
||||
if (vertical) {
|
||||
uint32_t bar_w = (info->res.width / n) >> 1 << 1;
|
||||
// Fill Y firstly
|
||||
for (int y = 0; y < (info->res.height >> 1); y++) {
|
||||
int bar_filled = 0;
|
||||
int i = 0;
|
||||
for (int x = 0; x < (info->res.width >> 1); x++) {
|
||||
*pixel++ = color[i].u;
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].y;
|
||||
bar_filled += 2;
|
||||
if (bar_filled >= bar_w) {
|
||||
bar_filled = 0;
|
||||
if (i < n - 1) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
bar_filled = 0;
|
||||
i = 0;
|
||||
for (int x = 0; x < (info->res.width >> 1); x++) {
|
||||
*pixel++ = color[i].v;
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].y;
|
||||
bar_filled += 2;
|
||||
if (bar_filled >= bar_w) {
|
||||
bar_filled = 0;
|
||||
if (i < n - 1) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t bar_h = (info->res.height / n) >> 1 << 1;
|
||||
uint32_t last_bar_h = info->res.height - bar_h * (n - 1);
|
||||
// Fill Y firstly
|
||||
for (int i = 0; i < n; i++) {
|
||||
uint32_t height = (i == n - 1 ? last_bar_h : bar_h);
|
||||
uint32_t width = info->res.width >> 1;
|
||||
for (int y = 0; y < (height >> 1); y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
*pixel++ = color[i].u;
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].y;
|
||||
}
|
||||
for (int x = 0; x < width; x++) {
|
||||
*pixel++ = color[i].v;
|
||||
*pixel++ = color[i].y;
|
||||
*pixel++ = color[i].y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(color);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void yuv_to_rgb(uint8_t y, uint8_t u, uint8_t v, rgb888_pixel_t *pixel)
|
||||
{
|
||||
int c = y - 16;
|
||||
int d = u - 128;
|
||||
int e = v - 128;
|
||||
int r_temp = (298 * c + 409 * e + 128) >> 8; // R = Y + 1.403 * (V-128)
|
||||
int g_temp = (298 * c - 100 * d - 208 * e + 128) >> 8; // G = Y - 0.344 * (U-128) - 0.714 * (V-128)
|
||||
int b_temp = (298 * c + 516 * d + 128) >> 8; // B = Y + 1.770 * (U-128)
|
||||
pixel->r = CLAMP(r_temp);
|
||||
pixel->g = CLAMP(g_temp);
|
||||
pixel->b = CLAMP(b_temp);
|
||||
}
|
||||
|
||||
static void get_pixel(pattern_info_t *info, rgb888_pixel_t *pixel, int x, int y)
|
||||
{
|
||||
uint8_t *data = info->pixel;
|
||||
switch (info->format_id) {
|
||||
case ESP_FOURCC_BGR24: {
|
||||
rgb888_pixel_t *src = (rgb888_pixel_t *)data;
|
||||
src += y * info->res.width + x;
|
||||
pixel->b = src->r;
|
||||
pixel->g = src->g;
|
||||
pixel->r = src->b;
|
||||
break;
|
||||
}
|
||||
case ESP_FOURCC_RGB24: {
|
||||
rgb888_pixel_t *src = (rgb888_pixel_t *)data;
|
||||
src += y * info->res.width + x;
|
||||
*pixel = *src;
|
||||
break;
|
||||
}
|
||||
case ESP_FOURCC_RGB16: {
|
||||
uint16_t *src = (uint16_t *)data;
|
||||
src += y * info->res.width + x;
|
||||
pixel->r = GET_RGB565_R(*src);
|
||||
pixel->g = GET_RGB565_G(*src);
|
||||
pixel->b = GET_RGB565_B(*src);
|
||||
break;
|
||||
}
|
||||
case ESP_FOURCC_RGB16_BE: {
|
||||
uint16_t *src = (uint16_t *)data;
|
||||
src += y * info->res.width + x;
|
||||
uint16_t v = SWAP_EDIAN(*src);
|
||||
pixel->r = GET_RGB565_R(v);
|
||||
pixel->g = GET_RGB565_G(v);
|
||||
pixel->b = GET_RGB565_B(v);
|
||||
break;
|
||||
}
|
||||
case ESP_FOURCC_UYVY: {
|
||||
x = (x >> 1 << 1);
|
||||
uint8_t *yuyv = data + y * info->res.width * 2 + x * 2;
|
||||
yuv_to_rgb(yuyv[3], yuyv[0], yuyv[2], pixel);
|
||||
break;
|
||||
}
|
||||
case ESP_FOURCC_YUYV: {
|
||||
x = (x >> 1 << 1);
|
||||
uint8_t *yuyv = data + y * info->res.width * 2 + x * 2;
|
||||
yuv_to_rgb(yuyv[0], yuyv[1], yuyv[3], pixel);
|
||||
break;
|
||||
}
|
||||
case ESP_FOURCC_YUV420P: {
|
||||
uint8_t *py = data + y * info->res.width + x;
|
||||
y >>= 1;
|
||||
x >>= 1;
|
||||
uint8_t *pu = data + info->res.height * info->res.width + y * info->res.width / 2 + x;
|
||||
uint8_t *pv = data + info->res.height * info->res.width * 5 / 4 + y * info->res.width / 2 + x;
|
||||
yuv_to_rgb(py[0], pu[0], pv[0], pixel);
|
||||
break;
|
||||
}
|
||||
case ESP_FOURCC_OUYY_EVYY: {
|
||||
uint8_t *uyy = data + (y >> 1) * info->res.width * 3 + (x >> 1)* 3;
|
||||
uint8_t *vyy = uyy + info->res.width * 3 / 2;
|
||||
uint8_t y_pixel = (y & 1) ? vyy[1 + (x & 1)] : uyy[1 + (x & 1)] ;
|
||||
yuv_to_rgb(y_pixel, uyy[0], vyy[0], pixel);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_convert_result(pattern_info_t *a, pattern_info_t *b)
|
||||
{
|
||||
if (a->bar_count == 0) {
|
||||
return;
|
||||
}
|
||||
printf("\n");
|
||||
int y = 0;
|
||||
rgb888_pixel_t block_start = {};
|
||||
rgb888_pixel_t block_end = {};
|
||||
|
||||
if (a->bar_count == b->bar_count) {
|
||||
int n = a->bar_count;
|
||||
uint32_t bar_w = (a->res.width / n) >> 1 << 1;
|
||||
uint32_t last_bar_w = a->res.width - bar_w * (n - 1);
|
||||
uint32_t bar_h = a->res.height / n;
|
||||
|
||||
uint32_t bar_w_b = (b->res.width / n) >> 1 << 1;
|
||||
uint32_t last_bar_w_b = b->res.width - bar_w_b * (n - 1);
|
||||
uint32_t bar_h_b = b->res.height / n;
|
||||
int y_b = 0;
|
||||
|
||||
for (int col = 0; col < n; col++) {
|
||||
int x = 0;
|
||||
for (int row = 0; row < n; row++) {
|
||||
get_pixel(a, &block_start, x, y);
|
||||
x += (row == n - 1 ? last_bar_w : bar_w);
|
||||
get_pixel(a, &block_end, x - 1, y);
|
||||
printf("\033[48;2;%d;%d;%dm%c\033[0m", block_start.r, block_start.g, block_start.b, ' ');
|
||||
printf("\033[48;2;%d;%d;%dm%c\033[0m", block_end.r, block_end.g, block_end.b, ' ');
|
||||
}
|
||||
if (b->pixel) {
|
||||
printf(" | ");
|
||||
x = 0;
|
||||
for (int row = 0; row < n; row++) {
|
||||
get_pixel(b, &block_start, x, y_b);
|
||||
x += (row == n - 1 ? last_bar_w_b : bar_w_b);
|
||||
get_pixel(b, &block_end, x - 1, y_b);
|
||||
printf("\033[48;2;%d;%d;%dm%c\033[0m", block_start.r, block_start.g, block_start.b, ' ');
|
||||
printf("\033[48;2;%d;%d;%dm%c\033[0m", block_end.r, block_end.g, block_end.b, ' ');
|
||||
}
|
||||
y_b += bar_h_b;
|
||||
}
|
||||
y += bar_h;
|
||||
printf("\n");
|
||||
}
|
||||
} else {
|
||||
// Draw image
|
||||
int n = a->bar_count;
|
||||
uint32_t bar_w = (a->res.width / n) >> 1 << 1;
|
||||
uint32_t last_bar_w = a->res.width - bar_w * (n - 1);
|
||||
uint32_t bar_h = a->res.height / n;
|
||||
|
||||
printf("A:\n");
|
||||
for (int col = 0, y = 0; col < n; col++, y += bar_h) {
|
||||
int x = 0;
|
||||
printf("║ ");
|
||||
for (int row = 0; row < n; row++) {
|
||||
get_pixel(a, &block_start, x, y);
|
||||
x += (row == n - 1 ? last_bar_w : bar_w);
|
||||
get_pixel(a, &block_end, x - 1, y);
|
||||
printf("\033[48;2;%d;%d;%dm%c\033[0m", block_start.r, block_start.g, block_start.b, ' ');
|
||||
printf("\033[48;2;%d;%d;%dm%c\033[0m", block_end.r, block_end.g, block_end.b, ' ');
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (b->pixel) {
|
||||
uint32_t bar_w = (b->res.width / n) >> 1 << 1;
|
||||
uint32_t last_bar_w = b->res.width - bar_w * (n - 1);
|
||||
uint32_t bar_h = b->res.height / n;
|
||||
|
||||
printf("B:\n");
|
||||
for (int col = 0, y = 0; col < n; col++, y += bar_h) {
|
||||
int x = 0;
|
||||
printf("║ ");
|
||||
for (int row = 0; row < n; row++) {
|
||||
get_pixel(b, &block_start, x, y);
|
||||
x += (row == n - 1 ? last_bar_w : bar_w);
|
||||
get_pixel(b, &block_end, x - 1, y);
|
||||
printf("\033[48;2;%d;%d;%dm%c\033[0m", block_start.r, block_start.g, block_start.b, ' ');
|
||||
printf("\033[48;2;%d;%d;%dm%c\033[0m", block_end.r, block_end.g, block_end.b, ' ');
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
BIN
Binary file not shown.
+27
@@ -0,0 +1,27 @@
|
||||
dependencies:
|
||||
espressif/gmf_audio:
|
||||
override_path: ../../gmf_audio
|
||||
espressif/gmf_io:
|
||||
override_path: ../../gmf_io
|
||||
espressif/gmf_misc:
|
||||
override_path: ../../gmf_misc
|
||||
espressif/gmf_ai_audio:
|
||||
override_path: ../../gmf_ai_audio
|
||||
espressif/gmf_core:
|
||||
override_path: ../../../gmf_core
|
||||
gmf_video:
|
||||
override_path: ../../gmf_video
|
||||
espressif/esp-dsp: <=1.6.0
|
||||
espressif/esp_video_codec: "~0.5.2"
|
||||
espressif/esp_h264:
|
||||
version: "1.0.4"
|
||||
rules:
|
||||
- if: "target in [esp32s3, esp32p4]"
|
||||
espressif/esp_wifi_remote:
|
||||
rules:
|
||||
- if: "target in [esp32p4]"
|
||||
espressif/gmf_loader:
|
||||
override_path: ../../../packages/gmf_loader
|
||||
espressif/gmf_app_utils:
|
||||
override_path: ../../../packages/gmf_app_utils
|
||||
|
||||
BIN
Binary file not shown.
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/**
|
||||
* Test API C++ compilation only, not as a example reference
|
||||
*/
|
||||
#include "unity.h"
|
||||
#include "esp_gmf_io_file.h"
|
||||
#include "esp_gmf_io_http.h"
|
||||
#include "esp_gmf_io_embed_flash.h"
|
||||
#include "esp_gmf_io_i2s_pdm.h"
|
||||
|
||||
extern "C" void test_cxx_build(void)
|
||||
{
|
||||
file_io_cfg_t file_config = FILE_IO_CFG_DEFAULT();
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_file_init(&file_config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
|
||||
http_io_cfg_t http_config = HTTP_STREAM_CFG_DEFAULT();
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_http_init(&http_config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
|
||||
embed_flash_io_cfg_t embed_flash_config = EMBED_FLASH_CFG_DEFAULT();
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_embed_flash_init(&embed_flash_config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
|
||||
i2s_pdm_io_cfg_t i2s_pdm_config = ESP_GMF_IO_I2S_PDM_CFG_DEFAULT();
|
||||
TEST_ASSERT_EQUAL(esp_gmf_io_i2s_pdm_init(&i2s_pdm_config, NULL), ESP_GMF_ERR_INVALID_ARG);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "esp_gmf_app_unit_test.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_gmf_app_test_main();
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x6000
|
||||
factory, app, factory, 0x10000, 3M,
|
||||
model, data, spiffs, , 528k,
|
||||
|
+5
@@ -0,0 +1,5 @@
|
||||
# Espressif ESP32 Partition Table
|
||||
# Name, Type, SubType, Offset, Size
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
factory, app, factory, 0x010000, 0x400000
|
||||
model, data, spiffs, , 0x3F0000,
|
||||
|
+21
@@ -0,0 +1,21 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.timeout(8000)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'default',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_gmf_elements(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=2000)
|
||||
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# WiFi Configuration
|
||||
#
|
||||
CONFIG_EXAMPLE_WIFI_SSID="${CI_WIFI_SSID}"
|
||||
CONFIG_EXAMPLE_WIFI_PASSWORD="${CI_WIFI_PASSWORD}"
|
||||
# end of WiFi Configuration
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
# General options for additional checks
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
|
||||
CONFIG_COMPILER_WARN_WRITE_STRINGS=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
|
||||
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
||||
CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
|
||||
CONFIG_COMPILER_STACK_CHECK=y
|
||||
|
||||
# Serial flasher config
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="8MB"
|
||||
|
||||
# disable task watchdog since this app uses an interactive menu
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
|
||||
# some tests verify file name encoding
|
||||
CONFIG_FATFS_LFN_HEAP=y
|
||||
CONFIG_FATFS_API_ENCODING_UTF_8=y
|
||||
CONFIG_FATFS_CODEPAGE_936=y
|
||||
|
||||
# some of the tests verify concurrent operation of FAT partitions in
|
||||
# an SD card and in Flash, so need to use a custom partition table.
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_4m.csv"
|
||||
|
||||
CONFIG_ESP_GDBSTUB_ENABLED=y
|
||||
|
||||
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=20
|
||||
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=128
|
||||
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=128
|
||||
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
||||
CONFIG_ESP_WIFI_TX_BA_WIN=32
|
||||
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
||||
CONFIG_ESP_WIFI_RX_BA_WIN=32
|
||||
|
||||
# CONFIG_ESP_WIFI_IRAM_OPT is not set
|
||||
# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set
|
||||
# CONFIG_ESP_WIFI_RX_IRAM_OPT is not set
|
||||
# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set
|
||||
# CONFIG_LWIP_IRAM_OPTIMIZATION=y
|
||||
|
||||
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=65535
|
||||
CONFIG_LWIP_TCP_WND_DEFAULT=65535
|
||||
CONFIG_LWIP_TCP_RECVMBOX_SIZE=64
|
||||
CONFIG_LWIP_UDP_RECVMBOX_SIZE=64
|
||||
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64
|
||||
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_COMPILER_OPTIMIZATION_PERF=y
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y
|
||||
|
||||
CONFIG_CODEC_I2C_BACKWARD_COMPATIBLE=n
|
||||
|
||||
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL=4
|
||||
CONFIG_UNITY_ENABLE_64BIT=y
|
||||
|
||||
#
|
||||
# GMF Video Configurations
|
||||
#
|
||||
|
||||
#
|
||||
# GMF Video Codec
|
||||
#
|
||||
CONFIG_GMF_VIDEO_CODEC_INIT_DECODER=y
|
||||
CONFIG_GMF_VIDEO_DEC_CODEC_TYPE_AUTO=y
|
||||
CONFIG_GMF_VIDEO_DEC_CODEC_TYPE=0x00000000
|
||||
CONFIG_GMF_VIDEO_CODEC_INIT_ENCODER=y
|
||||
CONFIG_GMF_VIDEO_ENC_CODEC_TYPE_AUTO=y
|
||||
CONFIG_GMF_VIDEO_ENC_CODEC_TYPE=0x00000000
|
||||
# end of GMF Video Codec
|
||||
|
||||
#
|
||||
# GMF Video Effects
|
||||
#
|
||||
CONFIG_GMF_VIDEO_EFFECTS_INIT_FPS_CONVERT=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_INIT_OVERLAY=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_INIT_COLOR_CONVERT=y
|
||||
|
||||
#
|
||||
# Video effects color convert Configuration
|
||||
#
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CC_INPUT_WIDTH=320
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CC_INPUT_HEIGHT=240
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CC_INPUT_FMT_GREY=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CC_INPUT_PIXEL_FORMAT=0x59455247
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CC_OUTPUT_FMT_RGB565_LE=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CC_OUTPUT_PIXEL_FORMAT=0x4C424752
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CC_COLOR_SPACE_BT601=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CC_COLOR_SPACE=0
|
||||
# end of Video effects color convert Configuration
|
||||
|
||||
CONFIG_GMF_VIDEO_EFFECTS_INIT_SCALE=y
|
||||
|
||||
#
|
||||
# Video effects scale Configuration
|
||||
#
|
||||
CONFIG_GMF_VIDEO_EFFECTS_SCALE_INPUT_WIDTH=320
|
||||
CONFIG_GMF_VIDEO_EFFECTS_SCALE_INPUT_HEIGHT=240
|
||||
CONFIG_GMF_VIDEO_EFFECTS_SCALE_INPUT_FMT_RGB565_LE=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_SCALE_INPUT_PIXEL_FORMAT=0x4C424752
|
||||
CONFIG_GMF_VIDEO_EFFECTS_SCALE_OUTPUT_WIDTH=160
|
||||
CONFIG_GMF_VIDEO_EFFECTS_SCALE_OUTPUT_HEIGHT=120
|
||||
CONFIG_GMF_VIDEO_EFFECTS_SCALE_FILTER_DOWN_RESAMPLE=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_SCALE_FILTER_TYPE=0
|
||||
# end of Video effects scale Configuration
|
||||
|
||||
CONFIG_GMF_VIDEO_EFFECTS_INIT_CROP=y
|
||||
|
||||
#
|
||||
# Video effects crop Configuration
|
||||
#
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CROP_INPUT_WIDTH=320
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CROP_INPUT_HEIGHT=240
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CROP_INPUT_FMT_RGB565_LE=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CROP_INPUT_PIXEL_FORMAT=0x4C424752
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CROP_X_POS=0
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CROP_Y_POS=0
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CROP_OUTPUT_WIDTH=160
|
||||
CONFIG_GMF_VIDEO_EFFECTS_CROP_OUTPUT_HEIGHT=120
|
||||
# end of Video effects crop Configuration
|
||||
|
||||
CONFIG_GMF_VIDEO_EFFECTS_INIT_ROTATE=y
|
||||
|
||||
#
|
||||
# Video effects rotate Configuration
|
||||
#
|
||||
CONFIG_GMF_VIDEO_EFFECTS_ROTATE_INPUT_WIDTH=320
|
||||
CONFIG_GMF_VIDEO_EFFECTS_ROTATE_INPUT_HEIGHT=240
|
||||
CONFIG_GMF_VIDEO_EFFECTS_ROTATE_INPUT_FMT_RGB565_LE=y
|
||||
CONFIG_GMF_VIDEO_EFFECTS_ROTATE_INPUT_PIXEL_FORMAT=0x4C424752
|
||||
CONFIG_GMF_VIDEO_EFFECTS_ROTATE_DEGREE=0
|
||||
# end of Video effects rotate Configuration
|
||||
# end of GMF Video Effects
|
||||
# end of GMF Video Configurations
|
||||
# end of ESP GMF Loader
|
||||
# ESP GMF Loader
|
||||
#
|
||||
|
||||
#
|
||||
# GMF IO Reader
|
||||
#
|
||||
CONFIG_GMF_IO_INIT_CODEC_DEV_RX=y
|
||||
CONFIG_GMF_IO_INIT_FILE_READER=y
|
||||
CONFIG_GMF_IO_INIT_HTTP_READER=y
|
||||
|
||||
#
|
||||
# HTTP Reader Configuration
|
||||
#
|
||||
CONFIG_GMF_IO_HTTP_READER_TASK_STACK=3072
|
||||
CONFIG_GMF_IO_HTTP_READER_TASK_CORE=0
|
||||
CONFIG_GMF_IO_HTTP_READER_TASK_PRIORITY=5
|
||||
CONFIG_GMF_IO_HTTP_READER_OUT_BUF_SIZE=8192
|
||||
CONFIG_GMF_IO_HTTP_READER_CERT_PEM=""
|
||||
# end of HTTP Reader Configuration
|
||||
|
||||
CONFIG_GMF_IO_INIT_FLASH_READER=y
|
||||
|
||||
#
|
||||
# GMF IO Writer
|
||||
#
|
||||
CONFIG_GMF_IO_INIT_CODEC_DEV_TX=y
|
||||
CONFIG_GMF_IO_INIT_FILE_WRITER=y
|
||||
CONFIG_GMF_IO_INIT_HTTP_WRITER=y
|
||||
|
||||
#
|
||||
# HTTP Writer Configuration
|
||||
#
|
||||
CONFIG_GMF_IO_HTTP_WRITER_TASK_STACK=3072
|
||||
CONFIG_GMF_IO_HTTP_WRITER_TASK_CORE=0
|
||||
CONFIG_GMF_IO_HTTP_WRITER_TASK_PRIORITY=5
|
||||
CONFIG_GMF_IO_HTTP_WRITER_OUT_BUF_SIZE=8192
|
||||
CONFIG_GMF_IO_HTTP_WRITER_CERT_PEM=""
|
||||
# end of HTTP Writer Configuration
|
||||
# end of GMF IO Writer
|
||||
# end of GMF IO Configurations
|
||||
|
||||
#
|
||||
# GMF Audio Codec
|
||||
#
|
||||
CONFIG_GMF_AUDIO_CODEC_INIT_DECODER=y
|
||||
CONFIG_GMF_AUDIO_CODEC_DECODER_TYPE_PCM=y
|
||||
# end of GMF Audio Codec
|
||||
|
||||
#
|
||||
# PCM Decoder Configuration
|
||||
#
|
||||
CONFIG_GMF_AUDIO_CODEC_DEC_PCM_SAMPLE_RATE=44100
|
||||
CONFIG_GMF_AUDIO_CODEC_DEC_PCM_CHANNEL=2
|
||||
CONFIG_GMF_AUDIO_CODEC_DEC_PCM_BITS_PER_SAMPLE=16
|
||||
# end of PCM Decoder Configuration
|
||||
|
||||
#
|
||||
# AAC Encoder Configuration
|
||||
#
|
||||
CONFIG_GMF_AUDIO_CODEC_INIT_ENCODER=y
|
||||
CONFIG_GMF_AUDIO_CODEC_ENCODER_TYPE_PCM=y
|
||||
# end of AAC Encoder Configuration
|
||||
|
||||
#
|
||||
# GMF Audio Effects
|
||||
#
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_ALC=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_CH_CVT=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_CH_CVT_DEST_CH=2
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_BIT_CVT=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_BIT_CVT_DEST_BITS=16
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_RATE_CVT=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_RATE_CVT_DEST_RATE=48000
|
||||
CONFIG_GMF_AUDIO_EFFECT_RATE_CVT_COMPLEXITY=1
|
||||
CONFIG_GMF_AUDIO_EFFECT_RATE_CVT_PERF_TYPE_MEMORY=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_RATE_CVT_PERF_TYPE=0
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_DEINTERLEAVE=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_INTERLEAVE=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_MIXER=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_EQ=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_SONIC=y
|
||||
CONFIG_GMF_AUDIO_EFFECT_INIT_FADE=y
|
||||
# end of GMF Audio Effects
|
||||
|
||||
#
|
||||
# GMF AI Audio
|
||||
#
|
||||
CONFIG_GMF_AI_AUDIO_INIT_AEC=y
|
||||
CONFIG_GMF_AI_AUDIO_AEC_FILTER_LEN=4
|
||||
CONFIG_GMF_AI_AUDIO_AEC_CH_ALLOCATION="RMNM"
|
||||
# end of GMF AI Audio
|
||||
|
||||
#
|
||||
# GMF Miscellaneous
|
||||
#
|
||||
CONFIG_GMF_MISC_INIT_COPIER=y
|
||||
# end of GMF Miscellaneous
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
|
||||
CONFIG_SR_WN_WN9_HILEXIN=y
|
||||
CONFIG_AUDIO_BOARD="LYRAT_MINI_V1"
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="8MB"
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHMODE="dio"
|
||||
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
|
||||
#
|
||||
# ESP Speech Recognition
|
||||
#
|
||||
CONFIG_AFE_INTERFACE_V1=y
|
||||
CONFIG_SR_NSN_WEBRTC=y
|
||||
CONFIG_SR_VADN_WEBRTC=y
|
||||
|
||||
#
|
||||
# Load Multiple Wake Words
|
||||
#
|
||||
CONFIG_SR_WN_WN9S_HILEXIN=y
|
||||
# CONFIG_SR_WN_WN9S_HIESP is not set
|
||||
# CONFIG_SR_WN_WN9S_NIHAOXIAOZHI is not set
|
||||
# CONFIG_SR_WN_WN9S_HIJASON is not set
|
||||
# end of Load Multiple Wake Words
|
||||
|
||||
CONFIG_SR_MN_CN_NONE=y
|
||||
CONFIG_SR_MN_EN_NONE=y
|
||||
# end of ESP Speech Recognition
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="8MB"
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHMODE="dio"
|
||||
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
|
||||
#
|
||||
# ESP Speech Recognition
|
||||
#
|
||||
CONFIG_AFE_INTERFACE_V1=y
|
||||
CONFIG_SR_NSN_WEBRTC=y
|
||||
CONFIG_SR_VADN_WEBRTC=y
|
||||
|
||||
#
|
||||
# Load Multiple Wake Words
|
||||
#
|
||||
CONFIG_SR_WN_WN9S_HILEXIN=y
|
||||
# CONFIG_SR_WN_WN9S_HIESP is not set
|
||||
# CONFIG_SR_WN_WN9S_NIHAOXIAOZHI is not set
|
||||
# CONFIG_SR_WN_WN9S_HIJASON is not set
|
||||
# end of Load Multiple Wake Words
|
||||
|
||||
CONFIG_SR_MN_CN_NONE=y
|
||||
CONFIG_SR_MN_EN_NONE=y
|
||||
# end of ESP Speech Recognition
|
||||
|
||||
CONFIG_GMF_AI_AUDIO_INIT_WN=y
|
||||
|
||||
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
# Flash setting
|
||||
CONFIG_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
|
||||
CONFIG_SPIRAM_SPEED_200M=y
|
||||
|
||||
# If you use serial JTAG turn on this option
|
||||
#CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
|
||||
|
||||
# Use camera SC2336
|
||||
CONFIG_CAMERA_SC2336=y
|
||||
CONFIG_CAMERA_SC2336_MIPI_RAW8_1024x600_30FPS=y
|
||||
|
||||
# Enable ISP pipelines
|
||||
CONFIG_ESP_VIDEO_ENABLE_ISP_PIPELINE_CONTROLLER=y
|
||||
|
||||
# Set Slave target type
|
||||
CONFIG_IDF_SLAVE_TARGET="esp32c6"
|
||||
CONFIG_SLAVE_IDF_TARGET_ESP32C6=y
|
||||
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=n
|
||||
CONFIG_HEAP_POISONING_LIGHT=y
|
||||
|
||||
CONFIG_GMF_VIDEO_EFFECTS_INIT_PPA=y
|
||||
#
|
||||
# ESP Speech Recognition
|
||||
#
|
||||
CONFIG_MODEL_IN_FLASH=y
|
||||
CONFIG_AFE_INTERFACE_V1=y
|
||||
CONFIG_SR_NSN_WEBRTC=y
|
||||
CONFIG_SR_VADN_WEBRTC=y
|
||||
CONFIG_SR_WN_WN9_HILEXIN=y
|
||||
CONFIG_SR_MN_CN_MULTINET7_QUANT=y
|
||||
CONFIG_SR_MN_EN_NONE=y
|
||||
|
||||
CONFIG_AUDIO_BOARD="ESP32_P4_DEV_V14"
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
CONFIG_IDF_CMAKE=y
|
||||
CONFIG_IDF_TARGET_ARCH_XTENSA=y
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_IDF_TARGET_ESP32S3=y
|
||||
CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="8MB"
|
||||
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_8m.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
|
||||
#
|
||||
# ESP Speech Recognition
|
||||
#
|
||||
CONFIG_MODEL_IN_FLASH=y
|
||||
CONFIG_AFE_INTERFACE_V1=y
|
||||
CONFIG_SR_WN_WN9_HILEXIN=y
|
||||
CONFIG_SR_MN_CN_MULTINET6_QUANT=y
|
||||
CONFIG_SR_MN_EN_NONE=y
|
||||
|
||||
CONFIG_SPIRAM_SPEED_80M=y
|
||||
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
|
||||
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=1024
|
||||
CONFIG_SPIRAM_MODE_OCT=y
|
||||
CONFIG_SPIRAM_TYPE_AUTO=y
|
||||
|
||||
CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
||||
CONFIG_ESP_TLS_INSECURE=y
|
||||
CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y
|
||||
|
||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
|
||||
CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
|
||||
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
|
||||
|
||||
CONFIG_AUDIO_BOARD="S3_Korvo_V2"
|
||||
Reference in New Issue
Block a user