Ticket #1679: fps-converter-ver2.patch

File fps-converter-ver2.patch, 3.9 KB (added by ming, 6 years ago)

Revised version to support multiple streams

  • pjmedia/include/pjmedia/port.h

     
    232232    pj_uint32_t     signature;          /**< Port signature.                */ 
    233233    pjmedia_dir     dir;                /**< Port direction.                */ 
    234234    pjmedia_format  fmt;                /**< Format.                        */ 
     235    pj_uint32_t     frames_counter;             /**< Frames counter, important for manipulating FPS.                */ 
     236    pj_uint32_t     src_frames_block_size;      /**< Size of the frames block if we need to manupulate FPS   */ 
     237    pj_uint32_t     dst_skip_frames;    /**< Skip all frames with number higher than this value             */ 
    235238} pjmedia_port_info; 
    236239 
    237240/** 
  • pjmedia/src/pjmedia/vid_tee.c

     
    293293    return PJ_ENOTFOUND; 
    294294} 
    295295 
     296int greatest_common_divisor(int a, int b) 
     297{ 
     298        if(b == 0) 
     299        { 
     300                return a; 
     301        } 
     302        else 
     303        { 
     304                return greatest_common_divisor(b, a % b); 
     305        } 
     306} 
    296307 
     308void calculate_vid_tee_port_fps_variables(pjmedia_port_info *src, pjmedia_port_info *dst) 
     309{ 
     310        int src_fps, dst_fps, divisor; 
     311 
     312        src_fps = src->fmt.det.vid.fps.num / src->fmt.det.vid.fps.denum; 
     313        dst_fps = dst->fmt.det.vid.fps.num / dst->fmt.det.vid.fps.denum; 
     314 
     315        if(dst_fps < src_fps) 
     316        { 
     317                divisor = greatest_common_divisor(src_fps, dst_fps); 
     318 
     319                dst->src_frames_block_size = src_fps / divisor; 
     320                dst->dst_skip_frames = dst_fps / divisor; 
     321        } 
     322        else 
     323        { 
     324                /* just to disable future calculations from above */ 
     325                dst->frames_counter = -1; 
     326        } 
     327} 
     328 
    297329static pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame) 
    298330{ 
    299331    vid_tee_port *tee = (vid_tee_port*)port; 
     
    331363         */ 
    332364        for (j = i; j < tee->dst_port_cnt; ++j) { 
    333365            pjmedia_frame framep; 
     366                        pj_bool_t deliver_data = PJ_TRUE; 
    334367             
    335368            if (tee->put_frm_flag[j] || 
    336369                (tee->dst_ports[j].dst->info.fmt.id !=  
     
    344377            } 
    345378             
    346379            framep = frame_; 
     380 
    347381            /* For dst_ports that do in-place processing, we need to duplicate 
    348382             * the data source first. 
    349383             */ 
     
    354388                framep.size = frame_.size; 
    355389                pj_memcpy(framep.buf, frame_.buf, frame_.size); 
    356390            } 
     391         
     392                        /* first frame to be sent */ 
     393                        if(tee->dst_ports[j].dst->info.frames_counter == 0) 
     394                        { 
     395                                calculate_vid_tee_port_fps_variables(&tee->base.info, &tee->dst_ports[j].dst->info); 
     396                        } 
    357397 
    358             /* Deliver the data */ 
    359             pjmedia_port_put_frame(tee->dst_ports[j].dst, &framep); 
    360             tee->put_frm_flag[j] = PUT_FRM_DONE; 
    361              
     398                        if(tee->dst_ports[j].dst->info.src_frames_block_size > 0) 
     399                        { 
     400                                /* send frames higher than dst_skip_frames of every src_frames_block_size frames */ 
     401                                int num = tee->dst_ports[j].dst->info.frames_counter % tee->dst_ports[j].dst->info.src_frames_block_size; 
     402                                if( num >= tee->dst_ports[j].dst->info.dst_skip_frames) 
     403                                { 
     404                                        deliver_data = PJ_FALSE; 
     405                                } 
     406                                ++tee->dst_ports[j].dst->info.frames_counter; 
     407                        } 
     408 
     409                        if(deliver_data) 
     410                        { 
     411                                /* Deliver the data */ 
     412                                pjmedia_port_put_frame(tee->dst_ports[j].dst, &framep); 
     413                        } 
     414                        tee->put_frm_flag[j] = PUT_FRM_DONE; 
     415 
    362416            if (!tee->tee_conv[i].conv) 
    363417                break; 
    364418        } 
  • pjmedia/src/pjmedia/port.c

     
    6868    info->signature = signature; 
    6969    info->dir = dir; 
    7070    info->name = *name; 
     71        info->frames_counter = 0; 
     72    info->src_frames_block_size = 0; 
     73    info->dst_skip_frames = 0; 
    7174 
    7275    pjmedia_format_copy(&info->fmt, fmt); 
    7376