修改上传所有文件
This commit is contained in:
218
e3_176_ref/middleware/mjpeg/mjpeg.c
Normal file
218
e3_176_ref/middleware/mjpeg/mjpeg.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user