|
Home --> Documentations --> PJMEDIA Reference
This example mainly demonstrates how to stream video to remote peer using RTP.
This file is pjsip-apps/src/samples/vid_streamutil.c
32#include <pjlib-util.h>
38#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
47static const char *desc =
51 " Demonstrate how to use pjmedia video stream component to \n"
52 " transmit/receive RTP packets to/from video device/file. \n"
56 " vid_streamutil [options] \n"
60 " --codec=CODEC Set the codec name. \n"
61 " --local-port=PORT Set local RTP port (default=4000) \n"
62 " --remote=IP:PORT Set the remote peer. If this option is set, \n"
63 " the program will transmit RTP audio to the \n"
64 " specified address. (default: recv only) \n"
65 " --play-file=AVI Send video from the AVI file instead of from \n"
66 " the video device. \n"
67 " --send-recv Set stream direction to bidirectional. \n"
68 " --send-only Set stream direction to send only \n"
69 " --recv-only Set stream direction to recv only (default) \n"
71 " --send-width Video width to be sent \n"
72 " --send-height Video height to be sent \n"
73 " --send-width and --send-height not applicable \n"
74 " for file streaming (see --play-file) \n"
76 " --send-pt Payload type for sending \n"
77 " --recv-pt Payload type for receiving \n"
79#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
80 " --use-srtp[=NAME] Enable SRTP with crypto suite NAME \n"
81 " e.g: AES_CM_128_HMAC_SHA1_80 (default), \n"
82 " AES_CM_128_HMAC_SHA1_32 \n"
83 " Use this option along with the TX & RX keys, \n"
84 " formated of 60 hex digits (e.g: E148DA..) \n"
85 " --srtp-tx-key SRTP key for transmiting \n"
86 " --srtp-rx-key SRTP key for receiving \n"
92#define THIS_FILE "vid_streamutil.c"
96#define HAS_LOCAL_RENDERER_FOR_PLAY_FILE 1
102#define DEF_RENDERER_WIDTH 640
103#define DEF_RENDERER_HEIGHT 480
107int my_hex_string_to_octet_string( char *raw, char *hex, int len)
110 for (i = 0; i < len; i+=2) {
116 raw[i/2] = (char)(tmp & 0xFF);
132#if defined(PJMEDIA_HAS_OPENH264_CODEC) && PJMEDIA_HAS_OPENH264_CODEC != 0
137#if defined(PJMEDIA_HAS_VID_TOOLBOX_CODEC) && \
138 PJMEDIA_HAS_VID_TOOLBOX_CODEC != 0
143#if defined(PJMEDIA_HAS_VPX_CODEC) && PJMEDIA_HAS_VPX_CODEC != 0
148#if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC != 0
159static void deinit_codecs()
161#if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC != 0
165#if defined(PJMEDIA_HAS_OPENH264_CODEC) && PJMEDIA_HAS_OPENH264_CODEC != 0
169#if defined(PJMEDIA_HAS_VID_TOOLBOX_CODEC) && \
170 PJMEDIA_HAS_VID_TOOLBOX_CODEC != 0
174#if defined(PJMEDIA_HAS_VPX_CODEC) && PJMEDIA_HAS_VPX_CODEC != 0
181 const char *file_name,
202 *p_play_port = play_port;
219# if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
225 pjmedia_vid_stream **p_stream )
230#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
241 info. tx_pt = (tx_pt == -1)? codec_info-> pt : tx_pt;
242 info. rx_pt = (rx_pt == -1)? codec_info-> pt : rx_pt;
264#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
277 tx_plc. key = *srtp_tx_key;
278 tx_plc. name = *crypto_suite;
279 rx_plc. key = *srtp_rx_key;
280 rx_plc. name = *crypto_suite;
299 app_perror(THIS_FILE, "Error creating stream", status);
311typedef struct play_file_data
313 const char *file_name;
325static void clock_cb( const pj_timestamp *ts, void *user_data)
327 play_file_data *play_file = (play_file_data*)user_data;
334 read_frame. buf = play_file->read_buf;
335 read_frame. size = play_file->read_buf_size;
339 if (play_file->decoder) {
342 write_frame. buf = play_file->dec_buf;
343 write_frame. size = play_file->dec_buf_size;
345 ( unsigned)write_frame. size,
350 write_frame = read_frame;
354 if (play_file->renderer)
373static int main_func( int argc, char *argv[])
378 pjmedia_vid_stream * stream = NULL;
386#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
393 pj_str_t srtp_crypto_suite = {NULL, 0};
403 char *codec_id = NULL;
407 play_file_data play_file = { NULL };
414 OPT_LOCAL_PORT = 'p',
420 OPT_SEND_WIDTH = 'W',
421 OPT_SEND_HEIGHT = 'H',
424#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
427 OPT_SRTP_TX_KEY = 'x',
428 OPT_SRTP_RX_KEY = 'y',
433 { "codec", 1, 0, OPT_CODEC },
434 { "local-port", 1, 0, OPT_LOCAL_PORT },
435 { "remote", 1, 0, OPT_REMOTE },
436 { "play-file", 1, 0, OPT_PLAY_FILE },
437 { "send-recv", 0, 0, OPT_SEND_RECV },
438 { "send-only", 0, 0, OPT_SEND_ONLY },
439 { "recv-only", 0, 0, OPT_RECV_ONLY },
440 { "send-width", 1, 0, OPT_SEND_WIDTH },
441 { "send-height", 1, 0, OPT_SEND_HEIGHT },
442 { "recv-pt", 1, 0, OPT_RECV_PT },
443 { "send-pt", 1, 0, OPT_SEND_PT },
444#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
445 { "use-srtp", 2, 0, OPT_USE_SRTP },
446 { "srtp-tx-key", 1, 0, OPT_SRTP_TX_KEY },
447 { "srtp-rx-key", 1, 0, OPT_SRTP_RX_KEY },
449 { "help", 0, 0, OPT_HELP },
457 pj_bzero(&remote_addr, sizeof(remote_addr));
467 while((c=pj_getopt_long(argc,argv, "h", long_options, &option_index))!=-1)
471 codec_id = pj_optarg;
476 if (local_port < 1) {
477 printf( "Error: invalid local port %s\n", pj_optarg);
489 app_perror(THIS_FILE, "Invalid remote address", status);
496 play_file.file_name = pj_optarg;
512 tx_size. w = (unsigned)atoi(pj_optarg);
515 case OPT_SEND_HEIGHT:
516 tx_size. h = (unsigned)atoi(pj_optarg);
527#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
531 pj_strset(&srtp_crypto_suite, pj_optarg, strlen(pj_optarg));
533 srtp_crypto_suite = pj_str( "AES_CM_128_HMAC_SHA1_80");
537 case OPT_SRTP_TX_KEY:
538 tmp_key_len = my_hex_string_to_octet_string(tmp_tx_key, pj_optarg,
539 ( int)strlen(pj_optarg));
540 pj_strset(&srtp_tx_key, tmp_tx_key, tmp_key_len/2);
543 case OPT_SRTP_RX_KEY:
544 tmp_key_len = my_hex_string_to_octet_string(tmp_rx_key, pj_optarg,
545 ( int)strlen(pj_optarg));
546 pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2);
555 printf( "Invalid options %s\n", argv[pj_optind]);
564 if (remote_addr. sin_addr.s_addr == 0) {
565 printf( "Error: remote address must be set\n");
571 printf( "Direction is set to --send-only because of --play-file\n");
575#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
578 if (!srtp_tx_key. slen || !srtp_rx_key. slen)
580 printf( "Error: Key for each SRTP stream direction must be set\n");
620 status = init_codecs(&cp. factory);
630 &str_codec_id, &count,
633 printf( "Error: unable to find codec %s\n", codec_id);
642 codec_info = &info[0];
651 if (tx_size. w && tx_size. h)
654#if DEF_RENDERER_WIDTH && DEF_RENDERER_HEIGHT
662 if (play_file.file_name) {
668 status = create_file_player(pool, play_file.file_name, &play_port);
675 PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d %s @%.2ffps",
682 play_file.read_buf = pj_pool_zalloc(pool, play_file.read_buf_size);
704 status = play_decoder-> op-> init(play_decoder, pool);
715 status = play_decoder-> op-> open(play_decoder, &codec_param2);
727 (*dec_vfi-> apply_fmt)(dec_vfi, &dec_vafp);
739 &clock_cb, &play_file, &play_clock);
798 status = create_stream(pool, med_endpt, codec_info, &codec_param,
799 dir, rx_pt, tx_pt, local_port, &remote_addr,
800# if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
801 use_srtp, &srtp_crypto_suite,
802 &srtp_tx_key, &srtp_rx_key,
843 if (play_file.file_name) {
845#if HAS_LOCAL_RENDERER_FOR_PLAY_FILE
874 play_file.play_port = play_port;
875 play_file.stream_port = enc_port;
876 play_file.decoder = play_decoder;
889 printf( "Stream is active, dir is recv-only, local port is %d\n",
892 printf( "Stream is active, dir is send-only, sending to %s:%d\n",
897 printf( "Stream is active, send/recv, local port is %d, "
898 "sending to %s:%d\n",
905 PJ_LOG(2, (THIS_FILE, "Sending %dx%d %.*s @%.2ffps",
921 printf( "Command: "); fflush(stdout);
923 if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
924 puts( "EOF while reading stdin, will quit now..");
956 play_decoder-> op-> close(play_decoder);
1002int main( int argc, char *argv[])
1004 return pj_run_app(&main_func, argc, argv, 0);
1009int main( int argc, char *argv[])
1013 puts( "Error: this sample requires video capability (PJMEDIA_HAS_VIDEO == 1)");
pj_status_t pjmedia_endpt_create(pj_pool_factory *pf, pj_ioqueue_t *ioqueue, unsigned worker_cnt, pjmedia_endpt **p_endpt) Definition: endpoint.h:127
pj_status_t pjmedia_endpt_destroy(pjmedia_endpt *endpt) Definition: endpoint.h:168
pj_status_t pjmedia_vid_stream_destroy(pjmedia_vid_stream *stream)
pj_status_t pjmedia_vid_stream_get_port(pjmedia_vid_stream *stream, pjmedia_dir dir, pjmedia_port **p_port)
pj_status_t pjmedia_vid_stream_start(pjmedia_vid_stream *stream)
pj_status_t pjmedia_vid_stream_create(pjmedia_endpt *endpt, pj_pool_t *pool, pjmedia_vid_stream_info *info, pjmedia_transport *tp, void *user_data, pjmedia_vid_stream **p_stream)
pjmedia_transport * pjmedia_vid_stream_get_transport(pjmedia_vid_stream *st)
int pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[], unsigned flags)
pj_status_t pj_init(void)
unsigned short pj_uint16_t
void pj_caching_pool_destroy(pj_caching_pool *ch_pool)
void pj_caching_pool_init(pj_caching_pool *ch_pool, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
#define PJ_LOG(level, arg)
pj_pool_factory_policy pj_pool_factory_default_policy
pj_pool_t * pj_pool_create(pj_pool_factory *factory, const char *name, pj_size_t initial_size, pj_size_t increment_size, pj_pool_callback *callback)
void * pj_pool_zalloc(pj_pool_t *pool, pj_size_t size)
void pj_pool_release(pj_pool_t *pool)
void * pj_memcpy(void *dst, const void *src, pj_size_t size)
pj_str_t pj_str(char *str)
pj_str_t * pj_strset(pj_str_t *str, char *ptr, pj_size_t length)
void pj_bzero(void *dst, pj_size_t size)
#define PJ_INET_ADDRSTRLEN
pj_uint16_t pj_ntohs(pj_uint16_t netshort)
pj_status_t pj_sockaddr_in_init(pj_sockaddr_in *addr, const pj_str_t *cp, pj_uint16_t port)
char * pj_inet_ntop2(int af, const void *src, char *dst, int size)
#define PJ_ASSERT_RETURN(expr, retval)
#define PJ_UNUSED_ARG(arg)
unsigned pj_hex_digit_to_val(unsigned char c)
int pj_isxdigit(unsigned char c)
pj_status_t pjmedia_vid_dev_default_param(pj_pool_t *pool, pjmedia_vid_dev_index id, pjmedia_vid_dev_param *param)
pj_status_t pjmedia_vid_dev_subsys_shutdown(void)
pj_status_t pjmedia_vid_dev_subsys_init(pj_pool_factory *pf)
@ PJMEDIA_VID_DEV_WND_RESIZABLE Definition: pjmedia/videodev.h:137
@ PJMEDIA_VID_DEV_WND_BORDER Definition: pjmedia/videodev.h:132
@ PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS Definition: pjmedia/videodev.h:298
@ PJMEDIA_VID_DEFAULT_CAPTURE_DEV Definition: pjmedia/videodev.h:150
@ PJMEDIA_VID_DEFAULT_RENDER_DEV Definition: pjmedia/videodev.h:155
Secure RTP (SRTP) transport.
PJMEDIA small footprint Open Source media stack
Copyright (C) 2006-2008 Teluu Inc.
|