📄 streamutil.c
字号:
pjmedia_codec_mgr_get_codec_info( pjmedia_endpt_get_codec_mgr(med_endpt), 0, &codec_info); } /* Create stream based on program arguments */ status = create_stream(pool, med_endpt, codec_info, dir, local_port, &remote_addr, &stream); if (status != PJ_SUCCESS) goto on_exit; /* Get the port interface of the stream */ status = pjmedia_stream_get_port( stream, &stream_port); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); if (play_file) { unsigned wav_ptime; wav_ptime = stream_port->info.samples_per_frame * 1000 / stream_port->info.clock_rate; status = pjmedia_wav_player_port_create(pool, play_file, wav_ptime, 0, -1, &play_file_port); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to use file", status); goto on_exit; } status = pjmedia_master_port_create(pool, play_file_port, stream_port, 0, &master_port); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to create master port", status); goto on_exit; } status = pjmedia_master_port_start(master_port); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Error starting master port", status); goto on_exit; } printf("Playing from WAV file %s..\n", play_file); } else if (rec_file) { status = pjmedia_wav_writer_port_create(pool, rec_file, stream_port->info.clock_rate, stream_port->info.channel_count, stream_port->info.samples_per_frame, stream_port->info.bits_per_sample, 0, 0, &rec_file_port); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to use file", status); goto on_exit; } status = pjmedia_master_port_create(pool, stream_port, rec_file_port, 0, &master_port); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to create master port", status); goto on_exit; } status = pjmedia_master_port_start(master_port); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Error starting master port", status); goto on_exit; } printf("Recording to WAV file %s..\n", rec_file); } else { /* Create sound device port. */ if (dir == PJMEDIA_DIR_ENCODING_DECODING) status = pjmedia_snd_port_create(pool, -1, -1, stream_port->info.clock_rate, stream_port->info.channel_count, stream_port->info.samples_per_frame, stream_port->info.bits_per_sample, 0, &snd_port); else if (dir == PJMEDIA_DIR_ENCODING) status = pjmedia_snd_port_create_rec(pool, -1, stream_port->info.clock_rate, stream_port->info.channel_count, stream_port->info.samples_per_frame, stream_port->info.bits_per_sample, 0, &snd_port); else status = pjmedia_snd_port_create_player(pool, -1, stream_port->info.clock_rate, stream_port->info.channel_count, stream_port->info.samples_per_frame, stream_port->info.bits_per_sample, 0, &snd_port); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Unable to create sound port", status); goto on_exit; } /* Connect sound port to stream */ status = pjmedia_snd_port_connect( snd_port, stream_port ); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); } /* Start streaming */ pjmedia_stream_start(stream); /* Done */ if (dir == PJMEDIA_DIR_DECODING) printf("Stream is active, dir is recv-only, local port is %d\n", local_port); else if (dir == PJMEDIA_DIR_ENCODING) printf("Stream is active, dir is send-only, sending to %s:%d\n", pj_inet_ntoa(remote_addr.sin_addr), pj_ntohs(remote_addr.sin_port)); else printf("Stream is active, send/recv, local port is %d, " "sending to %s:%d\n", local_port, pj_inet_ntoa(remote_addr.sin_addr), pj_ntohs(remote_addr.sin_port)); for (;;) { puts(""); puts("Commands:"); puts(" s Display media statistics"); puts(" q Quit"); puts(""); printf("Command: "); fflush(stdout); fgets(tmp, sizeof(tmp), stdin); if (tmp[0] == 's') print_stream_stat(stream); else if (tmp[0] == 'q') break; } /* Start deinitialization: */on_exit: /* Destroy sound device */ if (snd_port) { pjmedia_snd_port_destroy( snd_port ); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); } /* If there is master port, then we just need to destroy master port * (it will recursively destroy upstream and downstream ports, which * in this case are file_port and stream_port). */ if (master_port) { pjmedia_master_port_destroy(master_port, PJ_TRUE); play_file_port = NULL; stream = NULL; } /* Destroy stream */ if (stream) { pjmedia_transport *tp; tp = pjmedia_stream_get_transport(stream); pjmedia_stream_destroy(stream); pjmedia_transport_udp_close(tp); } /* Destroy file ports */ if (play_file_port) pjmedia_port_destroy( play_file_port ); if (rec_file_port) pjmedia_port_destroy( rec_file_port ); /* Release application pool */ pj_pool_release( pool ); /* Destroy media endpoint. */ pjmedia_endpt_destroy( med_endpt ); /* Destroy pool factory */ pj_caching_pool_destroy( &cp ); /* Shutdown PJLIB */ pj_shutdown(); return (status == PJ_SUCCESS) ? 0 : 1;}static const char *good_number(char *buf, pj_int32_t val){ if (val < 1000) { pj_ansi_sprintf(buf, "%d", val); } else if (val < 1000000) { pj_ansi_sprintf(buf, "%d.%dK", val / 1000, (val % 1000) / 100); } else { pj_ansi_sprintf(buf, "%d.%02dM", val / 1000000, (val % 1000000) / 10000); } return buf;}/* * Print stream statistics */static void print_stream_stat(pjmedia_stream *stream){ char duration[80], last_update[80]; char bps[16], ipbps[16], packets[16], bytes[16], ipbytes[16]; pjmedia_port *port; pjmedia_rtcp_stat stat; pj_time_val now; pj_gettimeofday(&now); pjmedia_stream_get_stat(stream, &stat); pjmedia_stream_get_port(stream, &port); puts("Stream statistics:"); /* Print duration */ PJ_TIME_VAL_SUB(now, stat.start); sprintf(duration, " Duration: %02ld:%02ld:%02ld.%03ld", now.sec / 3600, (now.sec % 3600) / 60, (now.sec % 60), now.msec); printf(" Info: audio %.*s@%dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n", (int)port->info.encoding_name.slen, port->info.encoding_name.ptr, port->info.clock_rate, port->info.samples_per_frame * 1000 / port->info.clock_rate, good_number(bps, port->info.bytes_per_frame * port->info.clock_rate / port->info.samples_per_frame), good_number(ipbps, (port->info.bytes_per_frame+32) * port->info.clock_rate / port->info.clock_rate)); if (stat.rx.update_cnt == 0) strcpy(last_update, "never"); else { pj_gettimeofday(&now); PJ_TIME_VAL_SUB(now, stat.rx.update); sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", now.sec / 3600, (now.sec % 3600) / 60, now.sec % 60, now.msec); } printf(" RX stat last update: %s\n" " total %s packets %sB received (%sB +IP hdr)%s\n" " pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n" " (msec) min avg max last\n" " loss period: %7.3f %7.3f %7.3f %7.3f%s\n" " jitter : %7.3f %7.3f %7.3f %7.3f%s\n", last_update, good_number(packets, stat.rx.pkt), good_number(bytes, stat.rx.bytes), good_number(ipbytes, stat.rx.bytes + stat.rx.pkt * 32), "", stat.rx.loss, stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss), stat.rx.dup, stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss), stat.rx.reorder, stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss), "", stat.rx.loss_period.min / 1000.0, stat.rx.loss_period.avg / 1000.0, stat.rx.loss_period.max / 1000.0, stat.rx.loss_period.last / 1000.0, "", stat.rx.jitter.min / 1000.0, stat.rx.jitter.avg / 1000.0, stat.rx.jitter.max / 1000.0, stat.rx.jitter.last / 1000.0, "" ); if (stat.tx.update_cnt == 0) strcpy(last_update, "never"); else { pj_gettimeofday(&now); PJ_TIME_VAL_SUB(now, stat.tx.update); sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago", now.sec / 3600, (now.sec % 3600) / 60, now.sec % 60, now.msec); } printf(" TX stat last update: %s\n" " total %s packets %sB sent (%sB +IP hdr)%s\n" " pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n" " (msec) min avg max last\n" " loss period: %7.3f %7.3f %7.3f %7.3f%s\n" " jitter : %7.3f %7.3f %7.3f %7.3f%s\n", last_update, good_number(packets, stat.tx.pkt), good_number(bytes, stat.tx.bytes), good_number(ipbytes, stat.tx.bytes + stat.tx.pkt * 32), "", stat.tx.loss, stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss), stat.tx.dup, stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss), stat.tx.reorder, stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss), "", stat.tx.loss_period.min / 1000.0, stat.tx.loss_period.avg / 1000.0, stat.tx.loss_period.max / 1000.0, stat.tx.loss_period.last / 1000.0, "", stat.tx.jitter.min / 1000.0, stat.tx.jitter.avg / 1000.0, stat.tx.jitter.max / 1000.0, stat.tx.jitter.last / 1000.0, "" ); printf(" RTT delay : %7.3f %7.3f %7.3f %7.3f%s\n", stat.rtt.min / 1000.0, stat.rtt.avg / 1000.0, stat.rtt.max / 1000.0, stat.rtt.last / 1000.0, "" );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -