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

360 lines
12 KiB
C
Raw Permalink Normal View History

2025-06-27 00:32:57 +08:00
#include "avi.h"
2025-07-06 17:11:38 +08:00
#include "dac.h"
#include "ff.h"
2025-06-27 00:32:57 +08:00
#include "lcd_rgb.h"
2025-07-06 17:11:38 +08:00
#include "mjpeg.h"
2025-06-27 00:32:57 +08:00
#include "mymem.h"
2025-07-06 17:11:38 +08:00
#include "timer.h"
#include "touch_043.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////
// <20><><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>
// AVI<56><49>Ƶ<EFBFBD><C6B5>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>@ALIENTEK
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳:www.openedv.com
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:2014/7/20
// <20><EFBFBD><E6B1BE>V1.0
// <20><>Ȩ<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
// All rights reserved
2025-06-27 00:32:57 +08:00
//*******************************************************************************
2025-07-06 17:11:38 +08:00
// <20>޸<EFBFBD><DEB8><EFBFBD>Ϣ
// <20><>
//////////////////////////////////////////////////////////////////////////////////
AVI_INFO avix; // avi<76>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
u8 *const AVI_VIDS_FLAG_TBL[2] = {"00dc",
"01dc"}; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>,00dc/01dc
u8 *const AVI_AUDS_FLAG_TBL[2] = {"00wb",
"01wb"}; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>,00wb/01wb
static vu8 g_i2splaybuf; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><C5B5><EFBFBD>Ƶ֡<C6B5><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static u8 *g_i2sbuf[4]; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>֡,<2C><>4֡,4*5K=20K
// <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>I2S DMA<4D><41><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
void audio_i2s_dma_callback(DAC_UserStruct *dac) {
g_i2splaybuf++;
if (g_i2splaybuf > 3)
g_i2splaybuf = 0;
if (dac->buff_useing == 1) {
DMA_MemoryTargetConfig(DMA1_Stream5, (u32)g_i2sbuf[g_i2splaybuf],
DMA_Memory_0);
} else {
DMA_MemoryTargetConfig(DMA1_Stream5, (u32)g_i2sbuf[g_i2splaybuf],
DMA_Memory_1);
}
2025-06-27 00:32:57 +08:00
}
2025-07-06 17:11:38 +08:00
// avi<76><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
// buf:<3A><><EFBFBD><EFBFBD><EBBBBA><EFBFBD><EFBFBD>
// size:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
// <20><><EFBFBD><EFBFBD>ֵ:AVI_OK,avi<76>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
// <20><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
AVISTATUS avi_init(u8 *buf, int size) {
u16 offset;
u8 *tbuf;
AVISTATUS res = AVI_OK;
AVI_HEADER *aviheader;
LIST_HEADER *listheader;
AVIH_HEADER *avihheader;
STRH_HEADER *strhheader;
STRF_BMPHEADER *bmpheader;
STRF_WAVHEADER *wavheader;
tbuf = buf;
aviheader = (AVI_HEADER *)buf;
if (aviheader->RiffID != AVI_RIFF_ID)
return AVI_RIFF_ERR; // RIFF ID<49><44><EFBFBD><EFBFBD>
if (aviheader->AviID != AVI_AVI_ID)
return AVI_AVI_ERR; // AVI ID<49><44><EFBFBD><EFBFBD>
buf += sizeof(AVI_HEADER); // ƫ<><C6AB>
listheader = (LIST_HEADER *)(buf);
if (listheader->ListID != AVI_LIST_ID)
return AVI_LIST_ERR; // LIST ID<49><44><EFBFBD><EFBFBD>
if (listheader->ListType != AVI_HDRL_ID)
return AVI_HDRL_ERR; // HDRL ID<49><44><EFBFBD><EFBFBD>
buf += sizeof(LIST_HEADER); // ƫ<><C6AB>
avihheader = (AVIH_HEADER *)(buf);
if (avihheader->BlockID != AVI_AVIH_ID)
return AVI_AVIH_ERR; // AVIH ID<49><44><EFBFBD><EFBFBD>
avix.SecPerFrame = avihheader->SecPerFrame; // <20>õ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
avix.TotalFrame = avihheader->TotalFrame; // <20>õ<EFBFBD><C3B5><EFBFBD>֡<EFBFBD><D6A1>
buf += avihheader->BlockSize + 8; // ƫ<><C6AB>
listheader = (LIST_HEADER *)(buf);
if (listheader->ListID != AVI_LIST_ID)
return AVI_LIST_ERR; // LIST ID<49><44><EFBFBD><EFBFBD>
if (listheader->ListType != AVI_STRL_ID)
return AVI_STRL_ERR; // STRL ID<49><44><EFBFBD><EFBFBD>
strhheader = (STRH_HEADER *)(buf + 12);
if (strhheader->BlockID != AVI_STRH_ID)
return AVI_STRH_ERR; // STRH ID<49><44><EFBFBD><EFBFBD>
if (strhheader->StreamType == AVI_VIDS_STREAM) // <20><>Ƶ֡<C6B5><D6A1>ǰ
{
if (strhheader->Handler != AVI_FORMAT_MJPG)
return AVI_FORMAT_ERR; // <20><>MJPG<50><47>Ƶ<EFBFBD><C6B5>,<2C><>֧<EFBFBD><D6A7>
avix.VideoFLAG = (u8 *)AVI_VIDS_FLAG_TBL[0]; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "00dc"
avix.AudioFLAG = (u8 *)AVI_AUDS_FLAG_TBL[1]; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "01wb"
bmpheader =
(STRF_BMPHEADER *)(buf + 12 + strhheader->BlockSize + 8); // strf
if (bmpheader->BlockID != AVI_STRF_ID)
return AVI_STRF_ERR; // STRF ID<49><44><EFBFBD><EFBFBD>
avix.Width = bmpheader->bmiHeader.Width;
avix.Height = bmpheader->bmiHeader.Height;
buf += listheader->BlockSize + 8; // ƫ<><C6AB>
listheader = (LIST_HEADER *)(buf);
if (listheader->ListID != AVI_LIST_ID) // <20>Dz<EFBFBD><C7B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ֡<C6B5><D6A1><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD>
{
avix.SampleRate = 0; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
avix.Channels = 0; // <20><>Ƶͨ<C6B5><CDA8><EFBFBD><EFBFBD>
avix.AudioType = 0; // <20><>Ƶ<EFBFBD><C6B5>ʽ
} else {
if (listheader->ListType != AVI_STRL_ID)
return AVI_STRL_ERR; // STRL ID<49><44><EFBFBD><EFBFBD>
strhheader = (STRH_HEADER *)(buf + 12);
if (strhheader->BlockID != AVI_STRH_ID)
return AVI_STRH_ERR; // STRH ID<49><44><EFBFBD><EFBFBD>
if (strhheader->StreamType != AVI_AUDS_STREAM)
return AVI_FORMAT_ERR; // <20><>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
wavheader =
(STRF_WAVHEADER *)(buf + 12 + strhheader->BlockSize + 8); // strf
if (wavheader->BlockID != AVI_STRF_ID)
return AVI_STRF_ERR; // STRF ID<49><44><EFBFBD><EFBFBD>
avix.SampleRate = wavheader->SampleRate; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
avix.Channels = wavheader->Channels; // <20><>Ƶͨ<C6B5><CDA8><EFBFBD><EFBFBD>
avix.AudioType = wavheader->FormatTag; // <20><>Ƶ<EFBFBD><C6B5>ʽ
}
} else if (strhheader->StreamType == AVI_AUDS_STREAM) // <20><>Ƶ֡<C6B5><D6A1>ǰ
{
avix.VideoFLAG = (u8 *)AVI_VIDS_FLAG_TBL[1]; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "01dc"
avix.AudioFLAG = (u8 *)AVI_AUDS_FLAG_TBL[0]; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "00wb"
wavheader =
(STRF_WAVHEADER *)(buf + 12 + strhheader->BlockSize + 8); // strf
if (wavheader->BlockID != AVI_STRF_ID)
return AVI_STRF_ERR; // STRF ID<49><44><EFBFBD><EFBFBD>
avix.SampleRate = wavheader->SampleRate; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
avix.Channels = wavheader->Channels; // <20><>Ƶͨ<C6B5><CDA8><EFBFBD><EFBFBD>
avix.AudioType = wavheader->FormatTag; // <20><>Ƶ<EFBFBD><C6B5>ʽ
buf += listheader->BlockSize + 8; // ƫ<><C6AB>
listheader = (LIST_HEADER *)(buf);
if (listheader->ListID != AVI_LIST_ID)
return AVI_LIST_ERR; // LIST ID<49><44><EFBFBD><EFBFBD>
if (listheader->ListType != AVI_STRL_ID)
return AVI_STRL_ERR; // STRL ID<49><44><EFBFBD><EFBFBD>
strhheader = (STRH_HEADER *)(buf + 12);
if (strhheader->BlockID != AVI_STRH_ID)
return AVI_STRH_ERR; // STRH ID<49><44><EFBFBD><EFBFBD>
if (strhheader->StreamType != AVI_VIDS_STREAM)
return AVI_FORMAT_ERR; // <20><>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
bmpheader =
(STRF_BMPHEADER *)(buf + 12 + strhheader->BlockSize + 8); // strf
if (bmpheader->BlockID != AVI_STRF_ID)
return AVI_STRF_ERR; // STRF ID<49><44><EFBFBD><EFBFBD>
if (bmpheader->bmiHeader.Compression != AVI_FORMAT_MJPG)
return AVI_FORMAT_ERR; // <20><>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
avix.Width = bmpheader->bmiHeader.Width;
avix.Height = bmpheader->bmiHeader.Height;
}
offset = avi_srarch_id(tbuf, size, "movi"); // <20><><EFBFBD><EFBFBD>movi ID
if (offset == 0)
return AVI_MOVI_ERR; // MOVI ID<49><44><EFBFBD><EFBFBD>
if (avix.SampleRate) // <20><><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>,<2C>Ų<EFBFBD><C5B2><EFBFBD>
{
tbuf += offset;
offset = avi_srarch_id(tbuf, size, avix.AudioFLAG); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (offset == 0)
return AVI_STREAM_ERR; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tbuf += offset + 4;
avix.AudioBufSize = *((u16 *)tbuf); // <20>õ<EFBFBD><C3B5><EFBFBD>Ƶ<EFBFBD><C6B5>buf<75><66>С.
}
// printf("avi init ok\r\n");
// printf("avix.SecPerFrame:%d\r\n",avix.SecPerFrame);
// printf("avix.TotalFrame:%d\r\n",avix.TotalFrame);
// printf("avix.Width:%d\r\n",avix.Width);
// printf("avix.Height:%d\r\n",avix.Height);
// printf("avix.AudioType:%d\r\n",avix.AudioType);
// printf("avix.SampleRate:%d\r\n",avix.SampleRate);
// printf("avix.Channels:%d\r\n",avix.Channels);
// printf("avix.AudioBufSize:%d\r\n",avix.AudioBufSize);
// printf("avix.VideoFLAG:%s\r\n",avix.VideoFLAG);
// printf("avix.AudioFLAG:%s\r\n",avix.AudioFLAG);
return res;
2025-06-27 00:32:57 +08:00
}
2025-07-06 17:11:38 +08:00
// <20><><EFBFBD><EFBFBD> ID
// buf:<3A><><EFBFBD><EFBFBD><E9BBBA><EFBFBD><EFBFBD>
// size:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
// id:Ҫ<><D2AA><EFBFBD>ҵ<EFBFBD>id,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD>ֽڳ<D6BD><DAB3><EFBFBD>
// <20><><EFBFBD><EFBFBD>ֵ:0,<2C><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>,<2C><><EFBFBD><EFBFBD>:movi IDƫ<44><C6AB><EFBFBD><EFBFBD>
u16 avi_srarch_id(u8 *buf, int size, u8 *id) {
u16 i;
size -= 4;
for (i = 0; i < size; i++) {
if (buf[i] == id[0])
if (buf[i + 1] == id[1])
if (buf[i + 2] == id[2])
if (buf[i + 3] == id[3])
return i; // <20>ҵ<EFBFBD>"id"<22><><EFBFBD>ڵ<EFBFBD>λ<EFBFBD><CEBB>
}
return 0;
2025-06-27 00:32:57 +08:00
}
2025-07-06 17:11:38 +08:00
// <20>õ<EFBFBD>stream<61><6D><EFBFBD><EFBFBD>Ϣ
// buf:<3A><><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>01wb/00wb/01dc/00dc<64><63>ͷ)
AVISTATUS avi_get_streaminfo(u8 *buf) {
int offset = 0;
avix.StreamID = MAKEWORD(buf + 2); // <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
avix.StreamSize = MAKEDWORD(buf + 4); // <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>С
if (avix.StreamSize % 2)
avix.StreamSize++; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1(avix.StreamSize,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ż<EFBFBD><C5BC>)
if (avix.StreamID == AVI_VIDS_FLAG || avix.StreamID == AVI_AUDS_FLAG)
return AVI_OK;
return AVI_STREAM_ERR;
2025-06-27 00:32:57 +08:00
}
2025-07-06 17:11:38 +08:00
static vu8 g_frame_en = 0;
2025-06-27 00:32:57 +08:00
2025-07-06 17:11:38 +08:00
void avi_timer_irq(void) { g_frame_en = 1; }
2025-06-27 00:32:57 +08:00
2025-07-06 17:11:38 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>avix.SecPerFrame
void avi_timer_init(u32 t) {
TIMER_InitStruct timer_init = {0};
timer_init.Cycle = t / 1;
timer_init.Tim = TIM3;
timer_init.UpdataCall = avi_timer_irq;
TIMER_InitNormal(&timer_init);
2025-06-27 00:32:57 +08:00
}
2025-07-06 17:11:38 +08:00
void avi_tiemr_delete(void) { TIMER_DeInit(TIM3); }
#define AVI_AUDIO_BUF_SIZE 1024 * 5 // <20><><EFBFBD><EFBFBD>avi<76><69><EFBFBD><EFBFBD>ʱ,<2C><>Ƶbuf<75><66>С.
#define AVI_VIDEO_BUF_SIZE 1024 * 200 // <20><><EFBFBD><EFBFBD>avi<76><69><EFBFBD><EFBFBD>ʱ,<2C><>Ƶbuf<75><66>С.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ
int video_play(char *pname, int loop) {
u8 listhead[8] = {0}; // <20><><EFBFBD><EFBFBD>ͷ
u32 fresh = 0;
u8 *framebuf; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>buf
u8 *pbuf; // bufָ<66><D6B8>
FIL *favi;
u8 res = 0;
u16 offset = 0;
UINT nr;
u8 key;
u8 i2ssavebuf;
DAC_UserStruct dac = {0};
u8 *audio_buff = mymalloc(AVI_AUDIO_BUF_SIZE);
framebuf = mymalloc(AVI_VIDEO_BUF_SIZE); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶbuf
favi = (FIL *)mymalloc(sizeof(FIL)); // <20><><EFBFBD><EFBFBD>favi<76>ڴ<EFBFBD>
g_i2sbuf[0] = mymalloc(AVI_AUDIO_BUF_SIZE); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ڴ<EFBFBD>
g_i2sbuf[1] = mymalloc(AVI_AUDIO_BUF_SIZE); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ڴ<EFBFBD>
g_i2sbuf[2] = mymalloc(AVI_AUDIO_BUF_SIZE); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ڴ<EFBFBD>
g_i2sbuf[3] = mymalloc(AVI_AUDIO_BUF_SIZE); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ڴ<EFBFBD>
mymemset(g_i2sbuf[0], 0, AVI_AUDIO_BUF_SIZE);
mymemset(g_i2sbuf[1], 0, AVI_AUDIO_BUF_SIZE);
mymemset(g_i2sbuf[2], 0, AVI_AUDIO_BUF_SIZE);
mymemset(g_i2sbuf[3], 0, AVI_AUDIO_BUF_SIZE);
while (res == 0) {
res = f_open(favi, (char *)pname, FA_READ);
if (res == 0) {
pbuf = framebuf;
res = f_read(favi, pbuf, AVI_VIDEO_BUF_SIZE, &nr); // <20><>ʼ<EFBFBD><CABC>ȡ
if (res) {
break;
}
// <20><>ʼavi<76><69><EFBFBD><EFBFBD>
res = avi_init(pbuf, AVI_VIDEO_BUF_SIZE); // avi<76><69><EFBFBD><EFBFBD>
if (res) {
break;
}
// avi_timer_init (avix.SecPerFrame);
offset =
avi_srarch_id(pbuf, AVI_VIDEO_BUF_SIZE, (u8 *)"movi"); // Ѱ<><D1B0>movi ID
avi_get_streaminfo(pbuf + offset + 4); // <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ϣ
f_lseek(favi, offset + 12 - 8); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־ID,<2C><><EFBFBD><EFBFBD>ַƫ<D6B7>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD>ʼ<EFBFBD><CABC>
extern void jdmerge_setvideo_xsize(int xsize, int lcd_xsize);
jdmerge_setvideo_xsize(avix.Width, LCD_GetLcdSizeX()); // <20><><EFBFBD>õ<EFBFBD>ַ<EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
res =
mjpegdec_init((LCD_GetLcdSizeX() - avix.Width) / 2,
(LCD_GetLcdSizeY() - avix.Height) / 2); // JPG<50><47><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
if (avix.SampleRate) // <20><><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>Ϣ,<2C>ų<EFBFBD>ʼ<EFBFBD><CABC>
{
// <20><>ʼ<EFBFBD><CABC>DAC
dac.buff1 = (u32 *)g_i2sbuf[1];
dac.buff2 = (u32 *)g_i2sbuf[2];
dac.buff_size = avix.AudioBufSize;
dac.rate = DAC_GetRate(avix.SampleRate);
dac.call_back = audio_i2s_dma_callback;
DAC_NormalInit(&dac);
}
while (1) // <20><><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
{
f_read(favi, listhead, 8, &nr);
if (avi_get_streaminfo(listhead)) // <20><>ȡ<EFBFBD><C8A1>һ֡ <20><><EFBFBD><EFBFBD>־
{
break;
}
if (Touch_GetState()->x[1] != 0)
break; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><E3B4A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (USART3_GetKeyPressed() & (0x08))
break; // <20><><EFBFBD>·<EFBFBD><C2B7>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD>
if (avix.StreamID == AVI_VIDS_FLAG) // <20><>Ƶ<EFBFBD><C6B5>
{
pbuf = framebuf;
// mymemset (pbuf,0,AVI_VIDEO_BUF_SIZE);
f_read(favi, pbuf, avix.StreamSize + 8 - 8,
&nr); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡+<2B><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID<49><44>Ϣ
// <20>ȴ<EFBFBD>֡ʱ<D6A1><CAB1>
// while (g_frame_en==0){} g_frame_en=0;
while (LCD_GetLayerUpdataStat() == 0)
;
LCD_SwitchLayerBuff();
res = mjpegdec_decode(pbuf, avix.StreamSize);
if (res == 0) {
LCD_ExitLayerBuff();
}
if (res) {
// break;
}
} else // <20><>Ƶ<EFBFBD><C6B5>
{
// f_read(favi,audio_buff,avix.StreamSize+8-8,&nr);//<2F><><EFBFBD><EFBFBD>i2sbuf
// pbuf=audio_buff;
i2ssavebuf++;
if (i2ssavebuf > 3)
i2ssavebuf = 0;
do {
nr = g_i2splaybuf;
if (nr)
nr--;
else
nr = 3;
} while (i2ssavebuf == nr); // <20><>ײ<EFBFBD>ȴ<EFBFBD>.
f_read(favi, g_i2sbuf[i2ssavebuf], avix.StreamSize,
&nr); // <20><><EFBFBD><EFBFBD>i2sbuf
u16 *p = (u16 *)g_i2sbuf[i2ssavebuf];
for (int i = 0; i < avix.StreamSize / 2; i++)
p[i] = (p[i] + 0x8000) >> 4;
pbuf = g_i2sbuf[i2ssavebuf];
}
}
// avi_tiemr_delete();
mjpegdec_free(); // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
f_close(favi);
}
if (loop == 0)
break;
}
myfree(framebuf);
myfree(favi);
myfree(audio_buff);
myfree(g_i2sbuf[0]);
myfree(g_i2sbuf[1]);
myfree(g_i2sbuf[2]);
myfree(g_i2sbuf[3]);
DAC_NormalDeInit(&dac);
return (int)res;
}