Ticket #1679: fps-converter.patch

File fps-converter.patch, 3.8 KB (added by nanang, 11 years ago)

Proposed patch from Arkadiusz Wronski, thanks. Note: Works only in case we want to lower the fps, and tested only with values being multiplication of 5.

  • pjmedia/include/pjmedia/port.h

    diff --git a/pjmedia/include/pjmedia/port.h b/pjmedia/include/pjmedia/port.h
    index fa9b279..0a50872 100644
    a b typedef struct pjmedia_port_info 
    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/port.c

    diff --git a/pjmedia/src/pjmedia/port.c b/pjmedia/src/pjmedia/port.c
    index c6d6b51..782a838 100644
    a b PJ_DEF(pj_status_t) pjmedia_port_info_init2( pjmedia_port_info *info, 
    6969    info->signature = signature; 
    7070    info->dir = dir; 
    7171    info->name = *name; 
     72        info->frames_counter = 0; 
     73    info->src_frames_block_size = 0; 
     74    info->dst_skip_frames = 0; 
    7275 
    7376    pjmedia_format_copy(&info->fmt, fmt); 
    7477 
  • pjmedia/src/pjmedia/vid_tee.c

    diff --git a/pjmedia/src/pjmedia/vid_tee.c b/pjmedia/src/pjmedia/vid_tee.c
    index 3e9dfb5..12459db 100644
    a b PJ_DEF(pj_status_t) pjmedia_vid_tee_remove_dst_port(pjmedia_port *vid_tee, 
    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} 
     307 
     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} 
    296328 
    297329static pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame) 
    298330{ 
    299331    vid_tee_port *tee = (vid_tee_port*)port; 
    300332    unsigned i, j; 
    301333    const pj_uint8_t PUT_FRM_DONE = 1; 
     334        pj_bool_t deliver_data = PJ_TRUE; 
    302335 
    303336    pj_bzero(tee->put_frm_flag, tee->dst_port_cnt * 
    304337                                sizeof(tee->put_frm_flag[0])); 
    static pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame) 
    354387                framep.size = frame_.size; 
    355388                pj_memcpy(framep.buf, frame_.buf, frame_.size); 
    356389            } 
     390         
     391                        /* first frame to be sent */ 
     392                        if(tee->dst_ports[j].dst->info.frames_counter == 0) 
     393                        { 
     394                                calculate_vid_tee_port_fps_variables(&tee->base.info, &tee->dst_ports[j].dst->info); 
     395                        } 
     396 
     397                        if(tee->dst_ports[j].dst->info.src_frames_block_size > 0) 
     398                        { 
     399                                /* send frames higher than dst_skip_frames of every src_frames_block_size frames */ 
     400                                int num = tee->dst_ports[j].dst->info.frames_counter % tee->dst_ports[j].dst->info.src_frames_block_size; 
     401                                if( num >= tee->dst_ports[j].dst->info.dst_skip_frames) 
     402                                { 
     403                                        deliver_data = PJ_FALSE; 
     404                                } 
     405                                ++tee->dst_ports[j].dst->info.frames_counter; 
     406                        } 
     407 
     408                        if(deliver_data) 
     409                        { 
     410                                /* Deliver the data */ 
     411                                pjmedia_port_put_frame(tee->dst_ports[j].dst, &framep); 
     412                        } 
     413                        tee->put_frm_flag[j] = PUT_FRM_DONE; 
    357414 
    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              
    362415            if (!tee->tee_conv[i].conv) 
    363416                break; 
    364417        }