新增所有文件

This commit is contained in:
2025-10-25 21:11:06 +08:00
parent 8cc4755d15
commit 3134504178
8414 changed files with 2995287 additions and 5 deletions

218
middleware/mjpeg/mjpeg.c Normal file
View File

@@ -0,0 +1,218 @@
/**
* @file mjpeg.c
*
* Copyright (c) 2020 Semidrive Semiconductor.
* All rights reserved.
*
* Description:
*
* Revision History:
* -----------------
*/
#include <stdio.h>
#include <string.h>
#include <debug.h>
#include "mjpeg.h"
#include "projdefs.h"
#include "portable.h"
#ifdef __FATFS_SUPPORTED__
#include "ff.h"
#endif
static const uint8_t jpg_signature[] = {0xFF, 0xD8};
static inline size_t mjpeg_in_func(JDEC *jd, uint8_t *buff, size_t nbyte)
{
jpg_session *dev = (jpg_session *)jd->device;
if (buff) {
if (dev->bits_offset + nbyte > dev->bit_size) {
nbyte = dev->bit_size - dev->bits_offset;
}
memcpy(buff, dev->bit_stream + dev->bits_offset, nbyte);
dev->bits_offset += nbyte;
return nbyte;
} else { /* skip data from input stream */
if (dev->bits_offset + nbyte > dev->bit_size) {
nbyte = dev->bit_size - dev->bits_offset;
}
dev->bits_offset += nbyte;
return nbyte;
}
}
static inline jformat mjpeg_get_subsample_format(JDEC *jdec)
{
uint8_t sample = 0;
sample = (jdec->msx << 4) | jdec->msy;
if (sample == 0x11)
return JDF_444;
else if (sample == 0x21)
return JDF_422;
else if (sample == 0x22)
return JDF_420;
return JDF_420; /* default to yuv420 now */
}
/* if the input is from the file, load the file into ram,
otherwise use the input data directly
*/
jpg_session *mjpeg_dec_init(io_source_type type, const void *data,
uint32_t size)
{
jpg_session *dec_session = NULL;
if (data == NULL)
return NULL;
dec_session = (jpg_session *)pvPortMalloc(sizeof(jpg_session));
if (dec_session == NULL)
return NULL;
memset(dec_session, 0x00, sizeof(jpg_session));
dec_session->src_type = type;
dec_session->bits_offset = 0;
dec_session->work_buf = pvPortMalloc(MJPEG_WORKBUFF_SIZE);
if (dec_session->work_buf == NULL) {
vPortFree(dec_session);
return NULL;
}
if (dec_session->src_type == JPEG_IO_SOURCE_C_ARRAY) {
// input data is stored in the ram already
dec_session->bit_stream = (uint8_t *)data;
dec_session->bit_size = size;
}
#ifdef __FATFS_SUPPORTED__
else if (dec_session->src_type == JPEG_IO_SOURCE_DISK) {
FIL fp;
FRESULT rc;
UINT count = 0;
char file_name[128] = {0};
strcpy(file_name, (char *)data);
rc = f_open(&fp, file_name, FA_READ);
if (rc) {
vPortFree(dec_session->work_buf);
vPortFree(dec_session);
ssdk_printf(0, "file open failed (rc=%d)\n", rc);
return NULL;
}
dec_session->bit_size = f_size(&fp);
dec_session->bit_stream =
(uint8_t *)pvPortMallocAligned(dec_session->bit_size, 32);
f_read(&fp, dec_session->bit_stream, dec_session->bit_size, &count);
f_close(&fp); /* close the MJPEG file */
}
#endif
return dec_session;
}
JRESULT mjpeg_dec_get_header_info(jpg_session *dec_session,
jpg_out_info *out_info)
{
JRESULT res;
/* prepare to decompress header info*/
res = jd_prepare(&dec_session->jdec, mjpeg_in_func, dec_session->work_buf,
MJPEG_WORKBUFF_SIZE, dec_session);
if (res == JDR_OK) {
/* it is ready to dcompress and image info is available here */
out_info->width = dec_session->jdec.aligned_width;
out_info->height = dec_session->jdec.aligned_height;
out_info->crop.x = 0;
out_info->crop.y = 0;
out_info->crop.w = dec_session->jdec.width;
out_info->crop.h = dec_session->jdec.height;
out_info->format = mjpeg_get_subsample_format(&dec_session->jdec);
dec_session->first_parse = 1;
} else {
ssdk_printf(0, "jd_prepare() failed (rc=%d)\n", res);
}
return res;
}
JRESULT mjpeg_dec_parser_next_frame(jpg_session *dec_session)
{
JRESULT res;
uint32_t search_range = dec_session->bit_size;
uint8_t *bits = NULL;
if (dec_session->first_parse) {
/* prepare return with ok, so we do not need to parser the first frame*/
dec_session->first_parse = 0;
return JDR_OK;
}
/* the previous decoding might have read more data than it needed, rewind */
dec_session->bits_offset -= CONFIG_JD_SZBUF;
if (dec_session->bits_offset + sizeof(jpg_signature) <
dec_session->bit_size) {
search_range -= sizeof(jpg_signature);
} else {
return JDR_INP;
}
for (bits = dec_session->bit_stream + dec_session->bits_offset;
dec_session->bits_offset < search_range;
dec_session->bits_offset++, bits++) {
if (bits[0] == 0xFF && bits[1] == 0xD8) {
/* find the start of next jpeg */
res = jd_prepare(&dec_session->jdec, mjpeg_in_func,
dec_session->work_buf, MJPEG_WORKBUFF_SIZE,
dec_session);
if (res == JDR_OK) {
return JDR_OK;
} else {
return JDR_INP;
}
}
}
return JDR_INP;
}
JRESULT mjpeg_dec_process_frame(jpg_session *dec_session, uint8_t *buf,
uint32_t y_size, uint32_t u_size)
{
JRESULT res;
res = jd_decomp_opt(&dec_session->jdec, buf, buf + y_size,
buf + y_size + u_size);
if (res == JDR_OK) {
/* the decompressed image in the frame buffer here. */
//ssdk_printf(0, "\rDecompression succeeded.\n");
} else {
ssdk_printf(0, "\rjd_decomp() failed (rc=%d)\n", res);
}
return res;
}
void mjpeg_dec_deinit(jpg_session *dec_session)
{
if (dec_session && dec_session->work_buf)
vPortFree(dec_session->work_buf);
#ifdef __FATFS_SUPPORTED__
if (dec_session && dec_session->src_type == JPEG_IO_SOURCE_DISK &&
dec_session->bit_stream)
vPortFree(dec_session->bit_stream);
#endif
vPortFree(dec_session);
}

75
middleware/mjpeg/mjpeg.h Normal file
View File

@@ -0,0 +1,75 @@
/**
* @file mjpeg.h
*
* Copyright (c) 2020 Semidrive Semiconductor.
* All rights reserved.
*
* Description:
*
* Revision History:
* -----------------
*/
#ifndef MJPEG_H
#define MJPEG_H
#include "tjpgd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MJPEG_WORKBUFF_SIZE (4096 * 4) // Recommended by TJPGD libray
typedef enum {
JPEG_IO_SOURCE_C_ARRAY = 0,
JPEG_IO_SOURCE_DISK,
} io_source_type;
typedef enum {
JDF_444 = 0,
JDF_422,
JDF_420,
} jformat;
/* session identifier for input/output functions (name, members and usage are as
* user defined) */
typedef struct {
io_source_type src_type;
uint8_t *bit_stream; /* input bs buffer*/
uint32_t bit_size;
uint32_t bits_offset;
uint8_t first_parse;
void *work_buf;
JDEC jdec;
} jpg_session;
typedef struct {
int x;
int y;
int w;
int h;
} mjpeg_rect;
typedef struct {
uint32_t width;
uint32_t height;
jformat format;
mjpeg_rect crop;
} jpg_out_info;
jpg_session *mjpeg_dec_init(io_source_type type, const void *data,
uint32_t size);
JRESULT mjpeg_dec_get_header_info(jpg_session *dec_session,
jpg_out_info *out_info);
JRESULT mjpeg_dec_start_decompress(jpg_session *dec_session);
JRESULT mjpeg_dec_parser_next_frame(jpg_session *dec_session);
JRESULT mjpeg_dec_process_frame(jpg_session *dec_session, uint8_t *buf,
uint32_t y_size, uint32_t u_size);
void mjpeg_dec_deinit(jpg_session *dec_session);
#ifdef __cplusplus
}
#endif
#endif /*MJPEG_H*/