int amdisplay_utils_get_osd_rotation() { char buf[40]; int ret; ret = amsysfs_get_sysfs_str(OSD_ROTATION_ON, buf, SYSCMD_BUFSIZE); if((ret<0) || strstr(buf,"OFF")) { return 0;//no rotation+ } memset(buf, 0 ,40); ret = amsysfs_get_sysfs_str(OSD_ROTATION_PATH, buf, SYSCMD_BUFSIZE); if(ret < 0) return 0;//no rotation int rotation = 0; if (sscanf(buf, "osd_rotate:%d", &rotation) == 1) { LOGI("get osd rotation %d\n", rotation); } switch (rotation) { case 0: rotation = 0; break; case 1: rotation = 90; break; case 2: rotation = 270; break; default: break; } LOGD("amdisplay_utils_get_osd_rotation return %d",rotation); return rotation; }
int amvideo_utils_get_freescale_enable(void) { int ret = 0; char buf[32]; ret = amsysfs_get_sysfs_str("/sys/class/graphics/fb0/free_scale", buf, 32); if((ret >=0) && strncmp(buf, "free_scale_enalbe:[0x1]", strlen("free_scale_enalbe:[0x1]"))==0){ return 1; } return 0; }
int amvideo_utils_get_global_offset(void) { LOG_FUNCTION_NAME int offset = 0; char buf[SYSCMD_BUFSIZE]; int ret; ret = amsysfs_get_sysfs_str(VIDEO_GLOBAL_OFFSET_PATH, buf, SYSCMD_BUFSIZE); if (ret < 0) { return offset; } if (sscanf(buf, "%d", &offset) == 1) { LOGI("video global_offset %d\n", offset); } return offset; }
int is_video_on_vpp2(void) { int ret = 0; char val[32]; memset(val, 0, sizeof(val)); if (property_get("ro.vout.dualdisplay4", val, "false") && strcmp(val, "true") == 0) { memset(val, 0, sizeof(val)); if (amsysfs_get_sysfs_str("/sys/module/amvideo/parameters/cur_dev_idx", val, sizeof(val)) == 0) { if ((strncmp(val, "1", 1) == 0)) { ret = 1; } } } return ret; }
int amdisplay_utils_get_size_fb2(int *width, int *height) { LOG_FUNCTION_NAME char buf[SYSCMD_BUFSIZE]; int disp_w = 0; int disp_h = 0; int ret; ret = amsysfs_get_sysfs_str(FB_DEVICE_PATH_FB2, buf, SYSCMD_BUFSIZE); if (ret < 0) { return ret; } if (sscanf(buf, "%d,%d", &disp_w, &disp_h) == 2) { LOGI("disp resolution %dx%d\n", disp_w, disp_h); disp_h = disp_h / FB_BUFFER_NUM; } else { return -2;/*format unknow*/ } *width = disp_w; *height = disp_h; return 0; }
/** * \brief get audio format * \return audio format on success otherwise ADEC_AUDIO_FORMAT_UNKNOWN */ static adec_audio_format_t get_audio_format(void) { char format[21]; int len; format[0] = 0; amsysfs_get_sysfs_str(FORMAT_PATH, format, 21); if (strncmp(format, "NA", 2) == 0) { return ADEC_AUDIO_FORMAT_UNKNOWN; } adec_print("amadec format: %s", format); if (strncmp(format, "amadec_mpeg", 11) == 0) { return ADEC_AUDIO_FORMAT_MPEG; } if (strncmp(format, "amadec_pcm_s16le", 16) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_PCM_S16LE; } if (strncmp(format, "amadec_pcm_s16be", 16) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_PCM_S16BE; } if (strncmp(format, "amadec_pcm_u8", 13) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_PCM_U8; } if (strncmp(format, "amadec_adpcm", 12) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_ADPCM; } if (strncmp(format, "amadec_aac_latm", 15) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_AAC_LATM; } if (strncmp(format, "amadec_aac", 10) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_AAC; } if (strncmp(format, "amadec_ac3", 10) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_AC3; } if (strncmp(format, "amadec_eac3", 11) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_EAC3; } if (strncmp(format, "amadec_alaw", 11) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_ALAW; } if (strncmp(format, "amadec_mulaw", 12) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_MULAW; } if (strncmp(format, "amadec_dts", 10) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_DTS; } if (strncmp(format, "amadec_flac", 11) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_FLAC; } if (strncmp(format, "amadec_cook", 11) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_COOK; } if (strncmp(format, "amadec_amr", 10) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_AMR; } if (strncmp(format, "amadec_raac", 11) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_RAAC; } if (strncmp(format, "amadec_wmapro", 13) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_WMAPRO; } if (strncmp(format, "amadec_wma", 10) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_WMA; } if (strncmp(format, "amadec_pcm_bluray", 10) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_AFORMAT_PCM_BLURAY; } if (strncmp(format, "amadec_alac", 11) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_AFORMAT_ALAC; } if (strncmp(format, "amadec_vorbis", 13) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_AFORMAT_VORBIS; } if (strncmp(format, "amadec_ape", 10) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_APE; } if (strncmp(format, "amadec_pcm_widi", 15) == 0) { /*TODO: get format/channel numer/sample rate etc */ return ADEC_AUDIO_FORMAT_PCM_WIFIDISPLAY; } adec_print("audio format unknow."); return ADEC_AUDIO_FORMAT_UNKNOWN; }
int amvideo_utils_set_virtual_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation) { LOG_FUNCTION_NAME //for osd rotation, need convert the axis first int osd_rotation = amdisplay_utils_get_osd_rotation(); if(osd_rotation > 0) amvideo_convert_axis(&x,&y,&w,&h,&rotation,osd_rotation); int video_fd; int dev_fd = -1, dev_w, dev_h, disp_w, disp_h, video_global_offset; int dst_x, dst_y, dst_w, dst_h; char buf[SYSCMD_BUFSIZE]; int angle_fd = -1; int ret = -1; int axis[4]; char enable_p2p_play[8] = {0}; int video_on_vpp2 = is_video_on_vpp2(); int vertical_panel = is_vertical_panel(); int vertical_panel_reverse = is_vertical_panel_reverse(); if (video_on_vpp2) { int fb0_w, fb0_h, fb2_w, fb2_h; amdisplay_utils_get_size(&fb0_w, &fb0_h); amdisplay_utils_get_size_fb2(&fb2_w, &fb2_h); if (fb0_w > 0 && fb0_h > 0 && fb2_w > 0 && fb2_h > 0) { if (vertical_panel) { int x1, y1, w1, h1; if (vertical_panel_reverse) { x1 = (1.0 * fb2_w / fb0_h) * y; y1 = (1.0 * fb2_h / fb0_w) * x; w1 = (1.0 * fb2_w / fb0_h) * h; h1 = (1.0 * fb2_h / fb0_w) * w; } else { x1 = (1.0 * fb2_w / fb0_h) * y; y1 = (1.0 * fb2_h / fb0_w) * (fb0_w - x - w); w1 = (1.0 * fb2_w / fb0_h) * h; h1 = (1.0 * fb2_h / fb0_w) * w; } x = x1; y = y1; w = w1; h = h1; } else { int x1, y1, w1, h1; x1 = (1.0 * fb2_w / fb0_w) * x; y1 = (1.0 * fb2_h / fb0_h) * y; w1 = (1.0 * fb2_w / fb0_w) * w; h1 = (1.0 * fb2_h / fb0_h) * h; x = x1; y = y1; w = w1; h = h1; } } } LOGI("amvideo_utils_set_virtual_position:: x=%d y=%d w=%d h=%d\n", x, y, w, h); bzero(buf, SYSCMD_BUFSIZE); dst_x = x; dst_y = y; dst_w = w; dst_h = h; video_fd = open(VIDEO_PATH, O_RDWR); if (video_fd < 0) { goto OUT; } dev_fd = open(DISP_DEVICE_PATH, O_RDONLY); if (dev_fd < 0) { goto OUT; } read(dev_fd, buf, SYSCMD_BUFSIZE); if (sscanf(buf, "%dx%d", &dev_w, &dev_h) == 2) { LOGI("device resolution %dx%d\n", dev_w, dev_h); } else { ret = -2; goto OUT; } if (video_on_vpp2) amdisplay_utils_get_size_fb2(&disp_w, &disp_h); else amdisplay_utils_get_size(&disp_w, &disp_h); LOGI("amvideo_utils_set_virtual_position:: disp_w=%d, disp_h=%d\n", disp_w, disp_h); video_global_offset = amvideo_utils_get_global_offset(); int free_scale_enable = 0; int ppscaler_enable = 0; int freescale_mode_enable = 0; if (((disp_w != dev_w) || (disp_h / 2 != dev_h)) && (video_global_offset == 0)) { char val[256]; memset(val, 0, sizeof(val)); if (video_on_vpp2) { if (amsysfs_get_sysfs_str(FREE_SCALE_PATH_FB2, val, sizeof(val)) == 0) { /* the returned string should be "free_scale_enable:[0x%x]" */ free_scale_enable = (val[21] == '0') ? 0 : 1; } } else { if (amsysfs_get_sysfs_str(FREE_SCALE_PATH, val, sizeof(val)) == 0) { /* the returned string should be "free_scale_enable:[0x%x]" */ free_scale_enable = (val[21] == '0') ? 0 : 1; } } memset(val, 0, sizeof(val)); if (amsysfs_get_sysfs_str(PPSCALER_PATH, val, sizeof(val)) == 0) { /* the returned string should be "current ppscaler mode is disabled/enable" */ ppscaler_enable = (val[25] == 'd') ? 0 : 1; } memset(val, 0, sizeof(val)); if (amsysfs_get_sysfs_str(FREE_SCALE_MODE_PATH, val, sizeof(val)) == 0) { /* the returned string should be "free_scale_mode:new/default" */ freescale_mode_enable = (val[16] == 'd') ? 0 : 1; } } angle_fd = open(ANGLE_PATH, O_WRONLY); if (angle_fd >= 0) { if (video_on_vpp2 && vertical_panel) ioctl(angle_fd, PPMGR_IOC_SET_ANGLE, 0); else ioctl(angle_fd, PPMGR_IOC_SET_ANGLE, (rotation/90) & 3); LOGI("set ppmgr angle %d\n", (rotation/90) & 3); } /* this is unlikely and only be used when ppmgr does not exist * to support video rotation. If that happens, we convert the window * position to non-rotated window position. * On ICS, this might not work at all because the transparent UI * window is still drawn is it's direction, just comment out this for now. */ #if 0 if (((rotation == 90) || (rotation == 270)) && (angle_fd < 0)) { if (dst_h == disp_h) { int center = x + w / 2; if (abs(center - disp_w / 2) < 2) { /* a centered overlay with rotation, change to full screen */ dst_x = 0; dst_y = 0; dst_w = dev_w; dst_h = dev_h; LOGI("centered overlay expansion"); } } } #endif /*if (free_scale_enable == 0 && ppscaler_enable == 0) { OSD_DISP_MODE display_mode = OSD_DISP_1080P; int x_d=0,y_d=0,w_d=0,h_d=0; LOGI("set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); display_mode = get_osd_display_mode(); get_device_win(display_mode, &x_d, &y_d, &w_d, &h_d); if(display_mode==OSD_DISP_720P) { if((dst_w >= 1279)||(dst_w==0)) { dst_x = x_d; dst_y = y_d; dst_w = w_d; dst_h = h_d; } else { dst_x = dst_x*w_d/1280+x_d; dst_y = dst_y*h_d/720+y_d; dst_w = dst_w*w_d/1280; dst_h = dst_h*h_d/720; } } else if((display_mode==OSD_DISP_1080I)||(display_mode==OSD_DISP_1080P)||(display_mode==OSD_DISP_LVDS1080P)) { if((dst_w >= 1919)||(dst_w == 0)) { dst_x = x_d; dst_y = y_d; dst_w = w_d; dst_h = h_d; } else {//scaled to 1080p dst_x = dst_x*w_d/1920+x_d; dst_y = dst_y*h_d/1080+y_d; dst_w = dst_w*w_d/1920; dst_h = dst_h*h_d/1080; LOGI("after scaled to 1080 ,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); } } else if((display_mode==OSD_DISP_480I)||(display_mode==OSD_DISP_480P)) { if((dst_w >= 719)||(dst_w == 0)) { dst_x = x_d; dst_y = y_d; dst_w = w_d; dst_h = h_d; } else {//scaled to 480p/480i dst_x = dst_x*w_d/720+x_d; dst_y = dst_y*h_d/480+y_d; dst_w = dst_w*w_d/720; dst_h = dst_h*h_d/480; LOGI("after scaled to 480,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); } } else if((display_mode==OSD_DISP_576I)||(display_mode==OSD_DISP_576P)) { if((dst_w >= 719)||(dst_w == 0)) { dst_x = x_d; dst_y = y_d; dst_w = w_d; dst_h = h_d; } else {//scaled to 576p/576i dst_x = dst_x*w_d/720+x_d; dst_y = dst_y*h_d/576+y_d; dst_w = dst_w*w_d/720; dst_h = dst_h*h_d/576; LOGI("after scaled to 576 ,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); } } }*/ if (free_scale_enable == 0 && ppscaler_enable == 0) { char val[256]; if (freescale_mode_enable == 1) { int left = 0, top = 0, right = 0, bottom = 0; int x = 0, y = 0, w = 0, h = 0; memset(val, 0, sizeof(val)); if (amsysfs_get_sysfs_str(WINDOW_AXIS_PATH, val, sizeof(val)) == 0) { /* the returned string should be "window axis is [a b c d]" */ if (sscanf(val + 15, "[%d %d %d %d]", &left, &top, &right, &bottom) == 4) { x = left; y = top; w = right - left + 1; h = bottom - top + 1; if ((dst_w >= dev_w - 1) || (dst_w == 0)) { dst_x = 0; dst_w = w; } if ((dst_h >= dev_h - 1) || (dst_h == 0)) { dst_y = 0; dst_h = h; } dst_x = dst_x * w / dev_w + x; dst_y = dst_y * h / dev_h + y; LOGI("after scaled, screen position: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); } } } else { int x = 0, y = 0, w = 0, h = 0; int fb_w = 0, fb_h = 0; int req_2xscale = 0; memset(val, 0, sizeof(val)); if (amsysfs_get_sysfs_str(REQUEST_2XSCALE_PATH, val, sizeof(val)) == 0) { /* the returned string should be "a b c" */ if (sscanf(val, "%d", &req_2xscale) == 1) { if (req_2xscale == 7 || req_2xscale == 16) { if (sscanf(val, "%d %d %d", &req_2xscale, &w, &h) == 3) { if (req_2xscale == 7) w *= 2; get_axis(DISPLAY_AXIS_PATH, &x, &y, &fb_w, &fb_h); if (fb_w == 0 || fb_h == 0) { fb_w = 1280; fb_h = 720; } set_scale(x, y, w, h, &dst_x, &dst_y, &dst_w, &dst_h, fb_w, fb_h); LOGI("after scaled, screen position: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); } } } } } } else if (free_scale_enable == 1 && ppscaler_enable == 0) { char val[256]; int left = 0, top = 0, right = 0, bottom = 0; int x = 0, y = 0, w = 0, h = 0; int freescale_x = 0, freescale_y = 0, freescale_w = 0, freescale_h = 0; if (amsysfs_get_sysfs_str(WINDOW_AXIS_PATH, val, sizeof(val)) == 0) { /* the returned string should be "window axis is [a b c d]" */ if (sscanf(val + 15, "[%d %d %d %d]", &left, &top, &right, &bottom) == 4) { x = left; y = top; w = right - left + 1; h = bottom - top + 1; get_axis(FREE_SCALE_AXIS_PATH, &freescale_x, &freescale_y, &freescale_w, &freescale_h); freescale_w = (freescale_w + 1) & (~1); freescale_h = (freescale_h + 1) & (~1); set_scale(x, y, w, h, &dst_x, &dst_y, &dst_w, &dst_h, freescale_w, freescale_h); LOGI("after scaled, screen position: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); } } } axis[0] = dst_x; axis[1] = dst_y; axis[2] = dst_x + dst_w - 1; axis[3] = dst_y + dst_h - 1; ioctl(video_fd, AMSTREAM_IOC_SET_VIDEO_AXIS, &axis[0]); ret = 0; OUT: if (video_fd >= 0) { close(video_fd); } if (dev_fd >= 0) { close(dev_fd); } if (angle_fd >= 0) { close(angle_fd); } LOGI("amvideo_utils_set_virtual_position (corrected):: x=%d y=%d w=%d h=%d\n", dst_x, dst_y, dst_w, dst_h); return ret; }
/** * \brief start audio dec when receive START command. * \param audec pointer to audec */ static void start_adec(aml_audio_dec_t *audec) { int ret; audio_out_operations_t *aout_ops = &audec->aout_ops; dsp_operations_t *dsp_ops = &audec->adsp_ops; unsigned long vpts,apts; int times=0; char buf[32]; apts = vpts = 0; audec->no_first_apts = 0; if (audec->state == INITTED) { audec->state = ACTIVE; while ((!audiodsp_get_first_pts_flag(dsp_ops)) && (!audec->need_stop) && (!audec->no_first_apts)) { adec_print("wait first pts checkin complete times=%d,!\n",times); times++; if (times>=5) { // read vpts amsysfs_get_sysfs_str(TSYNC_VPTS, buf, sizeof(buf)); if (sscanf(buf, "0x%lx", &vpts) < 1) { adec_print("unable to get vpts from: %s", buf); return -1; } // save vpts to apts adec_print("## can't get first apts, save vpts to apts,vpts=%lx, \n",vpts); sprintf(buf, "0x%lx", vpts); amsysfs_set_sysfs_str(TSYNC_APTS, buf); audec->no_first_apts = 1; } usleep(100000); } /*Since audio_track->start consumed too much time *for the first time after platform restart, *so execute start cmd before adec_pts_start */ aout_ops->start(audec); aout_ops->pause(audec); /*start the the pts scr,...*/ ret = adec_pts_start(audec); //adec_pts_droppcm(audec); if (audec->auto_mute) { avsync_en(0); audiodsp_automute_on(dsp_ops); adec_pts_pause(); while ((!audec->need_stop) && track_switch_pts(audec)) { usleep(1000); } audiodsp_automute_off(dsp_ops); avsync_en(1); adec_pts_resume(); audec->auto_mute = 0; } aout_ops->resume(audec); } }
int amvideo_utils_set_virtual_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation) { LOG_FUNCTION_NAME int video_fd; int dev_fd = -1, dev_w, dev_h, disp_w, disp_h, video_global_offset; int dst_x, dst_y, dst_w, dst_h; char buf[SYSCMD_BUFSIZE]; int angle_fd = -1; int ret = -1; int axis[4]; LOGI("amvideo_utils_set_virtual_position:: x=%d y=%d w=%d h=%d\n", x, y, w, h); bzero(buf, SYSCMD_BUFSIZE); dst_x = x; dst_y = y; dst_w = w; dst_h = h; video_fd = open(VIDEO_PATH, O_RDWR); if (video_fd < 0) { goto OUT; } dev_fd = open(DISP_DEVICE_PATH, O_RDONLY); if (dev_fd < 0) { goto OUT; } read(dev_fd, buf, SYSCMD_BUFSIZE); if (sscanf(buf, "%dx%d", &dev_w, &dev_h) == 2) { LOGI("device resolution %dx%d\n", dev_w, dev_h); } else { ret = -2; goto OUT; } amdisplay_utils_get_size(&disp_w, &disp_h); video_global_offset = amvideo_utils_get_global_offset(); /* if we are doing video output to a second display device with * a different resolution, scale all the numbers. * E.g. when a MID pad is connected to a HDMI output. */ if (((disp_w != dev_w) || (disp_h / 2 != dev_h)) && (video_global_offset == 0)) { char val[256]; int free_scale_enable = 0; memset(val, 0, sizeof(val)); if (amsysfs_get_sysfs_str(FREE_SCALE_PATH, val, sizeof(val)) == 0) { /* the returned string should be "free_scale_enable:[0x%x]" */ free_scale_enable = (val[21] == '0') ? 0 : 1; } if (free_scale_enable == 0) { dst_x = dst_x * dev_w / disp_w; dst_y = dst_y * dev_h / disp_h; dst_w = dst_w * dev_w / disp_w; dst_h = dst_h * dev_h / disp_h; } } angle_fd = open(ANGLE_PATH, O_WRONLY); if (angle_fd >= 0) { ioctl(angle_fd, PPMGR_IOC_SET_ANGLE, (rotation/90) & 3); LOGI("set ppmgr angle %d\n", (rotation/90) & 3); } /* this is unlikely and only be used when ppmgr does not exist * to support video rotation. If that happens, we convert the window * position to non-rotated window position. * On ICS, this might not work at all because the transparent UI * window is still drawn is it's direction, just comment out this for now. */ #if 0 if (((rotation == 90) || (rotation == 270)) && (angle_fd < 0)) { if (dst_h == disp_h) { int center = x + w / 2; if (abs(center - disp_w / 2) < 2) { /* a centered overlay with rotation, change to full screen */ dst_x = 0; dst_y = 0; dst_w = dev_w; dst_h = dev_h; LOGI("centered overlay expansion"); } } } #endif axis[0] = dst_x; axis[1] = dst_y; axis[2] = dst_x + dst_w - 1; axis[3] = dst_y + dst_h - 1; ioctl(video_fd, AMSTREAM_IOC_SET_VIDEO_AXIS, &axis[0]); ret = 0; OUT: if (video_fd >= 0) { close(video_fd); } if (dev_fd >= 0) { close(dev_fd); } if (angle_fd >= 0) { close(angle_fd); } LOGI("amvideo_utils_set_virtual_position (corrected):: x=%d y=%d w=%d h=%d\n", dst_x, dst_y, dst_w, dst_h); return ret; }
/** * \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; }
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; }
static int get_sysfs_str(const char *path, char *valstr, int size) { return amsysfs_get_sysfs_str(path, valstr, size); }