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

📄 play_avi_push.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
			for (i=0 ; i<audioInstances ; i++) {				DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(avi_info->dcc_info->pMultipleAudioSource, i, &audioHandle);								e.ModuleID = audioHandle.moduleID;				e.Mask = RUAEVENT_INBAND_COMMAND;				/* struct e is already set */				RUAResetEvent(avi_info->pRUA, &e);								InbandCmd.Tag = EMhwlibInbandCommand_EOS | INBAND_COMMAND_TYPE_BYTECOUNT | INBAND_COMMAND_NO_COORDINATE;				InbandCmd.Tag |= INBAND_COMMAND_DEST_AUDIO | INBAND_COMMAND_ACTION_STOP;				InbandCmd.Coordinate = 0;				RUASetProperty(avi_info->pRUA, audioHandle.moduleID, RMGenericPropertyID_InbandCommand, &InbandCmd, sizeof(InbandCmd), 0);			}			avi_info->switching_audio = TRUE;		}	}								                 	if ((actions.cmd == RM_DUALMODE_CHANGE) && (!actions.cmdProcessed)) {		RMuint32 i;		fprintf(stderr, "Changing DualMode to :");		switch(audio_opt[0].OutputDualMode) {		case DualMode_LeftMono:			fprintf(stderr, " RightMono\n");			audio_opt[0].OutputDualMode = DualMode_RightMono;			break;		case DualMode_RightMono:			fprintf(stderr, " MixMono\n");			audio_opt[0].OutputDualMode = DualMode_MixMono;			break;		case DualMode_MixMono:			fprintf(stderr, " Stereo\n");			audio_opt[0].OutputDualMode = DualMode_Stereo;			break;		case DualMode_Stereo:			fprintf(stderr, " LeftMono\n");			audio_opt[0].OutputDualMode = DualMode_LeftMono;			break;		default:			fprintf(stderr, " Unknown dual mode\n");			break;		} 		for (i=0; i < audioInstances; i++) {											audio_opt[i].OutputDualMode = audio_opt[0].OutputDualMode;										err = apply_audio_decoder_options_onthefly(avi_info->dcc_info, &(audio_opt[i]));			if (RMFAILED(err)) {				fprintf(stderr, "Error applying audio decoder options on the fly %d\n", err);			}		}		actions.cmdProcessed = TRUE;	}	if (actions.toDoActions & RM_PSM_NORMAL_PLAY) {		if (play_opt->fast_audio_recovery) {			RMuint64 wantedTime;			RMuint64 videoPTS = 0;									if (avi_info->dcc_info->SurfaceID != 0) {				err = RUAGetProperty(avi_info->pRUA, avi_info->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &videoPTS, sizeof(videoPTS));				if (err != RM_OK) {					RMDBGLOG((ENABLE, "error %d while getting CurrentDisplayPTS\n", err));					return LABEL_ERROR;				}			}			if (avi_info->vopTimeIncrementResolution == 90000)				videoPTS *= 2;						RMDBGLOG((ENABLE, "videoPTS %llu / %llu\n", videoPTS, (RMuint64)avi_info->vopTimeIncrementResolution));			wantedTime = (RMuint64)(videoPTS*1000000)/avi_info->vopTimeIncrementResolution;			RMDBGLOG((ENABLE, ">> seeking to %llu us to recover audio faster\n", wantedTime));			err = local_seek(avi_info, wantedTime);			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "Cannot seek to current display time\n"));				return LABEL_ERROR;			}			RM_PSM_SetState(avi_info->PSMcontext, &(avi_info->dcc_info), RM_PSM_Playing);			return (RMFAILED(err)) ? LABEL_ERROR : LABEL_STOP;					}		actions.toDoActions &= ~RM_PSM_NORMAL_PLAY;	}		return LABEL_NONE;}static void check_prebuf_state(struct avi_context *avi_info, RMuint32 buffersize){	RMbool quit_prebuf = FALSE;	enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(avi_info->PSMcontext, &(avi_info->dcc_info));		if (PlaybackStatus != RM_PSM_Prebuffering)		return;	/* if fail in getbuffer force quitting prebuffering state */	if (buffersize == 0) {		RMDBGLOG((ENABLE, "1\n"));		quit_prebuf = TRUE;	}	else if ((play_opt->prebuf_max > 0) && (avi_info->prebuf_level >= play_opt->prebuf_max)) {		RMDBGLOG((ENABLE, "2\n"));		quit_prebuf = TRUE;	}	avi_info->prebuf_level += buffersize;			if (quit_prebuf) {		monitorFIFO(avi_info, TRUE);		RMDBGLOG((ENABLE, "exit prebuffering state\n"));		RMDBGLOG((ENABLE, "setting play state\n"));		fprintf(stderr, "now playing\n");		RM_PSM_SetState(avi_info->PSMcontext, &(avi_info->dcc_info), RM_PSM_Playing);		Play(avi_info, RM_DEVICES_AUDIO | RM_DEVICES_VIDEO | RM_DEVICES_STC, DCCVideoPlayFwd);	}}static void checkInterleavedCallback (RMuint8 chunkid[4], RMuint8 *chunk, RMuint32 chunkLength, RMuint32 flags, void *context){	struct avi_interleaved_context *interleaved_info = (struct avi_interleaved_context*)context;	if ((chunkid[2] == 'd') && ((chunkid[3] == 'c') || (chunkid[3] == 'b'))){		interleaved_info->video_chunks++;	}			else if ((chunkid[2] == 'w') && (chunkid[3] == 'b')){		interleaved_info->audio_chunks++;	}}/* read some chunks from the beginning of the movi * if we find audio and video chunks in the first quarter * (or the first 1MB, whaterver comes first) * we decide that the file is interleaved */static RMbool check_interleaved(struct avi_context *avi_info){	RMuint8 *buf;	RMuint32 parsed_bytes = 0, max_parsed_bytes;	RMuint32 buf_size = (RMuint32) (1<<play_opt->dmapool_log2size);	RMuint32 movi_offset, movi_size;		RMstatus err;	struct avi_interleaved_context interleaved_context;	err = RMAviPushGetMoviOffset(avi_info->pAvi, &movi_offset);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot get movi offset\n"));		return FALSE;	}	err = RMAviPushGetMoviSize(avi_info->pAvi, &movi_size);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot get movi size\n"));		return FALSE;	}	err = RMSeekFile(avi_info->avi_file, movi_offset, RM_FILE_SEEK_START);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error seeking file to movi\n"));		return FALSE;	}		RMAviPushInitDemuxMovi (avi_info->pAvi, checkInterleavedCallback, NULL);	interleaved_context.audio_chunks = 0;	interleaved_context.video_chunks = 0;	while (RUAGetBuffer(avi_info->pDMA, &buf, COMMON_TIMEOUT_US) != RM_OK) {		RMDBGLOG((ENABLE, "Cannot get buffer for interleaved detection\n"));	}	max_parsed_bytes = RMmin(1024*1024, movi_size/4);	while(parsed_bytes < max_parsed_bytes){		RMuint32 count;		err = RMReadFile(avi_info->avi_file, buf, buf_size, &count);		if (RMFAILED(err)) {			break;		}		RMAviPushDemuxMovi(avi_info->pAvi, buf, count, &interleaved_context);		parsed_bytes += count;					}	RUAReleaseBuffer(avi_info->pDMA, buf);		RMDBGLOG((ENABLE, "demuxed %lu bytes and found %lu audio chunks and %lu video chunks\n", parsed_bytes, interleaved_context.audio_chunks, interleaved_context.video_chunks));	if((interleaved_context.audio_chunks) &&	   (interleaved_context.video_chunks)){		fprintf(stderr, "File does not have the interleaved flag but seems to be interleaved.\n");		return TRUE;	}	else		return FALSE;}#define DONT_SCALE_AUDIO_PTS 0static void moviDemuxCallback (RMuint8 chunkid[4], RMuint8 *chunk, RMuint32 chunkLength, RMuint32 flags, void *context){	struct avi_context *avi_info = (struct avi_context *) context;	RMuint32 decoder = 0;	RMstatus err; 	struct emhwlib_info Info = {0,};	enum RM_PSM_State FSMstate;	RMbool isAudio = FALSE;#ifdef _DEBUG	RMint64 diffPTS = 0;#endif	RMDBGLOG((DISABLE, "chunk '%c%c%c%c' size %lu flags(%s%s)\n",		  chunkid[0],		  chunkid[1],		  chunkid[2],		  chunkid[3],		  chunkLength,		  flags & RMAVI_FLAG_CHUNK_START ? "chunkStart ":"",		  flags & RMAVI_FLAG_CHUNK_END ? "chunkEnd":""));	if (avi_info->quitCallback)		return;	if ((avi_info->iframe) && (avi_info->video_end))		return;		FSMstate = RM_PSM_GetState(avi_info->PSMcontext, &(avi_info->dcc_info));	if ((chunkid[2] == 'd') && ((chunkid[3] == 'c') || (chunkid[3] == 'b'))){		RMDBGLOG((AVIDBG, "RECEIVED VIDEO CHUNK (size = %lu)!!!\n", chunkLength));		decoder = avi_info->dcc_info->video_decoder;		if (flags & RMAVI_FLAG_CHUNK_START) {			Info.ValidFields = (play_opt->send_video_pts) ? TIME_STAMP_INFO : 0;						Info.TimeStamp = (RMuint64)(avi_info->videoFrameCounter) * avi_info->vopTimeIncrement;			avi_info->videoPTS = Info.TimeStamp;			RMDBGLOG((AVIDBG, "Sending video PTS = %llu\n", Info.TimeStamp));			/* in rewind, can be ++ here since it is overwritten in the main loop */			avi_info->videoFrameCounter++;		}		if (flags & RMAVI_FLAG_CHUNK_END) {			avi_info->video_end = TRUE;		}#ifdef _DEBUG		if (avi_info->currentAudioIndex != -1) {			diffPTS  = (RMint64) ((avi_info->videoPTS * 1000) / avi_info->vopTimeIncrementResolution);#if DONT_SCALE_AUDIO_PTS			diffPTS -= (RMint64) ((avi_info->audio_info[avi_info->currentAudioIndex].audioPTS * 1000) / avi_info->audio_info[avi_info->currentAudioIndex].audioTimeScale);#else			diffPTS -= (RMint64) ((avi_info->audio_info[avi_info->currentAudioIndex].real_audio_pts * 1000) / avi_info->audio_info[avi_info->currentAudioIndex].audio_base);#endif		}#endif		if (play_opt->send_video)			avi_info->sendVideoData = TRUE;	}	else if ((chunkid[2] == 'w') && (chunkid[3] == 'b')){		RMint32 streamID;		RMuint32 i;		RMDBGLOG((AVIDBG, "RECEIVED AUDIO CHUNK (size = %lu)!!!\n", chunkLength));		isAudio = TRUE;				streamID = (chunkid[0]-'0')*10+chunkid[1]-'0';		for (i=0 ; i<avi_info->audio_stream_count ; i++) {			if (streamID == avi_info->audio_info[i].streamID)				break;		}				if (i == avi_info->audio_stream_count) {			RMDBGLOG((ENABLE, "Invalid audio chunk ID %ld\n", streamID));			return;		}		if (avi_info->audio_info[i].skipBogusAudioChunk){			RMDBGLOG((AVIDBG, "Skip Bogus MP3 frame\n"));			if (flags & RMAVI_FLAG_CHUNK_END)				avi_info->audio_info[i].skipBogusAudioChunk = FALSE;			return;		}		err = dump_data_into_file(play_opt, RMVDEMUX_AUDIO, chunk, chunkLength, 0, FALSE, FALSE);		if (err != RM_OK) {			RMDBGLOG((ENABLE, "Cannot dump audio \n"));		}		Info.TimeStamp = avi_info->audio_info[i].audioPTS;		// scale PTS to audio_base		if (avi_info->audio_info[i].audioTimeScale) {			RMuint64 pts = Info.TimeStamp;			if (pts < 0x8000000000000000ll) {				pts *= avi_info->audio_info[i].audio_base;				pts /= avi_info->audio_info[i].audioTimeScale;			}			else {				pts /= avi_info->audio_info[i].audioTimeScale;				pts *= avi_info->audio_info[i].audio_base;			}#if DONT_SCALE_AUDIO_PTS			RMDBGLOG((DISABLE, "should have scaled pts %llu with %lu/%lu => %llu\n",				  Info.TimeStamp,				  avi_info->audio_info[i].audio_base,				  avi_info->audio_info[i].audioTimeScale,				  pts));#else			RMDBGLOG((DISABLE, "scale pts %llu with %lu/%lu => %llu\n",				  Info.TimeStamp,				  avi_info->audio_info[i].audio_base,				  avi_info->audio_info[i].audioTimeScale,				  pts));			Info.TimeStamp = pts;#endif			// we have to store it for the diffPTS when processing video payload			avi_info->audio_info[i].real_audio_pts = Info.TimeStamp;		}#ifdef _DEBUG		if (avi_info->currentAudioIndex != -1) {			diffPTS  = (RMint64) ((avi_info->videoPTS * 1000) / avi_info->vopTimeIncrementResolution);#if DONT_SCALE_AUDIO_PTS			diffPTS -= (RMint64) ((avi_info->audio_info[avi_info->currentAudioIndex].audioPTS * 1000) / avi_info->audio_info[avi_info->currentAudioIndex].audioTimeScale);#else			diffPTS -= (RMint64) ((Info.TimeStamp * 1000) / avi_info->audio_info[avi_info->currentAudioIndex].audio_base);#endif		}#endif		avi_info->audio_info[i].audioByteCounter += chunkLength;				if (flags & RMAVI_FLAG_CHUNK_START){			avi_info->audio_info[i].audioFrameCounter++;			Info.ValidFields = (play_opt->send_audio_pts) ? TIME_STAMP_INFO : 0;						if (avi_info->audio_info[i].audio_VBR){				/* Some streams have junk audio chunks at the beginning, skip them (see				 * Sweet.Home.Alabama.DVDRip.avi). A junk chunk size is always a multiple of nBlockAlign,				 * it is filled with zeros (another thing we chould check, but it would be slower) */				if (chunkLength % avi_info->audio_info[i].audioFormat.nBlockAlign == 0){					RMDBGLOG((ENABLE,"Discard junk audio chunk (%ld frames)\n", chunkLength / avi_info->audio_info[i].audioFormat.nBlockAlign));					if (!(flags & RMAVI_FLAG_CHUNK_END))						avi_info->audio_info[i].skipBogusAudioChunk = TRUE;					avi_info->audio_info[i].audioPTS += chunkLength;					return;				} else 					avi_info->audio_info[i].audioPTS += avi_info->audio_info[i].audioFormat.nBlockAlign;			}		}				if (!avi_info->audio_info[i].audio_VBR){			avi_info->audio_info[i].audioPTS = ((RMuint64)(avi_info->audio_info[i].audioByteCounter) * avi_info->audio_info[i].audioTimeScale) / avi_info->audio_info[i].audioFormat.nAvgBytesPerSec;		}		if (streamID!=(RMint32) avi_info->currentAudioStream) 			return;		/* compute PTS but do not send data */ 		if ((FSMstate != RM_PSM_Playing) && (FSMstate != RM_PSM_Paused) && (FSMstate != RM_PSM_Prebuffering)) 			return;		if (avi_info->dcc_info->pMultipleAudioSource) {			struct DCCAudioSourceHandle audioHandle;			/* get only first decoder */			DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(avi_info->dcc_info->pMultipleAudioSource, 0, &audioHandle);			decoder = audioHandle.moduleID; //avi_info->dcc_info->audio_decoder;			RMDBGLOG((AVIDBG, "Audio PTS=%llu byte count = %ld\n", avi_info->audio_info[i].audioPTS, avi_info->audio_info[i].audioByteCounter));		}		if ((!avi_info->need_audio_au) || (flags & RMAVI_FLAG_CHUNK_START)) 			avi_info->sendAudioData = TRUE;	}	else if ((chunkid[2] == 'd') && (chunkid[3] == 'd')){		RMDBGLOG((AVIDBG, "RECEIVED DRM CHUNK !!!\n"));		return;	}	else {		RMDBGLOG((DISABLE, "UNKNOWN CHUNK %c%c%c%c\n",chunkid[0], chunkid[1], chunkid[2], chunkid[3]));		return;	}#ifdef _DEBUG	if ((play_opt->send_audio) && (play_opt->send_video)) {		if (diffPTS > avi_info->max_diff) {			avi_info->max_diff = diffPTS;			if (FSMstate == RM_PSM_Playing) {				RMDBGLOG((ENABLE, "[V-A] %ld ms\n", (RMint32) diffPTS));			}		}		else if (diffPTS < avi_info->min_diff) {			avi_info->min_diff = diffPTS;			if (FSMstate == RM_PSM_Playing) {				RMDBGLOG((ENABLE, "[V-A] %ld ms\n", (RMint32) diffPTS));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -