⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 movie_rec.c

📁 dm270 source code
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
    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 + -