Ejemplo n.º 1
0
//returns the first pts found within TIME_STAMP_PROBE_LEN bytes after stream_pos in demuxer's stream.
//if no pts is found or an error occurs, -1.0 is returned.
//Packs are freed.
static float read_first_mpeg_pts_at_position(demuxer_t* demuxer, off_t stream_pos)
{
  stream_t *s = demuxer->stream;
  mpg_demuxer_t *mpg_d = demuxer->priv;
  float pts = -1.0; //the pts to return;
  float found_pts1; //the most recently found pts
  float found_pts2; //the pts found before found_pts1
  float found_pts3; //the pts found before found_pts2
  int found = 0;

  if(!mpg_d || stream_pos < 0)
    return pts;

  found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts;
  stream_seek(s, stream_pos);

  //We look for pts.
  //However, we do not stop at the first found one, as timestamps may reset
  //Therefore, we seek until we found three consecutive
  //pts within MAX_PTS_DIFF_FOR_CONSECUTIVE.

  while(found<3 && !s->eof
   && (fabsf(found_pts2-found_pts1) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
   && (fabsf(found_pts3-found_pts2) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
   && (stream_tell(s) < stream_pos + TIMESTAMP_PROBE_LEN)
   && ds_fill_buffer(demuxer->video))
  {
    if(mpg_d->last_pts != found_pts1)
    {
      if(!found)
        found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts; //the most recently found pts
      else
      {
        found_pts3 = found_pts2;
        found_pts2 = found_pts1;
        found_pts1 = mpg_d->last_pts;
      }
      found++;
    }
  }

  if(found == 3) pts = found_pts3;

  //clean up from searching of first pts;
  ds_free_packs(demuxer->audio);
  ds_free_packs(demuxer->video);
  ds_free_packs(demuxer->sub);

  return pts;
}
static void demux_isdbt_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
{
        demux_stream_t *d_audio=demuxer->audio;
	demux_stream_t *d_video=demuxer->video;
	demux_stream_t *d_sub=demuxer->sub;
	sh_audio_t *sh_audio=d_audio->sh;
	sh_video_t *sh_video=d_video->sh;
	//================= seek in isdbt ==========================
//	ts_dump_streams(demuxer->priv);
//	reset_fifos(priv, sh_audio != NULL, sh_video != NULL, demuxer->sub->id > 0);
	demuxer->stream_pts=cur_ts;
       	LOGE("seek from demux!--------------------\n"); 
  	if(sh_audio != NULL)
		ds_free_packs(d_audio);
	if(sh_video != NULL)
		ds_free_packs(d_video);
	if(demuxer->sub->id > 0)
		ds_free_packs(d_sub);
}
//This is an almost verbatim copy of high_res_mp3_seek(), from demux_audio.c
static void demux_aac_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
{
	aac_priv_t *priv = (aac_priv_t *) demuxer->priv;
	demux_stream_t *d_audio=demuxer->audio;
	sh_audio_t *sh_audio=d_audio->sh;
	float time;

	ds_free_packs(d_audio);

	time = (flags & SEEK_ABSOLUTE) ? rel_seek_secs - priv->last_pts : rel_seek_secs;
	if(time < 0)
	{
		stream_seek(demuxer->stream, demuxer->movi_start);
		time = priv->last_pts + time;
		priv->last_pts = 0;
	}

	if(time > 0)
	{
		int len, nf, srate, num;

		nf = time * sh_audio->samplerate/1024;

		while(nf > 0)
		{
			if(stream_read(demuxer->stream,priv->buf, 8) < 8)
				break;
			len = aac_parse_frame(priv->buf, &srate, &num);
			if(len <= 0)
			{
				stream_skip(demuxer->stream, -7);
				continue;
			}
			stream_skip(demuxer->stream, len - 8);
			priv->last_pts += (float) (num*1024.0/srate);
			nf -= num;
		}
	}
}
Ejemplo n.º 4
0
static void demux_seek_aac_adif(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
{
  aac_adif_priv_t *priv = (aac_adif_priv_t *) demuxer->priv;
  demux_stream_t *d_audio=demuxer->audio;
  sh_audio_t *sh_audio=d_audio->sh;
  float time;
  unsigned int frame_len;

  //  frame_len = (1024 / priv->srate) * (priv->bitrate/8);
  //  frame_len = ((1024 * priv->bitrate * 4) / (8 * 44100));
  frame_len = ((1024.0 * 16.0) / (float) priv->srate) * ((float) priv->bitrate/8.0);

  ds_free_packs(d_audio);

  time = (flags & 1) ? rel_seek_secs :  priv->last_pts + rel_seek_secs;
  if(time < 0) 
  {
    stream_seek(demuxer->stream, demuxer->movi_start);
    time = priv->last_pts + time;
    priv->last_pts = 0;
  }
  if(time > 0)
  {
    float fltpos;
    int pos;
    fltpos = time * (priv->bitrate/8);
    pos = (int) fltpos;
    pos /= frame_len;
    pos *= frame_len;
    pos += priv->hdrlen;

    if (pos > demuxer->movi_end) pos = demuxer->movi_end;
    stream_seek(demuxer->stream, pos);
  }

  //  sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len)/(float)priv->bitrate; // FIXME - ????
}
Ejemplo n.º 5
0
static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
{
    lavf_priv_t *priv = demuxer->priv;

    switch (cmd) {
        case DEMUXER_CTRL_CORRECT_PTS:
	    return DEMUXER_CTRL_OK;
        case DEMUXER_CTRL_GET_TIME_LENGTH:
	    if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
	        return DEMUXER_CTRL_DONTKNOW;

	    *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
	    return DEMUXER_CTRL_OK;

	case DEMUXER_CTRL_GET_PERCENT_POS:
	    if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
	        return DEMUXER_CTRL_DONTKNOW;

	    *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);
	    return DEMUXER_CTRL_OK;
	case DEMUXER_CTRL_SWITCH_AUDIO:
	case DEMUXER_CTRL_SWITCH_VIDEO:
	{
	    int id = *((int*)arg);
	    int newid = -2;
	    int i, curridx = -1;
	    int nstreams, *pstreams;
	    demux_stream_t *ds;

	    if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
	    {
	        ds = demuxer->video;
	        nstreams = priv->video_streams;
	        pstreams = priv->vstreams;
	    }
	    else
	    {
	        ds = demuxer->audio;
	        nstreams = priv->audio_streams;
	        pstreams = priv->astreams;
	    }
	    for(i = 0; i < nstreams; i++)
	    {
	        if(pstreams[i] == ds->id) //current stream id
	        {
	            curridx = i;
	            break;
	        }
	    }

            if(id == -2) { // no sound
                i = -1;
            } else if(id == -1) { // next track
                i = (curridx + 2) % (nstreams + 1) - 1;
                if (i >= 0)
                    newid = pstreams[i];
	    }
	    else // select track by id
	    {
	        if (id >= 0 && id < nstreams) {
	            i = id;
	            newid = pstreams[i];
	        }
	    }
	    if(i == curridx)
	        return DEMUXER_CTRL_NOTIMPL;
	    else
	    {
	        ds_free_packs(ds);
	        if(ds->id >= 0)
	            priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
	        *((int*)arg) = ds->id = newid;
	        if(newid >= 0)
	            priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
	        return DEMUXER_CTRL_OK;
	    }
        }
        case DEMUXER_CTRL_IDENTIFY_PROGRAM:
        {
            demux_program_t *prog = arg;
            AVProgram *program;
            int p, i;
            int start;

            prog->vid = prog->aid = prog->sid = -2;	//no audio and no video by default
            if(priv->avfc->nb_programs < 1)
                return DEMUXER_CTRL_DONTKNOW;

            if(prog->progid == -1)
            {
                p = 0;
                while(p<priv->avfc->nb_programs && priv->avfc->programs[p]->id != priv->cur_program)
                    p++;
                p = (p + 1) % priv->avfc->nb_programs;
            }
            else
            {
                for(i=0; i<priv->avfc->nb_programs; i++)
                    if(priv->avfc->programs[i]->id == prog->progid)
                        break;
                if(i==priv->avfc->nb_programs)
                    return DEMUXER_CTRL_DONTKNOW;
                p = i;
            }
            start = p;
redo:
            program = priv->avfc->programs[p];
            for(i=0; i<program->nb_stream_indexes; i++)
            {
                switch(priv->avfc->streams[program->stream_index[i]]->codec->codec_type)
                {
                    case AVMEDIA_TYPE_VIDEO:
                        if(prog->vid == -2)
                            prog->vid = program->stream_index[i];
                        break;
                    case AVMEDIA_TYPE_AUDIO:
                        if(prog->aid == -2)
                            prog->aid = program->stream_index[i];
                        break;
                    case AVMEDIA_TYPE_SUBTITLE:
                        if(prog->sid == -2)
                            prog->sid = program->stream_index[i];
                        break;
                }
            }
            if (prog->aid >= 0 && prog->aid < MAX_A_STREAMS &&
                demuxer->a_streams[prog->aid]) {
                sh_audio_t *sh = demuxer->a_streams[prog->aid];
                prog->aid = sh->aid;
            } else
                prog->aid = -2;
            if (prog->vid >= 0 && prog->vid < MAX_V_STREAMS &&
                demuxer->v_streams[prog->vid]) {
                sh_video_t *sh = demuxer->v_streams[prog->vid];
                prog->vid = sh->vid;
            } else
                prog->vid = -2;
            if(prog->progid == -1 && prog->vid == -2 && prog->aid == -2)
            {
                p = (p + 1) % priv->avfc->nb_programs;
                if (p == start)
                    return DEMUXER_CTRL_DONTKNOW;
                goto redo;
            }
            priv->cur_program = prog->progid = program->id;
            return DEMUXER_CTRL_OK;
        }
	default:
	    return DEMUXER_CTRL_NOTIMPL;
    }
}
Ejemplo n.º 6
0
static void ASFThread(Context_t *context)
{
#ifdef DEBUG
	printf("%s::%s\n", FILENAME, __FUNCTION__);
#endif

	while (context->playback->isCreationPhase)
	{
#ifdef DEBUG
		printf("%s::%s Thread waiting for end of init phase...\n", FILENAME, __FUNCTION__);
#endif
	}

#ifdef DEBUG
	printf("%s::%s Running!\n", FILENAME, __FUNCTION__);
#endif

	while (context && context->playback && context->playback->isPlaying)
	{
		//printf("%s -->\n", __FUNCTION__);

		//IF MOVIE IS PAUSED, WAIT
		if (context->playback->isPaused)
		{
#ifdef DEBUG
			printf("%s::%s paused\n", FILENAME, __FUNCTION__);
#endif
			usleep(100000);
			continue;
		}

		if (context->playback->isSeeking || whileSeeking)
		{
#ifdef DEBUG
			printf("%s::%s seeking\n", FILENAME, __FUNCTION__);
#endif
			usleep(100000);
			continue;
		}

		//getASFMutex(FILENAME, __FUNCTION__,__LINE__);



		if (!demux_asf_fill_buffer(ds->demuxer, ds))
		{
#ifdef DEBUG
			printf("%s::%s demux_asf_fill_buffer failed!\n", FILENAME, __FUNCTION__);
#endif
			//releaseASFMutex(FILENAME, __FUNCTION__,__LINE__);

			break;
		}
		else
		{
			ASFGenerateParcel(context, ds->demuxer);
			if (ds->demuxer->sub != NULL && ds->demuxer->sub->first != NULL)
			{
				ds_free_packs(ds->demuxer->sub);
			}

			/* Dont free the packs, as the fragments would be deleted
			if (ds->demuxer->audio != NULL && ds->demuxer->audio->first != NULL) {
				ds_free_packs(ds->demuxer->audio);
			}

			if (ds->demuxer->video != NULL && ds->demuxer->video->first != NULL) {
				ds_free_packs(ds->demuxer->video);
			}
			*/

			//releaseASFMutex(FILENAME, __FUNCTION__,__LINE__);
		}
	}

	hasPlayThreadStarted = 0;	// prevent locking situation when calling PLAYBACK_TERM

	context->playback->Command(context, PLAYBACK_TERM, NULL);

#ifdef DEBUG
	printf("%s::%s terminating\n", FILENAME, __FUNCTION__);
#endif
}
Ejemplo n.º 7
0
static void free_demuxer_stream(struct demux_stream *ds)
{
    ds_free_packs(ds);
    free(ds);
}
Ejemplo n.º 8
0
void demux_flush(demuxer_t *demuxer)
{
    ds_free_packs(demuxer->video);
    ds_free_packs(demuxer->audio);
    ds_free_packs(demuxer->sub);
}
Ejemplo n.º 9
0
static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
{
    lavf_priv_t *priv = demuxer->priv;
    
    switch (cmd) {
        case DEMUXER_CTRL_GET_TIME_LENGTH:
	    if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
	        return DEMUXER_CTRL_DONTKNOW;
	    
	    *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
	    return DEMUXER_CTRL_OK;

	case DEMUXER_CTRL_GET_PERCENT_POS:
	    if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
	        return DEMUXER_CTRL_DONTKNOW;
	    
	    *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);
	    return DEMUXER_CTRL_OK;
	case DEMUXER_CTRL_SWITCH_AUDIO:
	case DEMUXER_CTRL_SWITCH_VIDEO:
	{
	    int id = *((int*)arg);
	    int newid = -2;
	    int i, curridx = -2;
	    int nstreams, *pstreams;
	    demux_stream_t *ds;

	    if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
	    {
	        ds = demuxer->video;
	        nstreams = priv->video_streams;
	        pstreams = priv->vstreams;
	    }
	    else
	    {
	        ds = demuxer->audio;
	        nstreams = priv->audio_streams;
	        pstreams = priv->astreams;
	    }
	    if(ds->id == -2)
	        return DEMUXER_CTRL_NOTIMPL;
	    for(i = 0; i < nstreams; i++)
	    {
	        if(pstreams[i] == ds->id) //current stream id
	        {
	            curridx = i;
	            break;
	        }
	    }

	    if(id < 0)
	    {
	        i = (curridx + 1) % nstreams;
	        newid = pstreams[i];
	    }
	    else
	    {
	        for(i = 0; i < nstreams; i++)
	        {
		    if(pstreams[i] == id)
		    {
		        newid = id;
		        break;
		    }
	        }
	    }
	    if(newid == -2 || i == curridx)
	        return DEMUXER_CTRL_NOTIMPL;
	    else
	    {
	        ds_free_packs(ds);
	        priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
	        *((int*)arg) = ds->id = newid;
	        priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
	        return DEMUXER_CTRL_OK;
	    }
        }
	default:
	    return DEMUXER_CTRL_NOTIMPL;
    }
}
Ejemplo n.º 10
0
static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
{
    lavf_priv_t *priv = demuxer->priv;
    
    switch (cmd) {
        case DEMUXER_CTRL_GET_TIME_LENGTH:
	    if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
	        return DEMUXER_CTRL_DONTKNOW;
	    
	    *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
	    return DEMUXER_CTRL_OK;

	case DEMUXER_CTRL_GET_PERCENT_POS:
	    if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
	        return DEMUXER_CTRL_DONTKNOW;
	    
	    *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);
	    return DEMUXER_CTRL_OK;
	case DEMUXER_CTRL_SWITCH_AUDIO:
	case DEMUXER_CTRL_SWITCH_VIDEO:
	{
	    int id = *((int*)arg);
	    int newid = -2;
	    int i, curridx = -2;
	    int nstreams, *pstreams;
	    demux_stream_t *ds;

	    if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
	    {
	        ds = demuxer->video;
	        nstreams = priv->video_streams;
	        pstreams = priv->vstreams;
	    }
	    else
	    {
	        ds = demuxer->audio;
	        nstreams = priv->audio_streams;
	        pstreams = priv->astreams;
	    }
	    if(id == -2)
	    {
	        if(ds->id >= 0)
	            priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
	        ds_free_packs(ds);
	        *((int*)arg) = ds->id = -2;
	        return DEMUXER_CTRL_OK;
	    } 
	    for(i = 0; i < nstreams; i++)
	    {
	        if(pstreams[i] == ds->id) //current stream id
	        {
	            curridx = i;
	            break;
	        }
	    }

	    if(id < 0)
	    {
	        i = (curridx + 1) % nstreams;
	        newid = pstreams[i];
	    }
	    else
	    {
	        for(i = 0; i < nstreams; i++)
	        {
		    if(pstreams[i] == id)
		    {
		        newid = id;
		        break;
		    }
	        }
	    }
	    if(i == curridx)
	        return DEMUXER_CTRL_NOTIMPL;
	    else
	    {
	        ds_free_packs(ds);
	        if(ds->id >= 0)
	            priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
	        *((int*)arg) = ds->id = newid;
	        if(newid >= 0)
	            priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
	        return DEMUXER_CTRL_OK;
	    }
        }
        case DEMUXER_CTRL_IDENTIFY_PROGRAM:
        {
            demux_program_t *prog = arg;
            AVProgram *program;
            int p, i;

            if(priv->avfc->nb_programs < 2)
                return DEMUXER_CTRL_NOTIMPL;

            if(prog->progid == -1)
            {
                p = 0;
                while(p<priv->avfc->nb_programs && priv->avfc->programs[p]->id != priv->cur_program)
                    p++;
                p = (p + 1) % priv->avfc->nb_programs;
            }
            else
            {
                for(i=0; i<priv->avfc->nb_programs; i++)
                    if(priv->avfc->programs[i]->id == prog->progid)
                        break;
                if(i==priv->avfc->nb_programs)
                    return DEMUXER_CTRL_NOTIMPL;
                p = i;
            }
            prog->vid = prog->aid = prog->sid = -2;	//no audio and no video by default
redo:
            program = priv->avfc->programs[p];
            for(i=0; i<program->nb_stream_indexes; i++)
            {
                switch(priv->avfc->streams[program->stream_index[i]]->codec->codec_type)
                {
                    case CODEC_TYPE_VIDEO:
                        if(prog->vid == -2)
                            prog->vid = program->stream_index[i];
                        break;
                    case CODEC_TYPE_AUDIO:
                        if(prog->aid == -2)
                            prog->aid = program->stream_index[i];
                        break;
                    case CODEC_TYPE_SUBTITLE:
                        if(prog->sid == -2 && priv->avfc->streams[program->stream_index[i]]->codec->codec_id == CODEC_ID_TEXT)
                            prog->sid = program->stream_index[i];
                        break;
                }
            }
            if(prog->progid == -1 && prog->vid == -2 && prog->aid == -2)
            {
                p = (p + 1) % priv->avfc->nb_programs;
                goto redo;
            }
            priv->cur_program = prog->progid = program->id;
            return DEMUXER_CTRL_OK;
        }
	default:
	    return DEMUXER_CTRL_NOTIMPL;
    }
}