- Timestamp:
- Jul 12, 2011 9:08:56 AM (13 years ago)
- Location:
- pjproject/branches/projects/2.0-dev/pjmedia
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/event.h
r3617 r3622 103 103 typedef struct pjmedia_event_fmt_changed_data 104 104 { 105 /** 106 * The new media format. 107 */ 105 /** The media flow direction */ 106 pjmedia_dir dir; 107 108 /** The new media format. */ 108 109 pjmedia_format new_fmt; 109 110 } pjmedia_event_fmt_changed_data; … … 337 338 PJ_DECL(pj_status_t) pjmedia_event_unsubscribe(pjmedia_event_publisher *epub, 338 339 pjmedia_event_subscription *esub); 340 341 /** 342 * Check if the specified publisher has subscribers. 343 * 344 * @param epub The event publisher. 345 * 346 * @return PJ_TRUE if the publisher has at least one subscriber. 347 */ 348 PJ_DECL(pj_bool_t) 349 pjmedia_event_publisher_has_sub(pjmedia_event_publisher *epub); 339 350 340 351 /** -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/port.h
r3402 r3622 26 26 */ 27 27 #include <pjmedia/clock.h> 28 #include <pjmedia/event.h> 28 29 #include <pjmedia/format.h> 29 30 #include <pjmedia/frame.h> … … 399 400 pj_status_t (*on_destroy)(struct pjmedia_port *this_port); 400 401 402 /** 403 * Get event publisher for this media port, if any. 404 */ 405 pjmedia_event_publisher *(*get_event_pub)(struct pjmedia_port *this_port); 406 401 407 } pjmedia_port; 402 408 … … 478 484 pjmedia_frame *frame ); 479 485 486 /** 487 * Get the event publisher for the media port, if any. 488 * 489 * @param port The media port. 490 * 491 * @return The event publisher, or NULL if the port does not publish 492 * events. 493 */ 494 PJ_DECL(pjmedia_event_publisher*) 495 pjmedia_port_get_event_publisher(pjmedia_port *port); 480 496 481 497 /** -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/vid_codec.h
r3613 r3622 28 28 29 29 #include <pjmedia/codec.h> 30 #include <pjmedia/event.h> 30 31 #include <pjmedia/format.h> 31 32 #include <pjmedia/types.h> … … 99 100 100 101 /** 101 * Enumeration of video codec events.102 */103 typedef enum pjmedia_vid_codec_event104 {105 /**106 * Format changed event. The decoder output format is not really107 * configurable, so that the output format setting configured in the108 * initialization may be changed. Application can catch this event109 * by checking the bit_info field of the pjmedia_frame of the decoder110 * output frame.111 */112 PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED = 1,113 114 } pjmedia_vid_codec_event;115 116 117 /**118 102 * Forward declaration for video codec. 119 103 */ … … 269 253 * format may different to the current setting, e.g: the format specified 270 254 * in the #pjmedia_vid_codec_param when opening the codec, in this case the 271 * PJMEDIA_ VID_CODEC_EVENT_FMT_CHANGED flag will be set in the bit_info272 * field of the output frame and application can query the new format255 * PJMEDIA_EVENT_FMT_CHANGED event will be emitted by the codec. The codec 256 * parameter will also be updated, and application can query the format by 273 257 * using #get_param(). 274 258 * … … 310 294 311 295 /** 312 * This structure describes a video codec instance. 296 * This structure describes a video codec instance. Codec implementers 297 * should use #pjmedia_vid_codec_init() to initialize this structure with 298 * default values. 313 299 */ 314 300 struct pjmedia_vid_codec … … 325 311 /** Operations to codec. */ 326 312 pjmedia_vid_codec_op *op; 313 314 /** Event publisher object */ 315 pjmedia_event_publisher epub; 327 316 }; 328 317 … … 438 427 439 428 429 /** 430 * Initialize pjmedia_vid_codec structure with default values. 431 * 432 * @param codec The codec to be initialized. 433 */ 434 PJ_DECL(void) pjmedia_vid_codec_init(pjmedia_vid_codec *codec); 440 435 441 436 /** -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3563 r3622 879 879 /* Create pool for codec instance */ 880 880 pool = pj_pool_create(ffmpeg_factory.pf, "ffmpeg codec", 512, 512, NULL); 881 codec = PJ_POOL_ ZALLOC_T(pool, pjmedia_vid_codec);881 codec = PJ_POOL_ALLOC_T(pool, pjmedia_vid_codec); 882 882 if (!codec) { 883 883 status = PJ_ENOMEM; 884 884 goto on_error; 885 885 } 886 pjmedia_vid_codec_init(codec); 886 887 codec->op = &ffmpeg_op; 887 888 codec->factory = factory; … … 1404 1405 return status; 1405 1406 1406 /* Notify application via the bit_info field of pjmedia_frame */ 1407 output->bit_info = PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED; 1407 /* Broadcast event */ 1408 if (pjmedia_event_publisher_has_sub(&codec->epub)) { 1409 pjmedia_event event; 1410 1411 pjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED, 1412 &input->timestamp, &codec->epub); 1413 event.data.fmt_changed.dir = PJMEDIA_DIR_DECODING; 1414 pj_memcpy(&event.data.fmt_changed.new_fmt, &ff->param.dec_fmt, 1415 sizeof(ff->param.dec_fmt)); 1416 pjmedia_event_publish(&codec->epub, &event); 1417 } 1408 1418 } 1409 1419 -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/event.c
r3617 r3622 58 58 } 59 59 60 PJ_DEF(pj_bool_t) 61 pjmedia_event_publisher_has_sub(pjmedia_event_publisher *epub) 62 { 63 PJ_ASSERT_RETURN(epub, PJ_FALSE); 64 return epub->subscription_list.next && 65 (!pj_list_empty(&epub->subscription_list)); 66 } 67 60 68 PJ_DEF(pj_status_t) pjmedia_event_subscribe( pjmedia_event_publisher *epub, 61 69 pjmedia_event_subscription *esub) … … 88 96 89 97 esub = epub->subscription_list.next; 98 if (!esub) 99 return err; 100 90 101 while (esub != &epub->subscription_list) { 91 102 pjmedia_event_subscription *next; -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/port.c
r3402 r3622 118 118 } 119 119 120 /* 121 * Get event publisher 122 */ 123 PJ_DEF(pjmedia_event_publisher*) 124 pjmedia_port_get_event_publisher(pjmedia_port *port) 125 { 126 PJ_ASSERT_RETURN(port, NULL); 127 128 if (port->get_event_pub) 129 return (*port->get_event_pub)(port); 130 131 return NULL; 132 } 120 133 121 134 /** -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_codec.c
r3613 r3622 67 67 static void sort_codecs(pjmedia_vid_codec_mgr *mgr); 68 68 69 /* 70 * Initialize pjmedia_vid_codec structure with default values. 71 */ 72 PJ_DEF(void) pjmedia_vid_codec_init(pjmedia_vid_codec *codec) 73 { 74 pj_bzero(codec, sizeof(*codec)); 75 pj_list_init(&codec->epub); 76 } 69 77 70 78 /* -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_port.c
r3617 r3622 57 57 pjmedia_conversion_param conv_param; 58 58 59 pjmedia_event_publisher epub;59 pjmedia_event_publisher epub; 60 60 pjmedia_event_subscription esub_dev; 61 pjmedia_event_subscription esub_client_port; 61 62 62 63 pjmedia_clock *clock; … … 91 92 static pj_status_t vidstream_event_cb(pjmedia_event_subscription *esub, 92 93 pjmedia_event *event); 94 static pj_status_t client_port_event_cb(pjmedia_event_subscription *esub, 95 pjmedia_event *event); 93 96 94 97 static void enc_clock_cb(const pj_timestamp *ts, void *user_data); … … 398 401 pj_bool_t destroy) 399 402 { 403 pjmedia_event_publisher *epub; 404 400 405 PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL); 401 406 vp->destroy_client_port = destroy; 402 407 vp->client_port = port; 408 409 /* Subscribe to client port's events */ 410 epub = pjmedia_port_get_event_publisher(port); 411 if (epub) { 412 pjmedia_event_subscription_init(&vp->esub_client_port, 413 &client_port_event_cb, 414 vp); 415 pjmedia_event_subscribe(epub, &vp->esub_client_port); 416 } 403 417 return PJ_SUCCESS; 404 418 } … … 408 422 { 409 423 PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL); 410 vp->client_port = NULL; 424 425 if (vp->client_port) { 426 pjmedia_event_publisher *epub; 427 428 /* Unsubscribe event */ 429 epub = pjmedia_port_get_event_publisher(vp->client_port); 430 if (epub && vp->esub_client_port.user_data) { 431 pjmedia_event_unsubscribe(epub, &vp->esub_client_port); 432 pj_bzero(&vp->esub_client_port, sizeof(vp->esub_client_port)); 433 } 434 vp->client_port = NULL; 435 } 411 436 return PJ_SUCCESS; 412 437 } … … 513 538 */ 514 539 540 /* Handle event from vidstream */ 515 541 static pj_status_t vidstream_event_cb(pjmedia_event_subscription *esub, 516 542 pjmedia_event *event) … … 538 564 } 539 565 540 static pj_status_t detect_fmt_change(pjmedia_vid_port *vp, 541 pjmedia_frame *frame) 542 { 543 if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) { 566 static pj_status_t client_port_event_cb(pjmedia_event_subscription *esub, 567 pjmedia_event *event) 568 { 569 pjmedia_vid_port *vp = (pjmedia_vid_port*)esub->user_data; 570 571 if (event->type == PJMEDIA_EVENT_FMT_CHANGED) { 544 572 const pjmedia_video_format_detail *vfd; 545 pjmedia_event pevent;546 573 pj_status_t status; 574 575 ++event->proc_cnt; 547 576 548 577 pjmedia_vid_port_stop(vp); … … 605 634 } 606 635 607 /* Notify application of the format change. */608 pjmedia_event_init(&pevent, PJMEDIA_EVENT_FMT_CHANGED, NULL, &vp->epub);609 pjmedia_format_copy(&pevent.data.fmt_changed.new_fmt,610 &vp->client_port->info.fmt);611 pjmedia_event_publish(&vp->epub, &pevent);612 613 636 pjmedia_vid_port_start(vp); 614 637 } 615 638 616 return PJ_SUCCESS; 639 /* Republish the event */ 640 return pjmedia_event_publish(&vp->epub, event); 617 641 } 618 642 … … 752 776 } 753 777 754 status = detect_fmt_change(vp, vp->frm_buf);755 if (status != PJ_SUCCESS)756 return;757 758 778 pj_add_timestamp32(&vp->clocksrc.timestamp, 759 779 frame_ts); … … 771 791 pj_add_timestamp32(&vp->clocksrc.timestamp, frame_ts); 772 792 pjmedia_clock_src_update(&vp->clocksrc, NULL); 773 774 status = detect_fmt_change(vp, vp->frm_buf);775 if (status != PJ_SUCCESS)776 return;777 793 778 794 if (convert_frame(vp, vp->frm_buf, &frame) != PJ_SUCCESS) … … 821 837 if (vp->role==ROLE_ACTIVE) { 822 838 if (vp->client_port) { 823 pj_status_t status; 824 825 status = pjmedia_port_get_frame(vp->client_port, frame); 826 if (status != PJ_SUCCESS) 827 return status; 828 829 return detect_fmt_change(vp, frame); 839 return pjmedia_port_get_frame(vp->client_port, frame); 830 840 } 831 841 } else { -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c
r3534 r3622 19 19 #include <pjmedia/vid_stream.h> 20 20 #include <pjmedia/errno.h> 21 #include <pjmedia/event.h> 21 22 #include <pjmedia/rtp.h> 22 23 #include <pjmedia/rtcp.h> … … 135 136 pj_uint32_t last_dec_ts; /**< Last decoded timestamp. */ 136 137 int last_dec_seq; /**< Last decoded sequence. */ 138 139 pjmedia_event_subscription esub_codec; /**< To subscribe codec events */ 140 pjmedia_event_publisher epub; /**< To publish events */ 137 141 }; 138 142 … … 301 305 #endif /* TRACE_JB */ 302 306 307 static void dump_port_info(const pjmedia_vid_channel *chan, 308 const char *event_name) 309 { 310 const pjmedia_port_info *pi = &chan->port.info; 311 312 PJ_LOG(5, (pi->name.ptr, 313 " %s format %s: %dx%d %c%c%c%c%s %d/%d(~%d)fps", 314 (chan->dir==PJMEDIA_DIR_DECODING? "Decoding":"Encoding"), 315 event_name, 316 pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h, 317 ((pi->fmt.id & 0x000000FF) >> 0), 318 ((pi->fmt.id & 0x0000FF00) >> 8), 319 ((pi->fmt.id & 0x00FF0000) >> 16), 320 ((pi->fmt.id & 0xFF000000) >> 24), 321 (chan->dir==PJMEDIA_DIR_ENCODING?"->":"<-"), 322 pi->fmt.det.vid.fps.num, pi->fmt.det.vid.fps.denum, 323 pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum)); 324 } 325 326 /* 327 * Handle events from stream components. 328 */ 329 static pj_status_t stream_event_cb(pjmedia_event_subscription *esub, 330 pjmedia_event *event) 331 { 332 pjmedia_vid_stream *stream = (pjmedia_vid_stream*)esub->user_data; 333 334 if (esub == &stream->esub_codec) { 335 /* This is codec event */ 336 switch (event->type) { 337 case PJMEDIA_EVENT_FMT_CHANGED: 338 /* Update param from codec */ 339 stream->codec->op->get_param(stream->codec, stream->info.codec_param); 340 341 /* Update decoding channel port info */ 342 pjmedia_format_copy(&stream->dec->port.info.fmt, 343 &stream->info.codec_param->dec_fmt); 344 345 /* we process the event */ 346 ++event->proc_cnt; 347 348 dump_port_info(event->data.fmt_changed.dir==PJMEDIA_DIR_DECODING ? 349 stream->dec : stream->enc, 350 "changed"); 351 break; 352 default: 353 break; 354 } 355 } 356 357 return pjmedia_event_publish(&stream->epub, event); 358 } 359 360 static pjmedia_event_publisher *port_get_epub(pjmedia_port *port) 361 { 362 pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata; 363 return &stream->epub; 364 } 303 365 304 366 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0 … … 795 857 return PJ_SUCCESS; 796 858 } 797 798 859 799 860 static pj_status_t get_frame(pjmedia_port *port, … … 915 976 } 916 977 917 /* Check if the decoder format is changed */918 if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) {919 /* Update param from codec */920 stream->codec->op->get_param(stream->codec, stream->info.codec_param);921 922 /* Update decoding channel port info */923 pjmedia_format_copy(&channel->port.info.fmt,924 &stream->info.codec_param->dec_fmt);925 }926 927 978 /* Learn remote frame rate after successful decoding */ 928 979 if (0 && frame->type == PJMEDIA_FRAME_TYPE_VIDEO && frame->size) … … 950 1001 stream->info.codec_param->dec_fmt.det.vid.fps = vfd->fps; 951 1002 952 /* Set bit_info */ 953 frame->bit_info |= PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED; 954 955 PJ_LOG(5, (channel->port.info.name.ptr, "Frame rate changed to %.2ffps", 956 (1.0 * vfd->fps.num / vfd->fps.denum))); 1003 PJ_LOG(5, (channel->port.info.name.ptr, 1004 "Frame rate changed to %d/%d(~%d)fps", 1005 vfd->fps.num, vfd->fps.denum, 1006 vfd->fps.num / vfd->fps.denum)); 1007 1008 /* Publish PJMEDIA_EVENT_FMT_CHANGED event */ 1009 if (pjmedia_event_publisher_has_sub(&stream->epub)) { 1010 pjmedia_event event; 1011 1012 dump_port_info(stream->dec, "changed"); 1013 1014 pjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED, 1015 &frame_in.timestamp, &stream->epub); 1016 event.data.fmt_changed.dir = PJMEDIA_DIR_DECODING; 1017 pj_memcpy(&event.data.fmt_changed.new_fmt, 1018 &stream->info.codec_param->dec_fmt, 1019 sizeof(pjmedia_format)); 1020 pjmedia_event_publish(&stream->epub, &event); 1021 } 957 1022 } 958 1023 } … … 962 1027 stream->last_dec_ts = last_ts; 963 1028 } 964 965 #if PJ_LOG_MAX_LEVEL >= 5966 if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) {967 pjmedia_port_info *pi = &channel->port.info;968 969 PJ_LOG(5, (channel->port.info.name.ptr,970 "Decoding format changed to %dx%d %c%c%c%c %.2ffps",971 pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h,972 ((pi->fmt.id & 0x000000FF) >> 0),973 ((pi->fmt.id & 0x0000FF00) >> 8),974 ((pi->fmt.id & 0x00FF0000) >> 16),975 ((pi->fmt.id & 0xFF000000) >> 24),976 (1.0*pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum)));977 }978 #endif979 1029 980 1030 return PJ_SUCCESS; … … 1070 1120 /* Init port. */ 1071 1121 channel->port.port_data.pdata = stream; 1072 1073 PJ_LOG(5, (name.ptr, "%s channel created %dx%d %c%c%c%c%s%.*s %.2ffps", 1122 channel->port.get_event_pub = &port_get_epub; 1123 1124 PJ_LOG(5, (name.ptr, 1125 "%s channel created %dx%d %c%c%c%c%s%.*s %d/%d(~%d)fps", 1074 1126 (dir==PJMEDIA_DIR_ENCODING?"Encoding":"Decoding"), 1075 1127 pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h, … … 1081 1133 info->codec_info.encoding_name.slen, 1082 1134 info->codec_info.encoding_name.ptr, 1083 (1.0*pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum))); 1135 pi->fmt.det.vid.fps.num, pi->fmt.det.vid.fps.denum, 1136 pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum)); 1084 1137 1085 1138 /* Done. */ … … 1198 1251 if (status != PJ_SUCCESS) 1199 1252 return status; 1253 1254 /* Init event publisher and subscribe to codec events */ 1255 pjmedia_event_publisher_init(&stream->epub); 1256 pjmedia_event_subscription_init(&stream->esub_codec, &stream_event_cb, 1257 stream); 1258 pjmedia_event_subscribe(&stream->codec->epub, &stream->esub_codec); 1200 1259 1201 1260 /* Estimate the maximum frame size */ -
pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_codec_test.c
r3579 r3622 29 29 } codec_port_data_t; 30 30 31 static pj_status_t codec_on_event(pjmedia_event_subscription *esub, 32 pjmedia_event *event) 33 { 34 codec_port_data_t *port_data = (codec_port_data_t*)esub->user_data; 35 36 if (event->type == PJMEDIA_EVENT_FMT_CHANGED) { 37 pjmedia_vid_codec *codec = port_data->codec; 38 pjmedia_vid_codec_param codec_param; 39 pj_status_t status; 40 41 ++event->proc_cnt; 42 43 status = codec->op->get_param(codec, &codec_param); 44 if (status != PJ_SUCCESS) 45 return status; 46 47 status = pjmedia_vid_dev_stream_set_cap( 48 pjmedia_vid_port_get_stream(port_data->rdr_port), 49 PJMEDIA_VID_DEV_CAP_FORMAT, 50 &codec_param.dec_fmt); 51 if (status != PJ_SUCCESS) 52 return status; 53 } 54 55 return PJ_SUCCESS; 56 } 57 31 58 static pj_status_t codec_put_frame(pjmedia_port *port, 32 59 pjmedia_frame *frame) … … 48 75 #if !BYPASS_PACKETIZER 49 76 if (enc_frame.size) { 50 unsigned pos = 0 , i = 0;77 unsigned pos = 0; 51 78 pj_bool_t packetized = PJ_FALSE; 52 79 unsigned unpack_pos = 0; … … 59 86 (pj_uint8_t*)enc_frame.buf, 60 87 enc_frame.size, &pos, 61 &payload, &payload_len); 88 (const pj_uint8_t**)&payload, 89 &payload_len); 62 90 if (status == PJ_ENOTSUP) 63 91 break; … … 87 115 status = codec->op->decode(codec, &enc_frame, frame->size, frame); 88 116 if (status != PJ_SUCCESS) goto on_error; 89 90 /* Detect format change */91 if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) {92 pjmedia_vid_codec_param codec_param;93 94 status = codec->op->get_param(codec, &codec_param);95 if (status != PJ_SUCCESS) goto on_error;96 97 status = pjmedia_vid_dev_stream_set_cap(98 pjmedia_vid_port_get_stream(port_data->rdr_port),99 PJMEDIA_VID_DEV_CAP_FORMAT,100 &codec_param.dec_fmt);101 if (status != PJ_SUCCESS) goto on_error;102 }103 117 } 104 118 #endif … … 170 184 pjmedia_vid_port_param vport_param; 171 185 pjmedia_video_format_detail *vfd; 186 pjmedia_event_subscription esub; 172 187 pj_status_t status; 173 188 int rc = 0; … … 277 292 codec_param.dec_fmt.det = codec_param.enc_fmt.det; 278 293 294 /* Subscribe to codec events */ 295 pjmedia_event_subscription_init(&esub, &codec_on_event, 296 &codec_port_data); 297 pjmedia_event_subscribe(&codec->epub, &esub); 279 298 #endif /* !BYPASS_CODEC */ 280 299 } 281 282 300 283 301 pjmedia_vid_port_param_default(&vport_param); -
pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_dev_test.c
r3617 r3622 90 90 pjmedia_vid_port_param param; 91 91 pjmedia_video_format_detail *vfd; 92 pjmedia_vid_cb cb;93 92 pjmedia_event_subscription esub; 94 93 pj_status_t status;
Note: See TracChangeset
for help on using the changeset viewer.