Files
player/Project/Src/MJPEG/mjpeg.c

224 lines
5.8 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#include "mjpeg.h"
#include "mymem.h"
#include "ff.h"
#include "lcd_rgb.h"
//////////////////////////////////////////////////////////////////////////////////
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>ѧϰʹ<CFB0>ã<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD>;
//ALIENTEK STM32F407<30><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//MJPEG<45><47>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>@ALIENTEK
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳:www.openedv.com
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:2014/7/20
//<2F><EFBFBD><E6B1BE>V1.0
//<2F><>Ȩ<EFBFBD><C8A8><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD><D8BE><EFBFBD>
//Copyright(C) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿƼ<D3BF><C6BC><EFBFBD><EFBFBD>޹<EFBFBD>˾ 2009-2019
2025-06-27 00:32:57 +08:00
//All rights reserved
//*******************************************************************************
2025-07-05 19:47:28 +08:00
//<2F>޸<EFBFBD><DEB8><EFBFBD>Ϣ
//<2F><>
2025-06-27 00:32:57 +08:00
//////////////////////////////////////////////////////////////////////////////////
struct jpeg_decompress_struct *cinfo;
struct my_error_mgr *jerr;
2025-07-05 19:47:28 +08:00
u8 *jpegbuf; //jpeg<65><67><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>ָ<EFBFBD><D6B8>
u32 jbufsize; //jpeg buf<75><66>С
u16 imgoffx,imgoffy; //ͼ<><CDBC><EFBFBD><EFBFBD>x,y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
////////////////////////////////////////////////////////////////////////////////
2025-07-05 19:47:28 +08:00
//<2F>򵥿<EFBFBD><F2B5A5BF>ٵ<EFBFBD><D9B5>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>
#define MJPEG_MAX_MALLOC_SIZE 38*1024 //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD>38K<38>ֽ<EFBFBD>
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
u8 *jmembuf; //mjpeg<65><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڴ<EFBFBD><DAB4><EFBFBD>
u32 jmempos; //<2F>ڴ<EFBFBD><DAB4><EFBFBD>ָ<EFBFBD><D6B8>
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
//mjpeg<65><67><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
void* mjpeg_malloc(u32 num)
{
2025-07-05 19:47:28 +08:00
u32 curpos=jmempos; //<2F>˴η<CBB4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ
jmempos+=num; //<2F><>һ<EFBFBD>η<EFBFBD><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ
2025-06-27 00:32:57 +08:00
if(jmempos>MJPEG_MAX_MALLOC_SIZE)
{
printf("mem error:%d,%d",curpos,num);
}
2025-07-05 19:47:28 +08:00
return (void *)&jmembuf[curpos]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBB5BD><EFBFBD>ڴ<EFBFBD><DAB4>׵<EFBFBD>ַ
2025-06-27 00:32:57 +08:00
}
////////////////////////////////////////////////////////////////////////////////
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>
2025-06-27 00:32:57 +08:00
static void my_error_exit(j_common_ptr cinfo)
{
my_error_ptr myerr=(my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->setjmp_buffer, 1);
}
METHODDEF(void) my_emit_message(j_common_ptr cinfo, int msg_level)
{
my_error_ptr myerr=(my_error_ptr) cinfo->err;
if(msg_level<0)
{
printf("emit msg:%d\r\n",msg_level);
longjmp(myerr->setjmp_buffer, 1);
}
}
2025-07-05 19:47:28 +08:00
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Դ,<2C><>ִ<EFBFBD><D6B4><EFBFBD>κβ<CEBA><CEB2><EFBFBD>
2025-06-27 00:32:57 +08:00
static void init_source(j_decompress_ptr cinfo)
{
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD>.
2025-06-27 00:32:57 +08:00
return;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBBBBA><EFBFBD><EFBFBD>,һ<><D2BB><EFBFBD>Զ<EFBFBD>ȡ<EFBFBD><C8A1>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
static boolean fill_input_buffer(j_decompress_ptr cinfo)
{
2025-07-05 19:47:28 +08:00
if(jbufsize==0)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
//printf("jd read off\r\n");
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
jpegbuf[0] = (u8) 0xFF;
jpegbuf[1] = (u8) JPEG_EOI;
cinfo->src->next_input_byte =jpegbuf;
cinfo->src->bytes_in_buffer = 2;
}else
{
cinfo->src->next_input_byte =jpegbuf;
cinfo->src->bytes_in_buffer = jbufsize;
jbufsize-=jbufsize;
}
return TRUE;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>num_bytes<65><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
/* Just a dumb implementation for now. Could use fseek() except
* it doesn't work on pipes. Not clear that being smart is worth
* any trouble anyway --- large skips are infrequent.
*/
if (num_bytes > 0)
{
while(num_bytes>(long) cinfo->src->bytes_in_buffer)
{
num_bytes-=(long)cinfo->src->bytes_in_buffer;
(void)cinfo->src->fill_input_buffer(cinfo);
/* note we assume that fill_input_buffer will never
* return FALSE, so suspension need not be handled.
*/
}
cinfo->src->next_input_byte += (size_t) num_bytes;
cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
}
}
2025-07-05 19:47:28 +08:00
//<2F>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>jpeg_finish_decompress<73><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
static void term_source(j_decompress_ptr cinfo)
{
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD>κδ<CEBA><CEB4><EFBFBD>
2025-06-27 00:32:57 +08:00
return;
}
2025-07-05 19:47:28 +08:00
//<2F><>ʼ<EFBFBD><CABC>jpeg<65><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
2025-06-27 00:32:57 +08:00
static void jpeg_filerw_src_init(j_decompress_ptr cinfo)
{
if (cinfo->src == NULL) /* first time for this JPEG object? */
{
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT,
sizeof(struct jpeg_source_mgr));
}
cinfo->src->init_source = init_source;
cinfo->src->fill_input_buffer = fill_input_buffer;
cinfo->src->skip_input_data = skip_input_data;
cinfo->src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
cinfo->src->term_source = term_source;
cinfo->src->bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
cinfo->src->next_input_byte = NULL; /* until buffer loaded */
}
2025-07-05 19:47:28 +08:00
//mjpeg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
//offx,offy:x,y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C>ɹ<EFBFBD>;
// 1,ʧ<><CAA7>
2025-06-27 00:32:57 +08:00
u8 mjpegdec_init(u16 offx,u16 offy)
{
cinfo=mymalloc(sizeof(struct jpeg_decompress_struct));
jerr=mymalloc(sizeof(struct my_error_mgr));
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>sram<61><6D><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>--2020.6.2
jmembuf=mymalloc_fast(MJPEG_MAX_MALLOC_SIZE);//MJPEG<45><47><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
if(cinfo==0||jerr==0||jmembuf==0)
{
mjpegdec_free();
return 1;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>x,y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
imgoffx=offx;
imgoffy=offy;
return 0;
}
2025-07-05 19:47:28 +08:00
//mjpeg<65><67><EFBFBD><EFBFBD>,<2C>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
void mjpegdec_free(void)
{
myfree(cinfo);
myfree(jerr);
myfree(jmembuf);
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>JPEGͼƬ
//buf:jpeg<65><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//bsize:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C>ɹ<EFBFBD>
// <20><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
u8 mjpegdec_decode(u8* buf,u32 bsize)
{
JSAMPARRAY buffer;
if(bsize==0)return 1;
jpegbuf=buf;
jbufsize=bsize;
2025-07-05 19:47:28 +08:00
jmempos=0;//MJEPG<50><47><EFBFBD><EFBFBD>,<2C><><EFBFBD>´<EFBFBD>0<EFBFBD><30>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
cinfo->err=jpeg_std_error(&jerr->pub);
jerr->pub.error_exit = my_error_exit;
jerr->pub.emit_message = my_emit_message;
//if(bsize>20*1024)printf("s:%d\r\n",bsize);
2025-07-05 19:47:28 +08:00
if (setjmp(jerr->setjmp_buffer)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
jpeg_abort_decompress(cinfo);
jpeg_destroy_decompress(cinfo);
return 2;
}
jpeg_create_decompress(cinfo);
jpeg_filerw_src_init(cinfo);
jpeg_read_header(cinfo, TRUE);
cinfo->dct_method = JDCT_IFAST;
cinfo->do_fancy_upsampling = 0;
jpeg_start_decompress(cinfo);
extern void jdmerge_setlcdaddr (unsigned short *addr);
unsigned short *lcd_addr=(unsigned short *)LCD_GetDrawAddr();
// lcd_addr+=LCD_GetLcdSizeX()*LCD_GetLcdSizeY()-1-(imgoffx+imgoffy*LCD_GetLcdSizeX());
2025-07-05 19:47:28 +08:00
jdmerge_setlcdaddr(lcd_addr);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾλ<CABE><CEBB>
2025-06-27 00:32:57 +08:00
while (cinfo->output_scanline < cinfo->output_height)
{
jpeg_read_scanlines(cinfo, buffer, 1);
}
jpeg_finish_decompress(cinfo);
jpeg_destroy_decompress(cinfo);
return 0;
}