예제 #1
0
/**
 * \brief calc pts when switch audio track
 * \param audec pointer to audec
 * \return 0 on success otherwise -1
 *
 * When audio track switch occurred, use this function to judge audio should
 * be played or not. If system time fall behind audio pts , and their difference
 * is greater than SYSTIME_CORRECTION_THRESHOLD, auido should wait for
 * video. Otherwise audio can be played.
 */
int track_switch_pts(aml_audio_dec_t *audec)
{
    unsigned long vpts;
    unsigned long apts;
    unsigned long pcr;
    char buf[32];

    memset(buf, 0, sizeof(buf));

    pcr = audec->adsp_ops.get_cur_pcrscr(&audec->adsp_ops);
    if (pcr == -1) {
        adec_print("unable to get pcr");
        return 1;
    }

    apts = adec_calc_pts(audec);
    if (apts == -1) {
        adec_print("unable to get apts");
        return 1;
    }

    if((apts > pcr) && (apts - pcr > 0x100000))
        return 0;

    if (abs(apts - pcr) < audec->avsync_threshold || (apts <= pcr)) {
        return 0;
    } else {
        return 1;
    }

}
/**
 * \brief start pts manager
 * \param audec pointer to audec
 * \return 0 on success otherwise -1
 */
int adec_pts_start(aml_audio_dec_t *audec)
{
    unsigned long pts = 0;
    char *file;
    int fd;
    char buf[64];
    dsp_operations_t *dsp_ops;

    adec_print("adec_pts_start");
    dsp_ops = &audec->adsp_ops;
    memset(buf, 0, sizeof(buf));

    dsp_ops->last_pts_valid = 0;

    pts = adec_calc_pts(audec);
    if (pts == -1) {

        adec_print("pts==-1");

        fd = open(TSYNC_APTS, O_RDONLY);
        if (fd < 0) {
            adec_print("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
            return -1;
        }

        read(fd, buf, sizeof(buf));
        close(fd);
        if (sscanf(buf, "0x%lx", &pts) < 1) {
            adec_print("unable to get apts from: %s", buf);
            return -1;
        }
    }

    adec_print("audio pts start from 0x%lx", pts);

    fd = open(TSYNC_EVENT, O_WRONLY);
    if (fd < 0) {
        adec_print("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
        return -1;
    }

    sprintf(buf, "AUDIO_START:0x%lx", pts);
    write(fd, buf, strlen(buf));
    close(fd);

    return 0;
}
/**
 * \brief calc pts when switch audio track
 * \param audec pointer to audec
 * \return 0 on success otherwise -1
 *
 * When audio track switch occurred, use this function to judge audio should
 * be played or not. If system time fall behind audio pts , and their difference
 * is greater than SYSTIME_CORRECTION_THRESHOLD, auido should wait for
 * video. Otherwise audio can be played.
 */
int track_switch_pts(aml_audio_dec_t *audec)
{
    unsigned long vpts;
    unsigned long apts;
    unsigned long pcr;
    char buf[32];
    int fd = -1;

    memset(buf, 0, sizeof(buf));

    fd = open(TSYNC_PCRSCR, O_RDWR);
    if (fd < 0) {
        adec_print("unable to open file %s,err: %s", TSYNC_PCRSCR, strerror(errno));
        return 1;
    }

    read(fd, buf, sizeof(buf));
    close(fd);

    if (sscanf(buf, "0x%lx", &pcr) < 1) {
        adec_print("unable to get pcr %s", buf);
        close(fd);
        return 1;
    }

    apts = adec_calc_pts(audec);
    if (apts == -1) {
        close(fd);
        adec_print("unable to get apts");
        return 1;
    }

    if (abs(apts - pcr) < SYSTIME_CORRECTION_THRESHOLD || (apts <= pcr)) {
        return 0;
    } else {
        return 1;
    }

}
/**
 * \brief refresh current audio pts
 * \param audec pointer to audec
 * \return 0 on success otherwise -1
 */
int adec_refresh_pts(aml_audio_dec_t *audec)
{
    unsigned long pts;
    unsigned long systime;
    static unsigned long last_pts = -1;
    int fd;
    char buf[64];

    memset(buf, 0, sizeof(buf));

    /* get system time */
    fd = open(TSYNC_PCRSCR, O_RDWR);
    if (fd < 0) {
        adec_print("unable to open file %s,err: %s", TSYNC_PCRSCR, strerror(errno));
        return -1;
    }

    read(fd, buf, sizeof(buf));
    close(fd);

    if (sscanf(buf, "0x%lx", &systime) < 1) {
        adec_print("unable to getsystime %s", buf);
        close(fd);
        return -1;
    }

    /* get audio time stamp */
    pts = adec_calc_pts(audec);
    if (pts == -1 || last_pts == pts) {
        close(fd);
        if (pts == -1) {
            return -1;
        }
    }

    //adec_print("adec_get_pts() pts=%x\n",pts);

    if ((abs(pts - last_pts) > APTS_DISCONTINUE_THRESHOLD) && (audec->adsp_ops.last_pts_valid)) {
        /* report audio time interruption */
        adec_print("pts = %lx, last pts = %lx\n", pts, last_pts);

        fd = open(TSYNC_EVENT, O_RDWR);
        if (fd < 0) {
            adec_print("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
            return -1;
        }

        adec_print("audio time interrupt: 0x%lx->0x%lx, 0x%lx\n", last_pts, pts, abs(pts - last_pts));

        sprintf(buf, "AUDIO_TSTAMP_DISCONTINUITY:0x%lx", pts);
        write(fd, buf, strlen(buf));
        close(fd);

        last_pts = pts;
        audec->adsp_ops.last_pts_valid = 1;

        return 0;
    }

    last_pts = pts;
    audec->adsp_ops.last_pts_valid = 1;

    if (abs(pts - systime) < SYSTIME_CORRECTION_THRESHOLD) {
        return 0;
    }

    /* report apts-system time difference */
    fd = open(TSYNC_APTS, O_RDWR);
    if (fd < 0) {
        adec_print("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
        return -1;
    }

    adec_print("report apts as %ld,system pts=%ld, difference= %ld\n", pts, systime, (pts - systime));

    sprintf(buf, "0x%lx", pts);
    write(fd, buf, strlen(buf));
    close(fd);

    return 0;
}
예제 #5
0
/**
 * \brief start pts manager
 * \param audec pointer to audec
 * \return 0 on success otherwise -1
 */
int adec_pts_start(aml_audio_dec_t *audec)
{
    unsigned long pts = 0;
    char *file;
    char buf[64];
    dsp_operations_t *dsp_ops;
	char value[PROPERTY_VALUE_MAX]={0};

    adec_print("adec_pts_start");
    dsp_ops = &audec->adsp_ops;
    memset(buf, 0, sizeof(buf));

    if (audec->avsync_threshold <= 0) {
        if (am_getconfig_bool("media.libplayer.wfd")) {
            audec->avsync_threshold = SYSTIME_CORRECTION_THRESHOLD * 2 / 3;
            adec_print("use 2/3 default av sync threshold!\n");
        } else {
            audec->avsync_threshold = SYSTIME_CORRECTION_THRESHOLD;
            adec_print("use default av sync threshold!\n");
        }
    }
    adec_print("av sync threshold is %d , no_first_apts=%d,\n", audec->avsync_threshold, audec->no_first_apts);

    dsp_ops->last_pts_valid = 0;
    if(property_get("sys.amplayer.drop_pcm",value,NULL) > 0)
    	if(!strcmp(value,"1"))
    	     adec_pts_droppcm(audec);
    // before audio start or pts start
    if(amsysfs_set_sysfs_str(TSYNC_EVENT, "AUDIO_PRE_START") == -1)
    {
        return -1;
    }

    usleep(1000);

	if (audec->no_first_apts) {
		if (amsysfs_get_sysfs_str(TSYNC_APTS, buf, sizeof(buf)) == -1) {
			adec_print("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
			return -1;
		}

		if (sscanf(buf, "0x%lx", &pts) < 1) {
			adec_print("unable to get vpts from: %s", buf);
			return -1;
		}

	} else {
	    pts = adec_calc_pts(audec);

	    if (pts == -1) {

	        adec_print("pts==-1");

    		if (amsysfs_get_sysfs_str(TSYNC_APTS, buf, sizeof(buf)) == -1) {
    			adec_print("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
    			return -1;
    		}

	        if (sscanf(buf, "0x%lx", &pts) < 1) {
	            adec_print("unable to get apts from: %s", buf);
	            return -1;
	        }
	    }
	}

    adec_print("audio pts start from 0x%lx", pts);

    sprintf(buf, "AUDIO_START:0x%lx", pts);

    if(amsysfs_set_sysfs_str(TSYNC_EVENT, buf) == -1)
    {
        return -1;
    }

    return 0;
}
예제 #6
0
int adec_refresh_pts(aml_audio_dec_t *audec)
{
    unsigned long pts;
    unsigned long systime;
    unsigned long last_pts = audec->adsp_ops.last_audio_pts;
    unsigned long last_kernel_pts = audec->adsp_ops.kernel_audio_pts;
    char buf[64];
    char ret_val = -1;
    if (audec->auto_mute == 1) {
        return 0;
    }

    memset(buf, 0, sizeof(buf));

    systime = audec->adsp_ops.get_cur_pcrscr(&audec->adsp_ops);
    if (systime == -1) {
        adec_print("unable to getsystime");
        return -1;
    }

    /* get audio time stamp */
    pts = adec_calc_pts(audec);
    if (pts == -1 || last_pts == pts) {
        //close(fd);
        //if (pts == -1) {
        return -1;
        //}
    }

    if ((abs(pts - last_pts) > APTS_DISCONTINUE_THRESHOLD) && (audec->adsp_ops.last_pts_valid)) {
        /* report audio time interruption */
        adec_print("pts = %lx, last pts = %lx\n", pts, last_pts);

        adec_print("audio time interrupt: 0x%lx->0x%lx, 0x%lx\n", last_pts, pts, abs(pts - last_pts));

        sprintf(buf, "AUDIO_TSTAMP_DISCONTINUITY:0x%lx", pts);

        if(amsysfs_set_sysfs_str(TSYNC_EVENT, buf) == -1)
        {
            adec_print("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
            return -1;
        }

        audec->adsp_ops.last_audio_pts = pts;
        audec->adsp_ops.last_pts_valid = 1;
        adec_print("set automute!\n");
        audec->auto_mute = 1;
        apts_interrupt=10;
        return 0;
    }

    if (last_kernel_pts == audec->adsp_ops.kernel_audio_pts) {
        return 0;
    }

    audec->adsp_ops.last_audio_pts = pts;
    audec->adsp_ops.last_pts_valid = 1;

    if (abs(pts - systime) < audec->avsync_threshold) {
        apts_interrupt=0;
        return 0;
    }
    else if(apts_interrupt>0){
        apts_interrupt --;
        return 0;
        }

    /* report apts-system time difference */

    if(audec->adsp_ops.set_cur_apts){
        ret_val = audec->adsp_ops.set_cur_apts(&audec->adsp_ops,pts);
    }
    else{
	 sprintf(buf, "0x%lx", pts);
	 ret_val = amsysfs_set_sysfs_str(TSYNC_APTS, buf);
    }
    if(ret_val == -1)
    {
        adec_print("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
        return -1;
    }
    //adec_print("report apts as %ld,system pts=%ld, difference= %ld\n", pts, systime, (pts - systime));
    return 0;
}
예제 #7
0
int adec_pts_droppcm(aml_audio_dec_t *audec)
{
    unsigned long vpts, apts;
    int drop_size;
    int ret;
    char buf[32];
    char buffer[8*1024];
    char value[PROPERTY_VALUE_MAX]={0};

    if (amsysfs_get_sysfs_str(TSYNC_VPTS, buf, sizeof(buf)) == -1) {
    	adec_print("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
    	return -1;
    }
    if (sscanf(buf, "0x%lx", &vpts) < 1) {
        adec_print("unable to get vpts from: %s", buf);
        return -1;
    }

    apts = adec_calc_pts(audec);
    int diff = (apts > vpts)?(apts-vpts):(vpts-apts);
    adec_print("before drop --apts 0x%x,vpts 0x%x,apts %s, diff 0x%x\n",apts,vpts,(apts>vpts)?"big":"small",diff);
    if(apts>=vpts) //no need to drop pcm
        return 0;
    int audio_ahead = 0;
    unsigned pts_ahead_val = SYSTIME_CORRECTION_THRESHOLD;

    if (am_getconfig_bool("media.libplayer.wfd")) {
        pts_ahead_val = pts_ahead_val * 2 / 3;
    }

    if(property_get("media.amplayer.apts",value,NULL) > 0){
    	if(!strcmp(value,"slow")){
    		audio_ahead = -1;
    	}
    	else if(!strcmp(value,"fast")){
    		audio_ahead = 1;
    	}
    }
    memset(value,0,sizeof(value));
    if(property_get("media.amplayer.apts_val",value,NULL) > 0){
    	pts_ahead_val = atoi(value);
    }
    adec_print("audio ahead %d,ahead pts value %d \n",	audio_ahead,pts_ahead_val);

    struct timeval  new_time,old_time;
    long new_time_mseconds;
    long old_time_mseconds;
    //old time
    gettimeofday(&old_time, NULL);
    old_time_mseconds = (old_time.tv_usec / 1000 + old_time.tv_sec * 1000);

#define DROP_PCM_DURATION_THRESHHOLD 4 //unit:s
    drop_size = ((vpts - apts+pts_ahead_val*audio_ahead)/90) * (audec->samplerate/1000) * audec->channels *2;
    int drop_duration=drop_size/audec->channels/2/audec->samplerate;
    int nDropCount=0;
    adec_print("==drop_size=%d, nDropCount:%d -----------------\n",drop_size, nDropCount);
    while(drop_size > 0 && drop_duration <DROP_PCM_DURATION_THRESHHOLD){
    	ret = audec->adsp_ops.dsp_read(&audec->adsp_ops, buffer, MIN(drop_size, 8192));
    	//apts = adec_calc_pts(audec);
    	//adec_print("==drop_size=%d, ret=%d, nDropCount:%d apts=0x%x,-----------------\n",drop_size, ret, nDropCount,apts);
    	if(ret==0)//no data in pcm buf
    	{
    		if(nDropCount>=5)
    			break;
    		else
    			nDropCount++;
    		adec_print("==ret:0 no pcm nDropCount:%d \n",nDropCount);
    	}
    	else
    	{
    		nDropCount=0;
    		drop_size -= ret;
    	}
    }

    //new time
    gettimeofday(&new_time, NULL);
    new_time_mseconds = (new_time.tv_usec / 1000 + new_time.tv_sec * 1000);
    adec_print("==old time  sec :%d usec:%d \n", old_time.tv_sec  ,old_time.tv_usec );
    adec_print("==new time  sec:%d usec:%d \n", new_time.tv_sec  ,new_time.tv_usec  );
    adec_print("==old time ms is :%d  new time ms is:%d   diff:%d  \n",old_time_mseconds ,new_time_mseconds ,new_time_mseconds- old_time_mseconds);

    if (amsysfs_get_sysfs_str(TSYNC_VPTS, buf, sizeof(buf)) == -1) {
    	adec_print("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
    	return -1;
    }
    if (sscanf(buf, "0x%lx", &vpts) < 1) {
        adec_print("unable to get vpts from: %s", buf);
        return -1;
    }

    apts = adec_calc_pts(audec);
    diff = (apts > vpts)?(apts-vpts):(vpts-apts);
    adec_print("after drop pcm:--apts 0x%x,vpts 0x%x,apts %s, diff 0x%x\n",apts,vpts,(apts>vpts)?"big":"small",diff);
    return 0;
}