示例#1
0
文件: audio_muxer.c 项目: erelh/gpac
int dc_audio_muxer_write(AudioOutputFile * p_aoutf, int i_frame_nb) {

	//GF_Err ret;
	switch (p_aoutf->muxer_type) {

	case FFMPEG_AUDIO_MUXER:
		return dc_ffmpeg_audio_muxer_write(p_aoutf);
	case GPAC_AUDIO_MUXER:
	case GPAC_INIT_AUDIO_MUXER:
		if (i_frame_nb % p_aoutf->i_frame_per_frag == 0) {
			gf_isom_start_fragment(p_aoutf->p_isof, 1);

			gf_isom_set_traf_base_media_decode_time(p_aoutf->p_isof, 1,
					p_aoutf->i_first_dts * p_aoutf->i_frame_size);
			p_aoutf->i_first_dts += p_aoutf->i_frame_per_frag;
		}
		dc_gpac_audio_isom_write(p_aoutf);
		if (i_frame_nb % p_aoutf->i_frame_per_frag
				== p_aoutf->i_frame_per_frag - 1) {
			gf_isom_flush_fragments(p_aoutf->p_isof, 1);
		}
		if(i_frame_nb + 1 == p_aoutf->i_frame_per_seg)
			return 1;
		return 0;
	default:
		return GF_BAD_PARAM;
	};

	return GF_BAD_PARAM;
}
示例#2
0
int dc_audio_muxer_write(AudioOutputFile *audio_output_file, int frame_nb, Bool insert_ntp)
{
	switch (audio_output_file->muxer_type) {
	case FFMPEG_AUDIO_MUXER:
		return dc_ffmpeg_audio_muxer_write(audio_output_file);
#ifndef GPAC_DISABLE_ISOM
	case GPAC_AUDIO_MUXER:
	case GPAC_INIT_AUDIO_MUXER:
		if (frame_nb % audio_output_file->frame_per_frag == 0) {
			gf_isom_start_fragment(audio_output_file->isof, 1);
			
			if (insert_ntp) {
				gf_isom_set_fragment_reference_time(audio_output_file->isof, 1, audio_output_file->frame_ntp, audio_output_file->first_dts * audio_output_file->codec_ctx->frame_size);
			}

			gf_isom_set_traf_base_media_decode_time(audio_output_file->isof, 1, audio_output_file->first_dts * audio_output_file->codec_ctx->frame_size);
			audio_output_file->first_dts += audio_output_file->frame_per_frag;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio start fragment first DTS %d at "LLU"\n", audio_output_file->first_dts, gf_net_get_utc() ));
		}
		dc_gpac_audio_isom_write(audio_output_file);
		if (frame_nb % audio_output_file->frame_per_frag == audio_output_file->frame_per_frag - 1) {
			gf_isom_flush_fragments(audio_output_file->isof, 1);
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio flush fragment first DTS %d at "LLU"\n", audio_output_file->first_dts, gf_net_get_utc() ));
		}
		//TODO - do same as video, flush based on time in case of losses
		if (frame_nb + 1 == audio_output_file->frame_per_seg) {
			return 1;
		}

		return 0;
#endif

	default:
		return GF_BAD_PARAM;
	}
	return GF_BAD_PARAM;
}
示例#3
0
文件: video_muxer.c 项目: Bevara/GPAC
int dc_video_muxer_write(VideoOutputFile *video_output_file, int frame_nb, Bool insert_utc)
{
	u64 frame_dur;
	GF_Err ret;
	switch (video_output_file->muxer_type) {
	case FFMPEG_VIDEO_MUXER:
		return dc_ffmpeg_video_muxer_write(video_output_file);
	case RAW_VIDEO_H264:
		return dc_raw_h264_write(video_output_file);
	case GPAC_VIDEO_MUXER:
	case GPAC_INIT_VIDEO_MUXER_AVC1:
	case GPAC_INIT_VIDEO_MUXER_AVC3:
		if (video_output_file->use_source_timing) {
			if (!video_output_file->fragment_started) {
				video_output_file->fragment_started = 1;
				ret = gf_isom_start_fragment(video_output_file->isof, 1);
				if (ret < 0)
					return -1;

				video_output_file->first_dts = video_output_file->codec_ctx->coded_frame->pkt_dts;
				if (!video_output_file->segment_started) {
					u32 sec, frac;
					u64 ntpts;
					video_output_file->pts_at_segment_start = video_output_file->codec_ctx->coded_frame->pts;
					video_output_file->segment_started = 1;

					if (insert_utc) {
						gf_net_get_ntp(&sec, &frac);
						ntpts = sec;
						ntpts <<= 32;
						ntpts |= frac;
						gf_isom_set_fragment_reference_time(video_output_file->isof, video_output_file->trackID, ntpts, video_output_file->pts_at_segment_start);
					}
				}
				gf_isom_set_traf_base_media_decode_time(video_output_file->isof, video_output_file->trackID, video_output_file->first_dts);
			}

			//keep track of previous frame dur and use last dur as the default duration for next sample
			//this works fine because we perform frame rate regulation at the capture stage
			frame_dur = video_output_file->codec_ctx->coded_frame->pts - video_output_file->last_pts;
			if (frame_dur && (video_output_file->frame_dur>(u32) frame_dur)) {
				GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("New frame dur detected: %d vs %d old\n", (u32) frame_dur, (u32) video_output_file->frame_dur));
				video_output_file->frame_dur = (u32)frame_dur;
			}

			if (dc_gpac_video_isom_write(video_output_file) < 0) {
				return -1;
			}
			video_output_file->last_pts = video_output_file->codec_ctx->coded_frame->pts;
			video_output_file->last_dts = video_output_file->codec_ctx->coded_frame->pkt_dts;

			if (( video_output_file->last_dts - video_output_file->first_dts + video_output_file->frame_dur) /video_output_file->timescale >= video_output_file->frag_dur / 1000) {
				gf_isom_flush_fragments(video_output_file->isof, 1);
				video_output_file->fragment_started = 0;
				GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Flushed fragment to disk at UTC "LLU" ms - last coded frame PTS %d\n", gf_net_get_utc(), video_output_file->codec_ctx->coded_frame->pts));
			}

			//we may have rounding errors on the input PTS :( add half frame dur safety
			if (1000 * ( video_output_file->last_pts - video_output_file->pts_at_segment_start + 3*video_output_file->frame_dur/2) /video_output_file->timescale >= video_output_file->seg_dur ) {
				return 1;
			}
			return 0;
		}

		if (frame_nb % video_output_file->frame_per_fragment == 0) {
			gf_isom_start_fragment(video_output_file->isof, 1);

			if (!video_output_file->segment_started) {
				u32 sec, frac;
				u64 ntpts;

				video_output_file->pts_at_segment_start = video_output_file->codec_ctx->coded_frame->pts;
				video_output_file->segment_started = 1;

				if (insert_utc) {
					time_t secs;
					struct tm t;
					gf_net_get_ntp(&sec, &frac);
					ntpts = sec;
					ntpts <<= 32;
					ntpts |= frac;
					gf_isom_set_fragment_reference_time(video_output_file->isof, video_output_file->trackID, ntpts, video_output_file->pts_at_segment_start);

					secs = sec - GF_NTP_SEC_1900_TO_1970;
					t = *gmtime(&secs);
					GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Producer reference clock: Timestamp %d matches sender NTP time %d-%02d-%02dT%02d:%02d:%02dZ (NTP frac part %u) \n", (u32) video_output_file->pts_at_segment_start, 1900+t.tm_year, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, (u32) frac ));

				}
			}


			gf_isom_set_traf_base_media_decode_time(video_output_file->isof, video_output_file->trackID, video_output_file->first_dts);
			video_output_file->first_dts += video_output_file->frame_per_fragment;
		}

		dc_gpac_video_isom_write(video_output_file);

		if (frame_nb % video_output_file->frame_per_fragment == video_output_file->frame_per_fragment - 1) {
			gf_isom_flush_fragments(video_output_file->isof, 1);
			GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Flushed fragment to disk at UTC "LLU" ms - last coded frame PTS %d\n", gf_net_get_utc(), video_output_file->codec_ctx->coded_frame->pts));
		}

		if (frame_nb + 1 == video_output_file->frame_per_segment)
			return 1;

		return 0;
	default:
		return -2;
	}

	return -2;
}