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

📄 play_mp4.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
			goto mainloop_noseek;				\		case LABEL_START_SENDING_DATA:				\			goto start_sending_data;			\		case LABEL_SIGNAL_EOS_AND_EXIT:				\			goto signal_EOS_and_exit_loop;			\		case LABEL_NONE:					\			RMDBGLOG((ENABLE, "warning unrecognised key pressed\n"));\			break;						\		}							\	}								\} while(0)#define ADTS_HEADER_SIZE 7static RMuint32 FindAdtsSRIndex(RMuint32 sr){	const RMuint32 adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};	RMuint32 i;		for (i = 0; i < 16; i++) {		if (sr == adts_sample_rates[i])			return i;	}	return 0xf;}static void FillAdtsHeader(RMuint8 *buf, RMuint32 framesize, RMuint32 samplerate, RMuint32 channelcount, RMuint32 objectID){	RMuint32 profile = (objectID - 1) & 0x3;	RMuint32 sr_index = FindAdtsSRIndex(samplerate);	framesize += ADTS_HEADER_SIZE;  /* add adts header size */	buf[0] = 0xFF; /* 8b: syncword */	buf[1] = 0xF1; /* 4b: syncword */	               /* 1b: mpeg id = 0 */	               /* 2b: layer = 0 */	               /* 1b: protection absent = 1 */		buf[2] = ((profile << 6) & 0xC0);  /* 2b: profile */	buf[2] += ((sr_index << 2) & 0x3C); /* 4b: sampling_frequency_index */	                                    /* 1b: private = 0 */	buf[2] += ((channelcount >> 2) & 0x1); /* 1b: channel_configuration */		buf[3] = ((channelcount << 6) & 0xC0); /* 2b: channel_configuration */	/* 1b: original = 0 */	/* 1b: home = 0 */	/* 1b: copyright_id = 0 */	/* 1b: copyright_id_start = 0 */	buf[3] += ((framesize >> 11) & 0x3); /* 2b: aac_frame_length */		buf[4] = ((framesize >> 3) & 0xFF); /* 8b: aac_frame_length */		buf[5] = ((framesize << 5) & 0xE0); /* 3b: aac_frame_length */	buf[5] += ((0x7FF >> 6) & 0x1F); /* 5b: adts_buffer_fullness */		buf[6] = ((0x7FF << 2) & 0xFC); /* 6b: adts_buffer_fullness */	/* 2b: num_raw_buf_blocks  = 0 */}/* prototypes */static RMuint64 round_int_div(RMuint64 numerator, RMuint32 divisor);static RMstatus mp4_select_audio_track(struct SendMP4DataContext *pSendContext, RMuint32 index);static RMstatus mp4_select_spu_track(struct SendMP4DataContext *pSendContext, RMuint32 index);static RMstatus mp4_select_subtitle_track(struct SendMP4DataContext *pSendContext, RMuint32 index);static void get_buffer(struct SendMP4DataContext *pSendContext, RMuint8 **buf);RMuint64 round_int_div(RMuint64 numerator, RMuint32 divisor) {	RMuint64 temp;	temp = numerator / divisor;	if ((numerator % divisor) * 2 > divisor)		temp++;	return temp;}static RMstatus init_private_options(struct priv_cmdline *options){	options->audio_track = 0;	options->internal_file_open = 0;	options->monitorFIFOs = FALSE;	#ifdef WITH_MONO	options->spuEnabled = TRUE;	options->subtitlesEnabled = TRUE;#else	options->spuEnabled = FALSE;	options->subtitlesEnabled = FALSE;#endif	return RM_OK;}#ifndef WITH_MONOstatic RMstatus parse_private_cmdline(struct SendMP4DataContext *pSendContext, int argc, char **argv, int *index, struct priv_cmdline *options){	RMstatus err = RM_PENDING;	int i = *index;	if (! strcmp(argv[i], "-at")) {		if (argc > i+1) {			options->audio_track = strtol(argv[i+1], NULL, 10);			i+=2;			err = RM_OK;		}		else			err = RM_ERROR;	} else if ( ! strcmp(argv[i], "-fopen")) {		if (argc > i+1) {			options->internal_file_open = strtol(argv[i+1], NULL, 10);			i+=2;			err = RM_OK;		}		else			err = RM_ERROR;	}	else if ( ! strcmp(argv[i], "-monitor")) {		options->monitorFIFOs = TRUE;		err = RM_OK;		i++;	}	else if ( ! strcmp(argv[i], "-subt")) {		options->subtitlesEnabled = TRUE;		err = RM_OK;		i++;	}		*index = i;		return err;}static void show_private_options(void){	fprintf(stderr, 		"MP4 OPTIONS (default values inside brackets)\n"		"\t-at track: Selects audio track number track [0]\n"		"\t-spu enable SPU (if present)\n"		"\t-subt enable Subtitles (if present)\n"		"\t-fopen <0|1>: use internal file open [0]\n");}static void show_usage(char *progname){	show_private_options();	show_playback_options();	show_display_options();	show_video_options();	show_audio_options();	fprintf(stderr, 		"--------------------------------\n"		"Minimum cmd line: %s <file name>\n"		"--------------------------------\n", 		progname);	exit(1);}static void parse_cmdline(struct SendMP4DataContext *pSendContext, int argc, char *argv[], RMuint32 *currentAudioInstance){	int i;	RMstatus err;	if (argc < 2) 		show_usage(argv[0]);		i = 1;	while ((argc > i)) {		if (argv[i][0] != '-') {			if (pSendContext->play_opt->filename == NULL) {				pSendContext->play_opt->filename = argv[i];				i++;			}			else				show_usage(argv[0]);		}		else {			err = parse_private_cmdline(pSendContext, argc, argv, &i, &(pSendContext->priv_opt));			if (err == RM_ERROR)				show_usage(argv[0]);			if (err != RM_PENDING)				continue;			err = parse_playback_cmdline(argc, argv, &i, pSendContext->play_opt);			if (err == RM_ERROR) 				show_usage(argv[0]);			if (err != RM_PENDING)				continue;			err = parse_display_cmdline(argc, argv, &i, pSendContext->disp_opt);			if (err == RM_ERROR) 				show_usage(argv[0]);			if (err != RM_PENDING)				continue;			err = parse_video_cmdline(argc, argv, &i, pSendContext->video_opt);			if (err == RM_ERROR) 				show_usage(argv[0]);			if (err != RM_PENDING)				continue;			RMDBGLOG((ENABLE, "option[%lu] %s\n", i, argv[i]));			err = parse_audio_cmdline2(argc, argv, &i, pSendContext->audio_opt, MAX_AUDIO_DECODER_INSTANCES, currentAudioInstance);			if (RMFAILED(err))				show_usage(argv[0]);		}	}	if (pSendContext->play_opt->filename == NULL)		show_usage(argv[0]);}#endif //WITH_MONOstatic void check_prebuf_state(struct SendMP4DataContext * pSendContext, RMuint32 buffersize);static RMstatus WaitForEOS(struct SendMP4DataContext *pSendContext, struct RM_PSM_Actions *pActions){	RMuint32 eos_bit_field = 0;	enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(pSendContext->PSMcontext, &(pSendContext->dcc_info));	if (pSendContext == NULL || pActions == NULL)		return RM_ERROR;		if (pSendContext->SendVideoData) 		eos_bit_field |= EOS_BIT_FIELD_VIDEO;	if (pSendContext->SendAudioData && 	    ((PlaybackStatus == RM_PSM_Playing) ||	     (PlaybackStatus == RM_PSM_Prebuffering)))		eos_bit_field |= EOS_BIT_FIELD_AUDIO;		return WaitForEOSWithCommand(pSendContext->PSMcontext, &(pSendContext->dcc_info), pActions, eos_bit_field);}static RMstatus init_MP4_tracks(struct SendMP4DataContext *pSendContext){	RMuint32 videotrackID = 0;	RMstatus status;	RMDBGLOG((ENABLE, "initTracks\n"));#if 0	if (!pSendContext->play_opt->send_video) {		pSendContext->isAudioOnly = TRUE;		pSendContext->videoTracks = 0;		goto init_audio_track;	}#endif	pSendContext->videoTracks = RMGetMP4NumberOfVideoTracks(pSendContext->mp4c);	RMDBGLOG((ENABLE, "found %lu video tracks\n", pSendContext->videoTracks));	if (pSendContext->videoTracks > 0) {		/* so far, all files have only one video track, init the first video track found */		RMDBGLOG((ENABLE, "init mp4 video track\n"));		pSendContext->currentVideoTrack = 1;		pSendContext->mp4tV = (ExternalRMmp4Track) NULL;		videotrackID = RMGetMP4VideoTrackID(pSendContext->mp4c);		pSendContext->videodsiBuf = (RMuint8 *) NULL;		if (videotrackID > 0) {			RMmpeg4TrackType type;			pSendContext->mp4tV = RMOpenMP4Track(pSendContext->mp4c, videotrackID);			if (!pSendContext->mp4tV) {				RMDBGLOG((ENABLE, "couldnt open track!\n"));				goto disable_video;			}			RMDBGLOG((ENABLE, "video track ID is %lu\n", videotrackID));			RMGetMP4TrackWidth(pSendContext->mp4tV, &(pSendContext->videoWidth));			RMGetMP4TrackHeight(pSendContext->mp4tV, &(pSendContext->videoHeight));			pSendContext->videoWidth >>= 16;			pSendContext->videoHeight >>= 16;			RMDBGLOG((ENABLE, ">> video size %lu x %lu\n", pSendContext->videoWidth, pSendContext->videoHeight));			RMGetMP4TrackType(pSendContext->mp4tV, &type);			if (type == RM_VIDEO_H264_TRACK)				pSendContext->isH264 = TRUE;			else if (type == RM_VIDEO_MPEG4_TRACK)				pSendContext->isH264 = FALSE;			else {				RMDBGLOG((ENABLE, "unknown video!!\n"));				goto disable_video;			}			if (pSendContext->isH264) {				RMuint32 level, profile, lengthSize;				RMDBGLOG((ENABLE, ">> video track is H264\n"));				RMGetH264Level(pSendContext->mp4tV, &level);				RMGetH264Profile(pSendContext->mp4tV, &profile);				RMGetH264LengthSize(pSendContext->mp4tV, &lengthSize);				pSendContext->h264LengthSize = lengthSize;				RMDBGLOG((ENABLE, "level %lu, profile %lu, lengthSize %lu\n", level, profile, lengthSize));				if (level > 41) {					fprintf(stderr, "unsupported level, level %lu > max 41\n", level);					goto disable_video;				}				if (profile > 100) {					fprintf(stderr, "unsupported profile, profile %lu > max 100\n", profile);					goto disable_video;				}#ifdef WITH_MONO				RMDBGLOG((ENABLE, ">> set codec to H264 HD\n"));				pSendContext->video_opt->MPEGProfile = Profile_H264_HD;				pSendContext->video_opt->Codec = VideoDecoder_Codec_H264_HD;#endif			}			else {				RMDBGLOG((ENABLE, ">> video track is MPEG4\n"));#ifdef WITH_MONO				RMDBGLOG((ENABLE, ">> set codec to MPEG4\n"));				pSendContext->video_opt->MPEGProfile = Profile_MPEG4_HD;				pSendContext->video_opt->Codec = VideoDecoder_Codec_MPEG4_HD;#endif			}						pSendContext->videodsiBuf = RMGetMP4TrackDSI(pSendContext->mp4tV, &(pSendContext->videodsiSize));			RMDBGLOG((ENABLE, "got %lu bytes of video DSI, parsing...\n", pSendContext->videodsiSize));			if (pSendContext->videodsiSize > (RMuint32) (1<<pSendContext->dmaBufferSizeLog2)) {				RMDBGLOG((ENABLE, "video DSI too big!!\n"));				goto disable_video;			}			else if (pSendContext->videodsiSize == 0) {				RMDBGLOG((ENABLE, "video DSI size is zero!!\n"));				goto disable_video;			}						pSendContext->VideoCTSTimeScale = RMGetMP4TrackTimeScale(pSendContext->mp4tV);						switch (pSendContext->video_opt->MPEGProfile){			case Profile_FIRST_:			case Profile_LAST_:				break;							case Profile_MPEG2_SD:			case Profile_MPEG2_DVD:			case Profile_MPEG2_HD:			case Profile_MPEG2_SD_Packed:			case Profile_MPEG2_HD_Packed:			case Profile_MPEG2_DVD_Packed:			case Profile_MPEG2_SD_DeInt:			case Profile_MPEG2_DVD_DeInt:			case Profile_MPEG2_HD_DeInt:			case Profile_MPEG2_SD_Packed_DeInt:			case Profile_MPEG2_DVD_Packed_DeInt:			case Profile_MPEG2_HD_Packed_DeInt:				RMDBGLOG((ENABLE, "MPEG 2 video\n"));				pSendContext->video_vop_tir = 90000;				break;						case Profile_DIVX3_SD:			case Profile_DIVX3_HD:			case Profile_DIVX3_SD_Packed:			case Profile_DIVX3_HD_Packed:				RMDBGLOG((ENABLE, "DIVX3 video\n"));				pSendContext->video_vop_tir = pSendContext->VideoCTSTimeScale;				break;			case Profile_WMV_SD:			case Profile_WMV_816P:			case Profile_WMV_HD:				RMDBGLOG((ENABLE, "WMV9 video\n"));				pSendContext->video_vop_tir = 1000;				break;			case Profile_MPEG4_SD:			case Profile_MPEG4_HD:			case Profile_MPEG4_SD_Packed:			case Profile_MPEG4_HD_Packed:			case Profile_MPEG4_SD_DeInt:			case Profile_MPEG4_HD_DeInt:			case Profile_MPEG4_SD_Packed_DeInt:			case Profile_MPEG4_HD_Packed_DeInt:			case Profile_MPEG4_SD_Padding:			case Profile_MPEG4_HD_Padding:			case Profile_MPEG4_SD_DeInt_Padding:			case Profile_MPEG4_HD_DeInt_Padding:				RMDBGLOG((ENABLE, "MPEG4 video\n"));				ParseMP4VideoDSI(pSendContext->videodsiBuf, pSendContext->videodsiSize, (void *) &pSendContext->video_vop_tir, sizeof(RMuint32));				break;			case Profile_VC1_SD:			case Profile_VC1_HD:				RMDBGLOG((ENABLE, "VC1 video\n"));				pSendContext->video_vop_tir = pSendContext->VideoCTSTimeScale;				break;						case Profile_H264_SD:			case Profile_H264_HD:			case Profile_H264_SD_DeInt:			case Profile_H264_HD_DeInt:				RMDBGLOG((ENABLE, "H264 video\n"));				pSendContext->video_vop_tir = pSendContext->VideoCTSTimeScale;				break;			}					RMDBGLOG((ENABLE,"********** video VOP TIR %lu, VideoCTSTimeScale %lu\n", pSendContext->video_vop_tir, pSendContext->VideoCTSTimeScale));			if (!pSendContext->video_vop_tir) {				RMDBGLOG((ENABLE, "video_vop_tir = 0!!, reset to VideoCTSTimeScale\n"));				pSendContext->video_vop_tir = pSendContext->VideoCTSTimeScale;			}		}		else			goto disable_video;	}	else {	disable_video:		RMDBGLOG((ENABLE, ">> no video\n"));		pSendContext->SendVideoData = FALSE;		pSendContext->isAudioOnly = TRUE;		pSendContext->currentVideoTrack = 0;		if (pSendContext->mp4tV) {			RMDBGLOG((ENABLE, "closing video track\n"));			RMCloseMP4Track(pSendContext->mp4c, pSendContext->mp4tV);			pSendContext->mp4tV = (ExternalRMmp4Track) NULL;		}	}		// continue with other tracks#if 0	if (!pSendContext->play_opt->send_audio)		goto init_spu_track;#endif	RMDBGLOG((ENABLE, "init mp4 audio track(s)\n"));	pSendContext->mp4tA = (ExternalRMmp4Track) NULL;

⌨️ 快捷键说明

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