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

📄 play_mp4.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
	pSendContext->audioTracks = RMGetMP4NumberOfAudioTracks(pSendContext->mp4c);	RMDBGLOG((ENABLE, "found %lu audio tracks\n", pSendContext->audioTracks));	if (pSendContext->audioTracks > 0) {		RMuint32 i;		pSendContext->currentAudioTrack = 0;		if (pSendContext->priv_opt.audio_track) {			RMDBGLOG((ENABLE, "open audio track %lu from cmdline\n", pSendContext->priv_opt.audio_track));			status = mp4_select_audio_track(pSendContext, pSendContext->priv_opt.audio_track);			if (status == RM_OK) {				pSendContext->currentAudioTrack = pSendContext->priv_opt.audio_track;				goto init_spu_track;			}			else {				RMDBGLOG((ENABLE, "cant select audio track %lu\n", pSendContext->priv_opt.audio_track));				goto disable_audio;			}		}					for (i = 1; i <= pSendContext->audioTracks; i++) {			// init the first working audio track			status = mp4_select_audio_track(pSendContext, i);			if (status != RM_OK)				RMDBGLOG((ENABLE, "cant select audio track %lu, skipping!\n", i));			else {				pSendContext->currentAudioTrack = i;				break;			}		}		if (pSendContext->currentAudioTrack != i) {		disable_audio:			// all audio tracks failed init, disable audio			RMDBGLOG((ENABLE, "all audio tracks failed init, disabling audio\n"));			pSendContext->SendAudioData = FALSE;			pSendContext->isAudioOnly = FALSE;			pSendContext->currentAudioTrack = 0;			if (pSendContext->mp4tA) {				RMDBGLOG((ENABLE, "closing audio track\n"));				RMCloseMP4Track(pSendContext->mp4c, pSendContext->mp4tA);				pSendContext->mp4tA = (ExternalRMmp4Track) NULL;			}		}	}	else {		RMDBGLOG((ENABLE, ">> no audio\n"));		pSendContext->SendAudioData = FALSE;		pSendContext->isAudioOnly = FALSE;		pSendContext->currentAudioTrack = 0;	} init_spu_track:	pSendContext->mp4tSPU = (ExternalRMmp4Track) NULL;	pSendContext->currentSPUTrack = 0;	pSendContext->spuTracks = RMGetMP4NumberOfSPUTracks(pSendContext->mp4c);	RMDBGLOG((ENABLE, "found %lu spu tracks\n", pSendContext->spuTracks));#ifdef WITHOUT_NERO_SPU	pSendContext->spuTracks = 0;#endif // WITHOUT_NERO_SPU	if ((pSendContext->priv_opt.spuEnabled) && (pSendContext->spuTracks)) {		RMuint32 i;		pSendContext->enableSPU = TRUE;		pSendContext->displaySPU = TRUE;				for (i = 1; i <= pSendContext->spuTracks; i++) {			// init the first working spu track			status = mp4_select_spu_track(pSendContext, i);			if (status != RM_OK)				RMDBGLOG((ENABLE, "cant select spu track %lu, skipping!\n", i));			else {				pSendContext->currentSPUTrack = i;				break;			}		}		if (pSendContext->currentSPUTrack != i) {			// all spu tracks failed init, disable spu			RMDBGLOG((ENABLE, "all spu tracks failed init, disabling spu\n"));			pSendContext->SendSPUData = FALSE;			pSendContext->spuTracks = 0;			pSendContext->enableSPU = FALSE;			if (pSendContext->mp4tSPU) {				RMDBGLOG((ENABLE, "closing spu track\n"));				RMCloseMP4Track(pSendContext->mp4c, pSendContext->mp4tSPU);				pSendContext->mp4tSPU = (ExternalRMmp4Track) NULL;			}		}	}	/* init Subtitle track */	pSendContext->mp4tSubT = (ExternalRMmp4Track) NULL;	pSendContext->currentSubtitleTrack = 0;		pSendContext->subtitleTracks = RMGetMP4NumberOfSubtitleTracks(pSendContext->mp4c);	RMDBGLOG((ENABLE, "found %lu subtitle tracks\n", pSendContext->subtitleTracks));	// disable subtitles to match Nero's behaviour (Nero Digital for Windows doesnt show subtitles, only SPU)	pSendContext->subtitleTracks = 0;	if ((pSendContext->priv_opt.subtitlesEnabled) && (pSendContext->subtitleTracks)) {		RMuint32 i;		pSendContext->enableSubtitles = TRUE;		if (!pSendContext->displaySPU)			pSendContext->displaySubtitles = TRUE;		for (i = 1; i <= pSendContext->subtitleTracks; i++) {			// init the first working subtitle track			status = mp4_select_subtitle_track(pSendContext, i);			if (status != RM_OK)				RMDBGLOG((ENABLE, "cant select subtitle track %lu, skipping!\n", i));			else {				pSendContext->currentSubtitleTrack = i;				break;			}		}		if (pSendContext->currentSubtitleTrack != i) {			// all subtitle tracks failed init, disable subtitles			RMDBGLOG((ENABLE, "all subtitle tracks failed init, disabling subtitles\n"));			pSendContext->subtitleTracks = 0;			pSendContext->enableSubtitles = FALSE;			if (pSendContext->mp4tSubT) {				RMDBGLOG((ENABLE, "closing subtitle track\n"));				RMCloseMP4Track(pSendContext->mp4c, pSendContext->mp4tSubT);				pSendContext->mp4tSubT = (ExternalRMmp4Track) NULL;			}		}	}	/* exit */	if ((pSendContext->audioTracks == 0) && (pSendContext->videoTracks == 0))		return RM_ERROR;	RMDBGLOG((ENABLE, "initTracks done, video %lu(of %lu), audio %lu(of %lu), spu %lu(of %lu), subtitle %lu(of %lu)\n",		  pSendContext->currentVideoTrack,		  pSendContext->videoTracks,		  pSendContext->currentAudioTrack,		  pSendContext->audioTracks,		  pSendContext->currentSPUTrack,		  pSendContext->spuTracks,		  pSendContext->currentSubtitleTrack,		  pSendContext->subtitleTracks));	return RM_OK;}/* for audio and spu (spu has a dsisize=64 always, is the palette) */#define MAX_DSI_SIZE 64 static RMstatus mp4_select_audio_track(struct SendMP4DataContext *pSendContext, RMuint32 index){	RMuint32 audiotrackID = 0;	RMstatus status;	ExternalRMmp4Track newTrack;	if (index > pSendContext->audioTracks)		return RM_ERROR;	if (index == pSendContext->currentAudioTrack)		return RM_OK;	status = RMGetMP4AudioTrackIDByIndex(pSendContext->mp4c, index, &audiotrackID);	if (status != RM_OK) {		RMDBGLOG((ENABLE, "cant get id for audio track %lu!\n", index));		return status;	}	if (audiotrackID > 0) { 		RMuint8 *dsibuf;		RMuint32 dsisize;		RMuint8 tempdsi[MAX_DSI_SIZE];		RMuint32 samplerate, channels;		RMuint8 objID;		RMmpeg4TrackType type;		RMDBGLOG((ENABLE, "selecting audio track %lu, id %lu\n", index, audiotrackID));		newTrack = RMOpenMP4Track(pSendContext->mp4c, audiotrackID);		if (!newTrack) {			RMDBGLOG((ENABLE, "couldnt open track!\n"));			return RM_ERROR;		}		RMGetMP4TrackType(newTrack, &type);				if (type == RM_AUDIO_AAC_TRACK) {					RMDBGLOG((ENABLE, ">> AAC audio\n"));			dsibuf = RMGetMP4TrackDSI(newTrack, &dsisize);						RMDBGLOG((ENABLE, "got %lu bytes of audio DSI, parsing...\n", dsisize));						if (dsibuf == NULL) {				RMDBGLOG((ENABLE, "audio DSI not present!\n"));#ifdef WITH_MONO				return RM_ERROR;#else				return RM_OK;#endif			}			else if (dsisize > MAX_DSI_SIZE) {				RMDBGLOG((ENABLE, "audio DSI too big!\n"));				return RM_ERROR;			}			else if (dsisize == 0) {				RMDBGLOG((ENABLE, "audio DSI has size zero!!\n"));				return RM_ERROR;			}			/* copy the DSI in case we overwite it during parsing */			memcpy(tempdsi, dsibuf, dsisize);						ParseMP4AudioDSI(tempdsi, &dsisize, &samplerate, &channels, &objID);			pSendContext->audioSampleRate = samplerate;			pSendContext->AAC_SampleRateFromDSI = samplerate;			pSendContext->AAC_ChannelsFromDSI = channels;			pSendContext->AAC_ObjectIDFromDSI = objID;			pSendContext->isAACaudioPayload = TRUE;		}		else if (type == RM_AUDIO_AC3_TRACK) {			RMDBGLOG((ENABLE, ">> AC3 audio\n"));			pSendContext->isAACaudioPayload = FALSE;			RMGetMP4TrackSampleRate(newTrack, &(pSendContext->audioSampleRate));			RMDBGLOG((ENABLE, "sample rate %lu\n", pSendContext->audioSampleRate));		}		else {			fprintf(stderr, "unknown audio!\n");						if (newTrack) {				RMDBGLOG((ENABLE, "closing audio track\n"));				RMCloseMP4Track(pSendContext->mp4c, newTrack);			}			return RM_ERROR;		}					if (pSendContext->mp4tA) {			RMDBGLOG((ENABLE, "audio track already open, closing\n"));			RMCloseMP4Track(pSendContext->mp4c, pSendContext->mp4tA);		}		pSendContext->mp4tA = newTrack;		pSendContext->audio_vop_tir = AUDIO_BASE;		pSendContext->AudioCTSTimeScale = RMGetMP4TrackTimeScale(pSendContext->mp4tA);		RMDBGLOG((ENABLE, "********** audio VOP TIR %ld, AudioCTSTimeScale %ld\n", pSendContext->audio_vop_tir, pSendContext->AudioCTSTimeScale));	} 	else		return RM_ERROR;	#ifdef WITH_MONO	{		RMuint32 i;		RMDBGLOG((ENABLE, "setup audio parameters for this track\n"));		for (i = 0; i < pSendContext->audioInstances; i++) {			RMmpeg4TrackType type;						RMGetMP4TrackType(pSendContext->mp4tA, &type);						if (type == RM_AUDIO_AAC_TRACK) {				RMDBGLOG((ENABLE, ">> set audio codec[%lu] to AAC\n", i));				pSendContext->audio_opt[i].Codec = AudioDecoder_Codec_AAC;				pSendContext->audio_opt[i].AACParams.InputFormat = 1;				pSendContext->audio_opt[i].AACParams.OutputChannels = Aac_LR;			}			else if (type == RM_AUDIO_AC3_TRACK) {				RMDBGLOG((ENABLE, ">> set audio codec[%lu] to AC3\n", i));				pSendContext->audio_opt[i].Codec = AudioDecoder_Codec_AC3;							}						if (!pSendContext->audio_opt[i].OutputChannelsExplicitAssign)				pSendContext->audio_opt[i].OutputChannels = Audio_Out_Ch_LR;					}	}#endif	return RM_OK;}static RMstatus mp4_select_spu_track(struct SendMP4DataContext *pSendContext, RMuint32 index){	RMuint32 sputrackID = 0;	RMstatus status;	ExternalRMmp4Track newTrack;	if (index > pSendContext->spuTracks)		return RM_ERROR;	if (index == pSendContext->currentSPUTrack)		return RM_OK;	status = RMGetMP4SPUTrackIDByIndex(pSendContext->mp4c, index, &sputrackID);	if (status != RM_OK) {		RMDBGLOG((ENABLE, "cant get id for spu track %lu!\n", index));		return status;	}	if (sputrackID > 0) { 		RMuint8 *dsibuf;		RMuint32 dsisize;				RMDBGLOG((ENABLE, "selecting spu track %lu, id %lu\n", index, sputrackID));		newTrack = RMOpenMP4Track(pSendContext->mp4c, sputrackID);		if (!newTrack) {			RMDBGLOG((ENABLE, "couldnt open track!\n"));			return RM_ERROR;		}		dsibuf = RMGetMP4TrackDSI(newTrack, &dsisize);		RMDBGLOG((ENABLE, "got %lu bytes of spu DSI\n", dsisize));		if (dsibuf == NULL) {			RMDBGLOG((ENABLE, "spu DSI not present!\n"));			return RM_ERROR;		}		else if (dsisize > MAX_DSI_SIZE) {			RMDBGLOG((ENABLE, "spu DSI too big!\n"));			return RM_ERROR;		}		else if (dsisize == 0) {			RMDBGLOG((ENABLE, "spu DSI has size zero!!\n"));			return RM_ERROR;		}		if (pSendContext->mp4tSPU) {			RMDBGLOG((ENABLE, "spu track already open, closing\n"));			RMCloseMP4Track(pSendContext->mp4c, pSendContext->mp4tSPU);		}		pSendContext->mp4tSPU = newTrack;		RMGetMP4TrackWidth(pSendContext->mp4tSPU, &(pSendContext->spuWidth));		RMGetMP4TrackHeight(pSendContext->mp4tSPU, &(pSendContext->spuHeight));		// we must do this in order to find the right value (but it is not in nero specification)		pSendContext->spuWidth >>= 16;		pSendContext->spuHeight >>= 16;		RMDBGLOG((ENABLE, "spu is %lu x %lu\n", pSendContext->spuWidth, pSendContext->spuHeight));		pSendContext->spuDSIBuf = dsibuf;		pSendContext->spuDSISize = dsisize;		pSendContext->spuCTSTimeScale = RMGetMP4TrackTimeScale(pSendContext->mp4tSPU);		RMDBGLOG((ENABLE, "spu timeScale %lu\n", pSendContext->spuCTSTimeScale));	} 	else		return RM_ERROR;	return RM_OK;}static RMstatus mp4_select_subtitle_track(struct SendMP4DataContext *pSendContext, RMuint32 index){	RMuint32 subtitletrackID = 0;	RMstatus status;	if (index > pSendContext->subtitleTracks)		return RM_ERROR;	if (index == pSendContext->currentSubtitleTrack)		return RM_OK;	status = RMGetMP4SubtitleTrackIDByIndex(pSendContext->mp4c, index, &subtitletrackID);	if (status != RM_OK) {		RMDBGLOG((ENABLE, "cant get id for subtitle track %lu!\n", index));		return status;	}	if (pSendContext->mp4tSubT) {		RMDBGLOG((ENABLE, "subtitle track already open, closing\n"));		RMCloseMP4Track(pSendContext->mp4c, pSendContext->mp4tSubT);		pSendContext->mp4tSubT = (ExternalRMmp4Track) NULL;	}	if (subtitletrackID > 0) {		RMDBGLOG((ENABLE, "selecting subtitle track %lu, id %lu\n", index, subtitletrackID));		pSendContext->mp4tSubT = RMOpenMP4Track(pSendContext->mp4c, subtitletrackID);		if (pSendContext->mp4tSubT == NULL) {			RMDBGLOG((ENABLE, "couldnt open subtitle track!!\n"));			return RM_ERROR;		}		pSendContext->subtCTSTimeScale = RMGetMP4TrackTimeScale(pSendContext->mp4tSubT);		RMDBGLOG((ENABLE, "subtitle timeScale %lu\n", pSendContext->subtCTSTimeScale));	} 	else		return RM_ERROR;	return RM_OK;}static RMstatus send_videoDSI(struct SendMP4DataContext * pSendContext){	RMuint32 i;	RMstatus status;	if (!pSendContext->sendVideoDSI) {		return RM_OK;	}	while (RUAGetBuffer(pSendContext->pDMA, &(pSendContext->videosample.buf),  COMMON_TIMEOUT_US) != RM_OK)		RMDBGLOG((ENABLE, "there are no free buffers for video DSI right now, retry later...\n"));	memcpy(pSendContext->videosample.buf, pSendContext->videodsiBuf, pSendContext->videodsiSize);		pSendContext->videosample.size = pSendContext->videodsiSize;	pSendContext->videosample.flags = 0;	pSendContext->video_Info.ValidFields = 0;	pSendContext->video_Info.TimeStamp = 0;	for (i = 0; i < pSendContext->videodsiSize; i++) {		RMDBGLOG((DISABLE, "videoDSI[%lu]=%02X\n", i, pSendContext->videodsiBuf[i]));	}	if (pSendContext->SendVideoData) {		while( RUASendData(pSendContext->pRUA, pSendContext->dcc_info->video_decoder, pSendContext->pDMA, 				   pSendContext->videosample.buf, 				   pSendContext->videosample.size, 				   &pSendContext->video_Info, sizeof(pSendContext->video_Info)) != RM_OK) {			RMDBGLOG((ENABLE, "waiting to send video DSI\n"));		}	}

⌨️ 快捷键说明

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