Beispiel #1
0
int CFfmpeg::Seek(int64_t pos)
{
	int ret;
	double rate;
      int64_t seek_target;
	pthread_mutex_lock(&iolock);
	if(transcode)
	{
		rate = ((double)pos)/((double)filesize);
		seek_target = infmt_ctx->duration * rate;
		FFMPEG_DEBUG("rate=%f, target = %lld, duration=%lld", rate, seek_target, infmt_ctx->duration);
		int defaultStreamIndex = av_find_default_stream_index(infmt_ctx);
		seek_target = av_rescale_q(seek_target, AV_TIME_BASE_Q, infmt_ctx->streams[defaultStreamIndex]->time_base);
		ret = av_seek_frame(infmt_ctx, defaultStreamIndex, seek_target, AVSEEK_FLAG_ANY);
		FFMPEG_DEBUG("ret = %s", ret_str(ret));
	      eof= 0;
		if(curpos > pos)
		{
			if(vst)
				vdts_base = vst->cur_dts;
			if(ast1)
				a1dts_base = ast1->cur_dts;
			if(ast2)
				a2dts_base = ast2->cur_dts;
		}
		outputringbuffer.data_ptr = outputringbuffer.buffer_base;
		outputringbuffer.data_size = 0;
	}
	else
	{
		ret = fseek(m_pFp, pos, SEEK_SET);
		if(ret == 0)
		{
			curpos = pos;
		}
		FFMPEG_DEBUG("pos=%lld, m_nCurpos=%lld", pos, curpos);
	}
	pthread_mutex_unlock(&iolock);
	return 0;
}
int ffsox_source_seek(source_t *n, int64_t ts)
{
  AVStream *st;
  int si;

  if (0ll<ts) {
    si=av_find_default_stream_index(n->f.fc);
    st=n->f.fc->streams[si];
    ts=av_rescale_q(ts,AV_TIME_BASE_Q,st->time_base);

    if (avformat_seek_file(n->f.fc,si,INT64_MIN,ts,INT64_MAX,0)<0) {
      DMESSAGE("seeking");
      goto seek;
    }

    n->ts=av_rescale_q(st->cur_dts,st->time_base,AV_TIME_BASE_Q);
  }

  return 0;
seek:
  return -1;
}
Beispiel #3
0
static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
{
	AVFormatContext *format_context = demuxer->format_context;
	unsigned int i;
	AVStream *audio_stream = NULL;
	AVStream *video_stream = NULL;
	int64_t start_time = INT64_MAX;

	for (i = 0; i < format_context->nb_streams; i++) {
		AVCodecContext *codec = format_context->streams[i]->codec;

		if (codec->codec_type == AVMEDIA_TYPE_VIDEO && !video_stream)
			video_stream = format_context->streams[i];

		if (codec->codec_type == AVMEDIA_TYPE_AUDIO && !audio_stream)
			audio_stream = format_context->streams[i];
	}

	int default_stream_index = av_find_default_stream_index(
			demuxer->format_context);

	if (default_stream_index >= 0) {
		AVStream *stream =
				format_context->streams[default_stream_index];

		if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
			demuxer->clock.sync_type = AV_SYNC_AUDIO_MASTER;
		else if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
			demuxer->clock.sync_type = AV_SYNC_VIDEO_MASTER;
	}

	if (video_stream != NULL)
		find_decoder(demuxer, video_stream);

	if (audio_stream != NULL)
		find_decoder(demuxer, audio_stream);

	if (demuxer->video_decoder == NULL && demuxer->audio_decoder == NULL) {
		return false;
	}

	if (!set_clock_sync_type(demuxer)) {
		return false;
	}

	for (i = 0; i < format_context->nb_streams; i++) {
		AVStream *st = format_context->streams[i];
		int64_t st_start_time;

		if (st->discard == AVDISCARD_ALL ||
		    st->start_time == AV_NOPTS_VALUE) {
			continue;
		}

		st_start_time = av_rescale_q(st->start_time, st->time_base,
				AV_TIME_BASE_Q);
		start_time = FFMIN(start_time, st_start_time);
	}

	if (format_context->start_time != AV_NOPTS_VALUE) {
		if (start_time > format_context->start_time ||
		    start_time == INT64_MAX) {
			start_time = format_context->start_time;
		}
	}

	if (start_time != INT64_MAX) {
		set_decoder_start_time(demuxer->video_decoder, start_time);
		set_decoder_start_time(demuxer->audio_decoder, start_time);
	}

	if (demuxer->audio_decoder != NULL) {
		if (ff_callbacks_initialize(&demuxer->audio_callbacks)) {
			ff_decoder_start(demuxer->audio_decoder);
		} else {
			ff_decoder_free(demuxer->audio_decoder);
			demuxer->audio_decoder = NULL;
			if (!set_clock_sync_type(demuxer))
				return false;
		}
	}

	if (demuxer->video_decoder != NULL) {
		if (ff_callbacks_initialize(&demuxer->video_callbacks)) {
			ff_decoder_start(demuxer->video_decoder);
		} else {
			ff_decoder_free(demuxer->video_decoder);
			demuxer->video_decoder = NULL;
			if (!set_clock_sync_type(demuxer))
				return false;
		}
	}

	return set_clock_sync_type(demuxer);
}
Beispiel #4
0
static
int cmf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
{
    av_log(NULL, AV_LOG_INFO, "\n------- cmf read_seek:BEGAN stream_index=%d ,sample_time=%lld,flags=%d --------\n\n", stream_index, sample_time, flags);
    struct cmf *cmf = s->priv_data;
    struct cmfvpb *ci = cmf->cmfvpb ;
    int ret;
    int64_t remain_seektime;
    int64_t seektimestamp;
    AVStream *st;

    av_log(NULL, AV_LOG_INFO, "cmf read_seek:TOTALINFO  index[%lld] total_num [%lld] total_duration [%lld] \n",ci->cur_index,ci->total_num, ci->total_duration);
    av_log(NULL, AV_LOG_INFO, "cmf read_seek:SIZEINFO    index[%lld] start_offset [0x%llx] end_offset [0x%llx] slice_size[0x%llx] \n", ci->cur_index, ci->start_offset, ci->end_offset, ci->size);
    av_log(NULL, AV_LOG_INFO, "cmf read_seek:TIMEINFO    index[%lld] start_time [%lld]ms end_time [%lld]ms curslice_duration[%lld]ms \n", ci->cur_index, ci->start_time, ci->end_time, ci->curslice_duration);
    
     if(stream_index < 0){
        stream_index= av_find_default_stream_index(s);
        if(stream_index < 0)
            return -1;
    }

    st= s->streams[stream_index];
    
    seektimestamp=av_rescale_rnd(sample_time,st->time_base.num*1000,st->time_base.den,AV_ROUND_ZERO);//pts->ms
    
    av_log(s, AV_LOG_INFO, "cmf read_seek: checkin pts [%lld] seektimestamp[%lld]ms streamindex [%d]\n",sample_time,seektimestamp,stream_index);
              
    if ((seektimestamp >= ci->start_time)&&(seektimestamp <= ci->end_time )){
        //in cur slice;
        av_log(s, AV_LOG_INFO, "cmf read_seek:IN CUR SLICE realtime = [%lld]ms  start-end [%lld-%lld] calctoend[%lld]ms\n",seektimestamp,ci->start_time,ci->end_time,ci->end_time-seektimestamp);
        seektimestamp = seektimestamp - ci->start_time;
        seektimestamp = seektimestamp*1000;//ms->us
        av_log(NULL, AV_LOG_INFO, "cmf read_seek:index[%lld] curduration[%lld] seektimestamp[%lld]us\n", ci->cur_index, ci->curslice_duration,seektimestamp);
        ret = av_seek_frame(cmf->sctx, stream_index, seektimestamp, flags);
        if (ret < 0) {
            av_log(s, AV_LOG_INFO, "cmf read_seek:av_seek_frame Failed in cur slice\n");
        }
    }else if ((seektimestamp < ci->start_time)||(seektimestamp > ci->end_time )){
        av_log(s, AV_LOG_INFO, "cmf read_seek:OUT_CUR_SLICE firstcheck seektimestamp[%lld]ms  start-end [%lld---%lld]ms\n",seektimestamp,ci->start_time,ci->end_time);
        //out of cur slice and in the total slice;
        //seek to cur slice;

        ret = url_fseekslicebytime(cmf->cmfvpb->pb,seektimestamp, AVSEEK_SLICE_BYTIME);
        if (ret < 0){
            av_log(s, AV_LOG_INFO, "cmf read_seek: seekbytime error seektimestamp[%lld]ms\n",seektimestamp);
            return -1;
        }
        cmfvpb_getinfo(ci,AVCMD_SLICE_INDEX,0,&ci->cur_index);
        cmfvpb_getinfo(ci, AVCMD_SLICE_START_OFFSET, 0, &ci->start_offset); 
        cmfvpb_getinfo(ci, AVCMD_SLICE_SIZE, 0 , &ci->size);
        cmfvpb_getinfo(ci, AVCMD_SLICE_STARTTIME, 0 , &ci->start_time);
        cmfvpb_getinfo(ci, AVCMD_SLICE_ENDTIME, 0 , &ci->end_time);

        ci->end_offset = ci->start_offset + ci->size;
        ci->curslice_duration=ci->end_time-ci->start_time;
        
        cmf->parsering_index = ci->cur_index;
        remain_seektime = seektimestamp - ci->start_time;
        cmf_flush_packet_queue(cmf->sctx);
        cmf_reset_packet(&cmf->pkt);
        av_log(s, AV_LOG_INFO, "cmf read_seek:OUT_CUR_SLICE switchtoincurindex index[%lld] seektimestamp[%lld]ms start-end [%lld--%lld]ms  remainseektime[%lld]ms\n",ci->cur_index,seektimestamp,ci->start_time,ci->end_time,remain_seektime);
        ret = cmf_parser_next_slice(s, cmf->parsering_index, 0);
        if (ret>=0) {
             av_log(s, AV_LOG_INFO, "cmf read_seek:switchto incurindex index[%lld] seektimestamp[%lld]ms starttime[%lld]ms endtime[%lld]ms remainseektime[%lld]ms\n",ci->cur_index,seektimestamp,ci->start_time,ci->end_time,remain_seektime);
            //parser succeed,seek in cur slice;
             remain_seektime=remain_seektime*1000;//ms->us;
             av_log(s, AV_LOG_INFO, "cmf read_seek:switchto incurindex:  index[%lld] remain_seektime[%lld]ms  start-end [%lld - %lld]ms calctoend[%lld]\n",ci->cur_index,remain_seektime/1000,ci->start_time,ci->end_time,(ci->end_time-seektimestamp));
             //seek to remainseektime;
             ret = av_seek_frame(cmf->sctx, stream_index, remain_seektime, flags);
            if (ret < 0) {
                av_log(s, AV_LOG_INFO, "cmf read_seek:out_curslice av_seek_frame Failed out of cur slice , cur_slice index [%lld]\n",ci->cur_index);
                return -1;
            }
        }else{
             av_log(s, AV_LOG_INFO, "cmf parser_next_slice failed %s---%d  [%d]\n",__FUNCTION__,__LINE__,ret);
             return -1;
        }
    }else if (seektimestamp > s->duration/1000){
          av_log(s, AV_LOG_INFO, "cmf read_seek CMFSEEKERROR out of the total slice [%lld] [%lld]\n",seektimestamp,s->duration/1000);
          return -1;
        //out of total slice;
    }else {
        av_log(NULL, AV_LOG_INFO, "cmf read_seek CMFSEEKERROR index[%lld] start_time [%lld] end_time [%lld] curduration[%lld] seektimestamp[%lld]us\n", ci->cur_index, ci->start_time, ci->end_time, ci->curslice_duration,seektimestamp);
        return -1;
    }
    av_log(NULL, AV_LOG_INFO, "\n------cmf read_seek:END    index[%lld] start_time [%lld]ms end_time [%lld]ms curslice_duration[%lld]ms -------\n\n", ci->cur_index, ci->start_time, ci->end_time, ci->curslice_duration);
    return 0;
}