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 |
232 | 232 | pj_uint32_t signature; /**< Port signature. */ |
233 | 233 | pjmedia_dir dir; /**< Port direction. */ |
234 | 234 | 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 */ |
235 | 238 | } pjmedia_port_info; |
236 | 239 | |
237 | 240 | /** |
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, |
69 | 69 | info->signature = signature; |
70 | 70 | info->dir = dir; |
71 | 71 | info->name = *name; |
| 72 | info->frames_counter = 0; |
| 73 | info->src_frames_block_size = 0; |
| 74 | info->dst_skip_frames = 0; |
72 | 75 | |
73 | 76 | pjmedia_format_copy(&info->fmt, fmt); |
74 | 77 | |
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, |
293 | 293 | return PJ_ENOTFOUND; |
294 | 294 | } |
295 | 295 | |
| 296 | int 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 | |
| 308 | void 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 | } |
296 | 328 | |
297 | 329 | static pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame) |
298 | 330 | { |
299 | 331 | vid_tee_port *tee = (vid_tee_port*)port; |
300 | 332 | unsigned i, j; |
301 | 333 | const pj_uint8_t PUT_FRM_DONE = 1; |
| 334 | pj_bool_t deliver_data = PJ_TRUE; |
302 | 335 | |
303 | 336 | pj_bzero(tee->put_frm_flag, tee->dst_port_cnt * |
304 | 337 | sizeof(tee->put_frm_flag[0])); |
… |
… |
static pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame) |
354 | 387 | framep.size = frame_.size; |
355 | 388 | pj_memcpy(framep.buf, frame_.buf, frame_.size); |
356 | 389 | } |
| 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; |
357 | 414 | |
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 | | |
362 | 415 | if (!tee->tee_conv[i].conv) |
363 | 416 | break; |
364 | 417 | } |