📄 movie_rec.c
字号:
/*
DM270 ARM Evaluation Software
(c)Texas Instruments 2003
*/
#include <system/intc270.h>
#include <system/uart270.h>
#include <system/dspc270.h>
#include <user/armdsp.h>
#include <user/prev.h>
#include <user/ccdm_3d3.h>
#include <user/ccdm.h>
#include <user/ccdc.h>
#include <user/osd.h>
#include <user/intc.h>
#include <dsp/dspsource.h>
#include <appl/movie_main.h>
#include <appl/movie_rec.h>
#include <util/mem_fs.h>
#include <demo/dm270_demo.h>
#include <demo/mem_alloc.h>
#include <demo/menu.h>
#include <demo/ui.h>
#include <util/file_name_gen.h>
#include <demo_gui/demo_gui.h>
#include <qtff/qt.h>
//MPEG-4
MPEG4_REC_START_CMD Mpeg4RecStartCmd;
MPEG4_REC_CMD_REPLY Mpeg4RecStartCmdReply;
MPEG4_REC_DSP_REQ Mpeg4RecDspReq;
MPEG4_REC_DSP_REQ_REPLY Mpeg4RecDspReqReply;
//MJPEG
MJPEG_REC_START_CMD MjpegRecStartCmd;
MJPEG_REC_CMD_REPLY MjpegRecStartCmdReply;
MJPEG_REC_DSP_REQ MjpegRecDspReq;
MJPEG_REC_DSP_REQ_REPLY MjpegRecDspReqReply;
STATUS MOVIE_REC_init() {
//MPEG-4
Mpeg4RecStartCmd.VideoAddrHigh = HIGH_WORD(OSD_VIDEO_WIN0_OFFSET);
Mpeg4RecStartCmd.VideoAddrLow = LOW_WORD (OSD_VIDEO_WIN0_OFFSET);
Mpeg4RecStartCmd.WorkAreaAddrHigh = HIGH_WORD(WORK_AREA_OFFSET);
Mpeg4RecStartCmd.WorkAreaAddrLow = LOW_WORD (WORK_AREA_OFFSET);
Mpeg4RecStartCmd.RingBuffAddrHigh = HIGH_WORD(MOVIE_BUFFER_OFFSET);
Mpeg4RecStartCmd.RingBuffAddrLow = LOW_WORD (MOVIE_BUFFER_OFFSET);
Mpeg4RecStartCmd.RingBuffSizeHigh = HIGH_WORD(MOVIE_BUFFER_SIZE);
Mpeg4RecStartCmd.RingBuffSizeLow = LOW_WORD (MOVIE_BUFFER_SIZE);
Mpeg4RecStartCmd.AvgBitRateHigh = HIGH_WORD(MPEG4_REC_AVG_BITRATE);
Mpeg4RecStartCmd.AvgBitRateLow = LOW_WORD (MPEG4_REC_AVG_BITRATE);
Mpeg4RecStartCmd.MaxBitRateHigh = HIGH_WORD(MPEG4_REC_MAX_BITRATE);
Mpeg4RecStartCmd.MaxBitRateLow = LOW_WORD (MPEG4_REC_MAX_BITRATE);
Mpeg4RecStartCmd.ImageSize = MPEG4_REC_320x240;
Mpeg4RecStartCmd.FrameRate = MPEG4_FRAME_RATE;
Mpeg4RecStartCmd.SecPerGOV = 1;
Mpeg4RecStartCmd.PreFilter = 0; // MPEG4 Pre Filter,0:None 1-7:Adaptive 8-31:Fixed
Mpeg4RecStartCmd.RateControl = (Uint16)-2; // MPEG4 Rate Control, Fixed QP:1-31, Rate Control:-1, Frame&Bit Rate:-2
Mpeg4RecStartCmd.IniQvalue = 4;
Mpeg4RecStartCmd.IniIPRatio = 4;
Mpeg4RecStartCmd.ShortCycleSpeedControl = 7;
Mpeg4RecStartCmd.LongCycleSpeedControl = 31;
Mpeg4RecStartCmd.Reserved = 0;
Mpeg4RecStartCmd.AudioRingBuffAddrHigh = HIGH_WORD(AUDIO_BUFFER_OFFSET);
Mpeg4RecStartCmd.AudioRingBuffAddrLow = LOW_WORD (AUDIO_BUFFER_OFFSET);
Mpeg4RecStartCmd.AudioRingBuffSizeHigh = HIGH_WORD(AUDIO_BUFFER_SIZE);
Mpeg4RecStartCmd.AudioRingBuffSizeLow = LOW_WORD (AUDIO_BUFFER_SIZE);
Mpeg4RecStartCmd.AudioBitRate = MPEG_G726_32KBPS;
Mpeg4RecStartCmd.AudioQuality = 2;
Mpeg4RecStartCmd.VoiceDelayTime = 0;
Mpeg4RecStartCmd.AudioFormat = MOVIE_AUDIO_FORMAT_G711;
//MJPEG
MjpegRecStartCmd.VideoAddrHigh = HIGH_WORD(OSD_VIDEO_WIN0_OFFSET);
MjpegRecStartCmd.VideoAddrLow = LOW_WORD (OSD_VIDEO_WIN0_OFFSET);
MjpegRecStartCmd.RingBuffAddrHigh = HIGH_WORD(MOVIE_BUFFER_OFFSET);
MjpegRecStartCmd.RingBuffAddrLow = LOW_WORD (MOVIE_BUFFER_OFFSET);
MjpegRecStartCmd.RingBuffSizeHigh = HIGH_WORD(MOVIE_BUFFER_SIZE);
MjpegRecStartCmd.RingBuffSizeLow = LOW_WORD (MOVIE_BUFFER_SIZE);
MjpegRecStartCmd.ImageSize = MJPEG_REC_320x240;
MjpegRecStartCmd.ImgFormat = 0;//Image data format =. 0:VIDEO, 1:SEPARATE420, 2:SEPARATE422
MjpegRecStartCmd.EncFormat = MOVIE_ENC_IMAGE_FORMAT_YUV420;// 4:YUV420, 3:YUV422
MjpegRecStartCmd.RestartMakerInterval = 0;
MjpegRecStartCmd.QFactor = 128;
MjpegRecStartCmd.FrameRate = MJPEG_FRAME_RATE;
MjpegRecStartCmd.Reserved = 0;
MjpegRecStartCmd.AudioRingBuffAddrHigh = HIGH_WORD(AUDIO_BUFFER_OFFSET);
MjpegRecStartCmd.AudioRingBuffAddrLow = LOW_WORD (AUDIO_BUFFER_OFFSET);
MjpegRecStartCmd.AudioRingBuffSizeHigh = HIGH_WORD(AUDIO_BUFFER_SIZE);
MjpegRecStartCmd.AudioRingBuffSizeLow = LOW_WORD (AUDIO_BUFFER_SIZE);
MjpegRecStartCmd.AudioBitRate = MJPEG_G711_64KBPS;
MovieCtrl.QtFileFormat = TRUE;
return E_PASS;
}
void MOVIE_REC_run(MOVIE_MODE mode) {
BOOL stopped;
char ch;
switch(mode) {
case MOVIE_MPEG4_MODE:
UART_sendString( UART0, mpeg4_record_in_progress_menu);
break;
case MOVIE_MJPEG_MODE:
UART_sendString( UART0, mjpeg_record_in_progress_menu);
break;
default:
return;
}
if( MOVIE_REC_START_run(mode) != E_PASS )
return;
stopped=FALSE;
while(!stopped) {
ch = UI_checkInput();
switch(ch) {
case '1':
MOVIE_REC_PAUSE_run(mode);
break;
case '2':
UART_sendString( UART0, "\r\n\n Stopping recording. Please wait ...");
// if movie is paused, resume it and then stop it
if(MovieCtrl.MoviePaused)
MOVIE_REC_PAUSE_run(mode);
MovieCtrl.MovieStopped = TRUE;
break;
case '3':
MOVIE_REC_FULLSCREEN_run(mode);
break;
default :
GUI_controlPanelSeekBarUpdate(MovieCtrl.VideoSize);
//GUI_controlPanelTimerUpdate(MovieCtrl.FrameCount/MovieCtrl.FrameRate);
stopped = MovieCtrl.DspStopped;
MOVIE_REC_IN_PROGRESS_run(mode);
if(stopped)
MOVIE_REC_STOP_run(mode);
break;
}
}
}
void MOVIE_REC_PAUSE_run(MOVIE_MODE mode) {
Uint16 cmd;
if(MovieCtrl.FrameCount<1)
return;
if(MovieCtrl.MoviePaused==TRUE) {
MovieCtrl.MoviePaused=FALSE;
UART_sendString( UART0, "\r\n Record Resumed.");
GUI_controlPanelButtonStateSet(&BUTTON_RECORD_START);
} else {
MovieCtrl.MoviePaused=TRUE;
UART_sendString( UART0, "\r\n Record Paused.");
GUI_controlPanelButtonStateSet(&BUTTON_RECORD_PAUSE);
}
cmd = 0;
DSPC_writeData((char*)&cmd, 1, ARM_DSP_DSPCCR);
switch(mode) {
case MOVIE_MPEG4_MODE:
ARMDSP_sendDspCmd(MPEG4_REC_PAUSE, NULL, 0);
TMRDelay(20);
do {
DSPC_readData((char*)&cmd, 1, ARM_DSP_DSPCCR);
} while( (cmd&DSP_CMD_MASK) != MPEG4_REC_PAUSE );
break;
case MOVIE_MJPEG_MODE:
ARMDSP_sendDspCmd(MJPEG_REC_PAUSE, NULL, 0);
TMRDelay(20);
do {
DSPC_readData((char*)&cmd, 1, ARM_DSP_DSPCCR);
} while( (cmd&DSP_CMD_MASK) != MJPEG_REC_PAUSE );
break;
default:
break;
}
if( (cmd&DSP_CMD_COMPLETE)!=DSP_CMD_COMPLETE )
MovieCtrl.DspStopped = TRUE;
}
STATUS MOVIE_REC_START_run(MOVIE_MODE mode) {
STATUS status;
Uint16 cmd;
// stop OSD, PREV, CCDC
OSD_winEnable( OSD_VID_WIN0, FALSE);
PREV_enable(FALSE);
CCDC_enable(FALSE, FALSE);
INTC_clearIRQ(INT_DSP);
INTC_enable( INT_DSP, FALSE);
// download DSP code
switch(mode) {
case MOVIE_MPEG4_MODE:
status = DSPLoadCode(mpeg4_encode);
break;
case MOVIE_MJPEG_MODE:
status = DSPLoadCode(mjpeg_encode);
break;
default:
return E_INVALID_INPUT;
}
if(status!=E_PASS) {
UART_sendString( UART0, "\r\n ERROR : DSPLoadCode(). ");
return status;
}
MOVIE_AIC23_init(TRUE);
// wait for DSP to be ready
do {
ARMDSP_getArmCmd(&cmd, NULL, 0);
} while( cmd != 0x777 ) ;
// init MovieCtrl data structure
status = MOVIE_REC_initMovieCtrl(mode);
if(status != E_PASS )
return status;
// init PREV, CCDC, OSD
MOVIE_REC_initPREV(mode);
switch(mode) {
case MOVIE_MPEG4_MODE:
INTC_clearIRQ(INT_DSP);
ARMDSP_sendDspCmd( MPEG4_REC_START, (Uint16*)&Mpeg4RecStartCmd, sizeof(Mpeg4RecStartCmd)/2);
break;
case MOVIE_MJPEG_MODE:
INTC_clearIRQ(INT_DSP);
ARMDSP_sendDspCmd( MJPEG_REC_START, (Uint16*)&MjpegRecStartCmd, sizeof(MjpegRecStartCmd)/2);
break;
default:
return E_INVALID_INPUT;
}
INTC_waitForInt( INT_DSP, 0);
switch(mode) {
case MOVIE_MPEG4_MODE:
ARMDSP_getDspReply( &cmd, (Uint16*)&Mpeg4RecStartCmdReply, sizeof(Mpeg4RecStartCmdReply)/2 );
// check reply
if( (cmd & DSP_CMD_MASK) != MPEG4_REC_START) {
UART_sendString( UART0, "\r\n ERROR : MPEG4 record start DSP command, failed.");
return E_DEVICE;
}
if( (cmd & DSP_CMD_COMPLETE) != DSP_CMD_COMPLETE) {
UART_sendString( UART0, "\r\n ERROR : MPEG4 record start DSP command, failed.");
return E_DEVICE;
}
if( (cmd & DSP_CMD_INVALID_CMD ) || (cmd & DSP_CMD_INVALID_PARAM ) ) {
UART_sendString( UART0, "\r\n ERROR : MPEG4 record start DSP command, invalid DSP command/paramters.");
return E_DEVICE;
}
break;
case MOVIE_MJPEG_MODE:
ARMDSP_getDspReply( &cmd, (Uint16*)&MjpegRecStartCmdReply, sizeof(MjpegRecStartCmdReply)/2 );
// check reply
if( (cmd & DSP_CMD_MASK) != MJPEG_REC_START) {
UART_sendString( UART0, "\r\n ERROR : MJPEG record start DSP command, failed.");
return E_DEVICE;
}
if( (cmd & DSP_CMD_COMPLETE) != DSP_CMD_COMPLETE) {
UART_sendString( UART0, "\r\n ERROR : MJPEG record start DSP command, failed.");
return E_DEVICE;
}
if( (cmd & DSP_CMD_INVALID_CMD ) || (cmd & DSP_CMD_INVALID_PARAM ) ) {
UART_sendString( UART0, "\r\n ERROR : MJPEG record start DSP command, invalid DSP command/paramters.");
return E_DEVICE;
}
break;
default:
return E_INVALID_INPUT;
}
// attach DSP HINT ISR
switch(mode) {
case MOVIE_MPEG4_MODE:
INTC_enable( INT_DSP, FALSE);
INTCAttachISR( INT_DSP, MPEG4_REC_isr );
INTC_enable( INT_DSP, TRUE);
GUI_controlPanelButtonStateSet(&BUTTON_RECORD_START);
break;
case MOVIE_MJPEG_MODE:
INTC_enable( INT_DSP, FALSE);
INTCAttachISR( INT_DSP, MJPEG_REC_isr );
INTC_enable( INT_DSP, TRUE);
GUI_controlPanelButtonStateSet(&BUTTON_RECORD_START);
break;
default:
return E_INVALID_INPUT;
}
return E_PASS;
}
void MOVIE_REC_IN_PROGRESS_run(MOVIE_MODE mode) {
if(MovieCtrl.VideoBuffWrite) {
MovieCtrl.VideoBuffWrite = FALSE;
if(FS_FILE_IO) {
profile_start(10);
FILE_write( MovieCtrl.FS_VideoFile , (char*)MovieCtrl.VideoRingBuffer.startAddr + MovieCtrl.VideoRingBuffer.curBuff*(MovieCtrl.VideoRingBuffer.size/3),
MovieCtrl.VideoRingBuffer.size/3
);
profile_end(10);
} else {
MEM_FILE_write( &MovieCtrl.VideoFile,
(char*)MovieCtrl.VideoRingBuffer.startAddr + MovieCtrl.VideoRingBuffer.curBuff*(MovieCtrl.VideoRingBuffer.size/3),
MovieCtrl.VideoRingBuffer.size/3 );
}
MovieCtrl.VideoRingBuffer.curBuff = (MovieCtrl.VideoRingBuffer.curBuff+1)%3;
MovieCtrl.CurVideoFileSize += MovieCtrl.VideoRingBuffer.size/3;
UART_sendString( UART0, "+" );
}
if(MovieCtrl.AudioBuffWrite) {
MovieCtrl.AudioBuffWrite = FALSE;
if(FS_FILE_IO && MovieCtrl.QtFileFormat==FALSE) {
profile_start(10);
FILE_write( MovieCtrl.FS_AudioFile, (char*)MovieCtrl.AudioRingBuffer.startAddr + MovieCtrl.AudioRingBuffer.curBuff*(MovieCtrl.AudioRingBuffer.size/3),
MovieCtrl.AudioRingBuffer.size/3
);
profile_end(10);
} else {
MEM_FILE_write( &MovieCtrl.AudioFile,
(char*)MovieCtrl.AudioRingBuffer.startAddr + MovieCtrl.AudioRingBuffer.curBuff*(MovieCtrl.AudioRingBuffer.size/3),
MovieCtrl.AudioRingBuffer.size/3 );
}
MovieCtrl.AudioRingBuffer.curBuff = (MovieCtrl.AudioRingBuffer.curBuff+1)%3;
MovieCtrl.CurAudioFileSize += MovieCtrl.AudioRingBuffer.size/3;
UART_sendString( UART0, "." );
}
}
void MOVIE_REC_STOP_run(MOVIE_MODE mode) {
// flush incompltely filled buffer (Video, Audio) data to file
if(FS_FILE_IO) {
if(MovieCtrl.FS_VideoFile!=NULL) {
if(MovieCtrl.VideoSize > MovieCtrl.CurVideoFileSize) {
MovieCtrl.VideoSize += (MovieCtrl.VideoSize+4)&0x3;
if(MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize <= MovieCtrl.VideoRingBuffer.size/3) {
FILE_write( MovieCtrl.FS_VideoFile, (char*)MovieCtrl.VideoRingBuffer.startAddr + MovieCtrl.VideoRingBuffer.curBuff*(MovieCtrl.VideoRingBuffer.size/3),
MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize
);
MovieCtrl.CurVideoFileSize += (MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize);
} else {
FILE_write( MovieCtrl.FS_VideoFile, (char*)MovieCtrl.VideoRingBuffer.startAddr + MovieCtrl.VideoRingBuffer.curBuff*(MovieCtrl.VideoRingBuffer.size/3),
(MovieCtrl.VideoRingBuffer.size/3)
);
MovieCtrl.CurVideoFileSize += (MovieCtrl.VideoRingBuffer.size/3);
MovieCtrl.VideoRingBuffer.curBuff = (MovieCtrl.VideoRingBuffer.curBuff+1)%3;
FILE_write( MovieCtrl.FS_VideoFile, (char*)MovieCtrl.VideoRingBuffer.startAddr + MovieCtrl.VideoRingBuffer.curBuff*(MovieCtrl.VideoRingBuffer.size/3),
(MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize)%(MovieCtrl.VideoRingBuffer.size/3)
);
MovieCtrl.CurVideoFileSize += ( (MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize)%(MovieCtrl.VideoRingBuffer.size/3) );
}
}
if(FS_FILE_IO && MovieCtrl.QtFileFormat==FALSE)
FILE_close( MovieCtrl.FS_VideoFile, FILEIO_NO_FAT_CACHE_FLUSH );
else {
// QTFF wrapper needs to be appended to this file, so this file is kept open
// this file would be closed inside MOVIE_REC_qtffCreate();
}
}
} else {
if(MovieCtrl.VideoSize > MovieCtrl.CurVideoFileSize) {
if(MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize <= MovieCtrl.VideoRingBuffer.size/3) {
MEM_FILE_write( &MovieCtrl.VideoFile,
(char*)MovieCtrl.VideoRingBuffer.startAddr + MovieCtrl.VideoRingBuffer.curBuff*(MovieCtrl.VideoRingBuffer.size/3),
MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize );
MovieCtrl.CurVideoFileSize += (MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize);
} else {
MEM_FILE_write( &MovieCtrl.VideoFile,
(char*)MovieCtrl.VideoRingBuffer.startAddr + MovieCtrl.VideoRingBuffer.curBuff*(MovieCtrl.VideoRingBuffer.size/3),
(MovieCtrl.VideoRingBuffer.size/3) );
MovieCtrl.CurVideoFileSize += (MovieCtrl.VideoRingBuffer.size/3);
MovieCtrl.VideoRingBuffer.curBuff = (MovieCtrl.VideoRingBuffer.curBuff+1)%3;
MEM_FILE_write( &MovieCtrl.VideoFile,
(char*)MovieCtrl.VideoRingBuffer.startAddr + MovieCtrl.VideoRingBuffer.curBuff*(MovieCtrl.VideoRingBuffer.size/3),
(MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize)%(MovieCtrl.VideoRingBuffer.size/3) );
MovieCtrl.CurVideoFileSize += ( (MovieCtrl.VideoSize - MovieCtrl.CurVideoFileSize)%(MovieCtrl.VideoRingBuffer.size/3) );
}
}
MEM_FILE_close( &MovieCtrl.VideoFile );
}
// flush incompltely filled buffer (Video, Audio) data to file
if(FS_FILE_IO && MovieCtrl.QtFileFormat==FALSE) {
if(MovieCtrl.FS_AudioFile!=NULL) {
if( MovieCtrl.AudioSize > MovieCtrl.CurAudioFileSize ) {
if(MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize <= MovieCtrl.AudioRingBuffer.size/3) {
FILE_write( MovieCtrl.FS_AudioFile, (char*)MovieCtrl.AudioRingBuffer.startAddr + MovieCtrl.AudioRingBuffer.curBuff*(MovieCtrl.AudioRingBuffer.size/3),
MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize
);
MovieCtrl.CurAudioFileSize += (MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize);
} else {
FILE_write( MovieCtrl.FS_AudioFile, (char*)MovieCtrl.AudioRingBuffer.startAddr + MovieCtrl.AudioRingBuffer.curBuff*(MovieCtrl.AudioRingBuffer.size/3),
(MovieCtrl.AudioRingBuffer.size/3)
);
MovieCtrl.CurAudioFileSize += (MovieCtrl.AudioRingBuffer.size/3);
MovieCtrl.AudioRingBuffer.curBuff = (MovieCtrl.AudioRingBuffer.curBuff+1)%3;
FILE_write( MovieCtrl.FS_AudioFile, (char*)MovieCtrl.AudioRingBuffer.startAddr + MovieCtrl.AudioRingBuffer.curBuff*(MovieCtrl.AudioRingBuffer.size/3),
(MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize)%(MovieCtrl.AudioRingBuffer.size/3)
);
MovieCtrl.CurAudioFileSize += (MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize)%(MovieCtrl.AudioRingBuffer.size/3);
}
}
FILE_close( MovieCtrl.FS_AudioFile, 0 );
}
} else {
if( MovieCtrl.AudioSize > MovieCtrl.CurAudioFileSize ) {
if(MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize <= MovieCtrl.AudioRingBuffer.size/3) {
MEM_FILE_write( &MovieCtrl.AudioFile,
(char*)MovieCtrl.AudioRingBuffer.startAddr + MovieCtrl.AudioRingBuffer.curBuff*(MovieCtrl.AudioRingBuffer.size/3),
MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize );
MovieCtrl.CurAudioFileSize += (MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize);
} else {
MEM_FILE_write( &MovieCtrl.AudioFile,
(char*)MovieCtrl.AudioRingBuffer.startAddr + MovieCtrl.AudioRingBuffer.curBuff*(MovieCtrl.AudioRingBuffer.size/3),
(MovieCtrl.AudioRingBuffer.size/3) );
MovieCtrl.CurAudioFileSize += (MovieCtrl.AudioRingBuffer.size/3);
MovieCtrl.AudioRingBuffer.curBuff = (MovieCtrl.AudioRingBuffer.curBuff+1)%3;
MEM_FILE_write( &MovieCtrl.AudioFile,
(char*)MovieCtrl.AudioRingBuffer.startAddr + MovieCtrl.AudioRingBuffer.curBuff*(MovieCtrl.AudioRingBuffer.size/3),
(MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize)%(MovieCtrl.AudioRingBuffer.size/3) );
MovieCtrl.CurAudioFileSize += (MovieCtrl.AudioSize - MovieCtrl.CurAudioFileSize)%(MovieCtrl.AudioRingBuffer.size/3);
}
}
MEM_FILE_close( &MovieCtrl.AudioFile );
}
MEM_FILE_seek ( &MovieCtrl.IndexFile, 0, MEM_FILE_SEEK_START );
MEM_FILE_write( &MovieCtrl.IndexFile, (char*)&MovieCtrl.FrameCount, sizeof(Uint32) );
MEM_FILE_close( &MovieCtrl.IndexFile );
sprintf( UART_outBuff, "\r\n"
"\r\n Recording Stopped. "
"\r\n %ld video frames encoded."
"\r\n Video data size = %ld B"
"\r\n Audio data size = %ld B"
"\r\n"
"\r\n", MovieCtrl.FrameCount, MovieCtrl.VideoSize, MovieCtrl.AudioSize );
UART_sendString( UART0, UART_outBuff );
INTC_enable( INT_VD0, FALSE);
INTCDetachISR( INT_VD0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -