Ignore:
Timestamp:
Jul 12, 2011 3:05:35 AM (13 years ago)
Author:
bennylp
Message:

Initial implementation of re #1284 (Event Framework). Current event has been converted to the new framework. Next to convert is codec event

Location:
pjproject/branches/projects/2.0-dev
Files:
2 added
16 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjmedia/build/Makefile

    r3616 r3617  
    5858                        delaybuf.o echo_common.o \ 
    5959                        echo_port.o echo_suppress.o endpoint.o errno.o \ 
    60                         format.o ffmpeg_util.o \ 
     60                        event.o format.o ffmpeg_util.o \ 
    6161                        g711.o jbuf.o master_port.o mem_capture.o mem_player.o \ 
    6262                        null_port.o plc_common.o port.o splitcomb.o \ 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h

    r3592 r3617  
    2626#include <pjmedia-videodev/config.h> 
    2727#include <pjmedia-videodev/errno.h> 
     28#include <pjmedia/event.h> 
    2829#include <pjmedia/frame.h> 
    2930#include <pjmedia/format.h> 
     
    170171/** Forward declaration for pjmedia_vid_dev_stream */ 
    171172typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream; 
    172  
    173 typedef enum pjmedia_event_type 
    174 { 
    175     PJMEDIA_EVENT_NONE, 
    176     PJMEDIA_EVENT_FMT_CHANGED, 
    177     PJMEDIA_EVENT_MOUSEBUTTONDOWN, 
    178     PJMEDIA_EVENT_WINDOW_RESIZE, 
    179     PJMEDIA_EVENT_WINDOW_FULLSCREEN, 
    180     PJMEDIA_EVENT_WINDOW_CLOSE, 
    181 } pjmedia_event_type; 
    182  
    183 typedef struct pjmedia_vid_event 
    184 { 
    185     pjmedia_event_type event_type; 
    186     union { 
    187         struct resize_event { 
    188             pjmedia_rect_size new_size; 
    189         } resize; 
    190         struct fmt_changed_event { 
    191             pjmedia_format new_format; 
    192         } fmt_change; 
    193     } event_desc; 
    194 } pjmedia_vid_event; 
    195  
    196173 
    197174typedef struct pjmedia_vid_cb 
     
    235212                             pjmedia_frame *frame); 
    236213 
    237     /** 
    238     * This callback is called by the stream to report the occurence of an 
    239     * event to the application. 
    240     * 
    241     * @param stream        The video stream. 
    242     * @param user_data     User data associated with the stream. 
    243     * @param event         The event. 
    244     * 
    245     * @return              Return PJ_SUCCESS will invoke the video stream's 
    246     *                      default event-handler (if any), otherwise the 
    247     *                      video stream will ignore the particular event. 
    248     */ 
    249     pj_status_t (*on_event_cb)(pjmedia_vid_dev_stream *stream, 
    250                                void *user_data, 
    251                                pjmedia_vid_event *event); 
    252  
    253214} pjmedia_vid_cb; 
    254215 
     
    598559                                            pjmedia_vid_dev_stream *strm); 
    599560 
     561/** 
     562 * Get the event publisher object for the video stream. Caller typically use 
     563 * the returned object to subscribe or unsubscribe events from the video 
     564 * stream. 
     565 * 
     566 * @param strm      The video stream. 
     567 * 
     568 * @return          The event publisher object. 
     569 */ 
     570PJ_DECL(pjmedia_event_publisher*) 
     571pjmedia_vid_dev_stream_get_event_publisher(pjmedia_vid_dev_stream *strm); 
     572 
    600573/* Get/put frame API for passive stream */ 
    601574PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame( 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev_imp.h

    r3592 r3617  
    186186    /** Operations */ 
    187187    pjmedia_vid_dev_stream_op *op; 
     188 
     189    /** Event producer */ 
     190    pjmedia_event_publisher     epub; 
    188191}; 
    189192 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia.h

    r3615 r3617  
    3838#include <pjmedia/endpoint.h> 
    3939#include <pjmedia/errno.h> 
     40#include <pjmedia/event.h> 
    4041#include <pjmedia/frame.h> 
    4142#include <pjmedia/format.h> 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/vid_port.h

    r3615 r3617  
    106106 
    107107/** 
     108 * Get the event publisher instance of the video port. 
     109 * 
     110 * @param vid_port      The video port. 
     111 * 
     112 * @return              The event publisher of the video port. 
     113 */ 
     114PJ_DECL(pjmedia_event_publisher*) 
     115pjmedia_vid_port_get_event_publisher(pjmedia_vid_port *vid_port); 
     116 
     117/** 
    108118 * Return the underlying video stream of the video port. 
    109119 * 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/colorbar_dev.c

    r3592 r3617  
    417417    pj_memcpy(&strm->vafp, &vafp, sizeof(vafp)); 
    418418    strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1); 
     419    pjmedia_event_publisher_init(&strm->base.epub); 
    419420 
    420421    for (i = 0; i < vfi->plane_cnt; ++i) { 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c

    r3592 r3617  
    779779    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb)); 
    780780    strm->user_data = user_data; 
     781    pjmedia_event_publisher_init(&strm->base.epub); 
    781782 
    782783    if (param->dir & PJMEDIA_DIR_CAPTURE) { 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c

    r3592 r3617  
    385385    strm->pool = pool; 
    386386    pj_memcpy(&strm->param, param, sizeof(*param)); 
     387    pjmedia_event_publisher_init(&strm->base.epub); 
    387388 
    388389    /* Done */ 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ios_dev.m

    r3593 r3617  
    427427    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb)); 
    428428    strm->user_data = user_data; 
     429    pjmedia_event_publisher_init(&strm->base.epub); 
    429430 
    430431    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE); 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/qt_dev.m

    r3593 r3617  
    420420    strm->user_data = user_data; 
    421421    strm->apool = [[NSAutoreleasePool alloc]init]; 
     422    pjmedia_event_publisher_init(&strm->base.epub); 
    422423 
    423424    /* Create capture stream here */ 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c

    r3605 r3617  
    148148    pjmedia_format              *new_fmt; 
    149149    pjmedia_rect_size           *new_disp_size; 
     150    pj_timestamp                 last_ts; 
    150151 
    151152#if SDL_VERSION_ATLEAST(1,3,0) 
     
    684685{ 
    685686    struct sdl_stream *strm = (struct sdl_stream*)data; 
     687    pj_bool_t notify_wnd_closed_event = PJ_FALSE; 
     688    pj_status_t saved_stream_status; 
    686689#endif 
    687690 
     
    734737    { 
    735738        SDL_Event sevent; 
    736         pjmedia_vid_event pevent; 
     739        pjmedia_event pevent; 
    737740 
    738741#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
     
    752755         */ 
    753756        while (SDL_PollEvent(&sevent)) { 
    754             pj_bzero(&pevent, sizeof(pevent)); 
     757            pjmedia_event_init(&pevent, PJMEDIA_EVENT_NONE, &strm->last_ts, 
     758                               &strm->base.epub); 
    755759 
    756760            switch(sevent.type) { 
    757761                case SDL_MOUSEBUTTONDOWN: 
    758                     pevent.event_type = PJMEDIA_EVENT_MOUSEBUTTONDOWN; 
     762                    pevent.type = PJMEDIA_EVENT_MOUSE_BTN_DOWN; 
    759763                    break; 
    760764#if SDL_VERSION_ATLEAST(1,3,0) 
     
    762766                    switch (sevent.window.event) { 
    763767                        case SDL_WINDOWEVENT_RESIZED: 
    764                             pevent.event_type = PJMEDIA_EVENT_WINDOW_RESIZE; 
    765                             pevent.event_desc.resize.new_size.w = 
     768                            pevent.type = PJMEDIA_EVENT_WND_RESIZED; 
     769                            pevent.data.wnd_resized.new_size.w = 
    766770                                sevent.window.data1; 
    767                             pevent.event_desc.resize.new_size.h = 
     771                            pevent.data.wnd_resized.new_size.h = 
    768772                                sevent.window.data2; 
    769773                            break; 
     
    772776#else 
    773777                case SDL_VIDEORESIZE: 
    774                     pevent.event_type = PJMEDIA_EVENT_WINDOW_RESIZE; 
    775                     pevent.event_desc.resize.new_size.w = sevent.resize.w; 
    776                     pevent.event_desc.resize.new_size.h = sevent.resize.h; 
     778                    pevent.type = PJMEDIA_EVENT_WND_RESIZED; 
     779                    pevent.data.wnd_resized.new_size.w = sevent.resize.w; 
     780                    pevent.data.wnd_resized.new_size.h = sevent.resize.h; 
    777781                    break; 
    778782                case SDL_QUIT: 
    779                     pevent.event_type = PJMEDIA_EVENT_WINDOW_CLOSE; 
     783                    pevent.type = PJMEDIA_EVENT_WND_CLOSING; 
     784                    break; 
    780785#endif 
    781786            } 
    782787 
    783             switch (pevent.event_type) { 
    784                 case PJMEDIA_EVENT_MOUSEBUTTONDOWN: 
    785                     if (strm->vid_cb.on_event_cb) 
    786                         if ((*strm->vid_cb.on_event_cb)(&strm->base, 
    787                                                         strm->user_data, 
    788                                                         &pevent) != PJ_SUCCESS) 
    789                         { 
    790                             /* Application wants us to ignore this event */ 
    791                             break; 
    792                         } 
    793                     break; 
    794  
    795                 case PJMEDIA_EVENT_WINDOW_RESIZE: 
    796                     if (strm->vid_cb.on_event_cb) { 
    797                         if ((*strm->vid_cb.on_event_cb)(&strm->base, 
    798                                                         strm->user_data, 
    799                                                         &pevent) != PJ_SUCCESS) 
    800                         { 
    801                             break; 
    802                         } 
    803                     } 
    804                     strm->new_disp_size = &pevent.event_desc.resize.new_size; 
     788            if (pevent.type != PJMEDIA_EVENT_NONE) { 
     789                pj_status_t status; 
     790 
     791                status = pjmedia_event_publish(&strm->base.epub, &pevent); 
     792 
     793                switch (pevent.type) { 
     794                case PJMEDIA_EVENT_WND_RESIZED: 
     795                    strm->new_disp_size = &pevent.data.wnd_resized.new_size; 
    805796                    detect_fmt_change(strm); 
    806                     break; 
    807  
    808                 case PJMEDIA_EVENT_WINDOW_CLOSE: 
    809                     /** 
    810                      * To process PJMEDIA_EVENT_WINDOW_CLOSE event, 
    811                      * application should do this in the on_event_cb callback: 
    812                      * 1. stop further calls to  
    813                      *    #pjmedia_vid_dev_stream_put_frame() 
    814                      * 2. return PJ_SUCCESS 
    815                      * Upon returning from the callback, SDL will destroy its 
    816                      * own stream. 
    817                      * 
    818                      * Returning non-PJ_SUCCESS will cause SDL to ignore 
    819                      * the event 
    820                      */ 
    821                     if (strm->vid_cb.on_event_cb) { 
    822                         strm->is_quitting = PJ_TRUE; 
    823                         if ((*strm->vid_cb.on_event_cb)(&strm->base, 
    824                                                         strm->user_data, 
    825                                                         &pevent) != PJ_SUCCESS) 
    826                         { 
    827                             /* Application wants us to ignore this event */ 
    828                             strm->is_quitting = PJ_FALSE; 
    829                             break; 
    830                         } 
    831  
    832                         /* Destroy the stream */ 
    833                         sdl_stream_destroy(&strm->base); 
    834                         goto on_return; 
    835                     } 
    836  
    837                     /** 
    838                      * Default event-handler when there is no user-specified 
    839                      * callback: close the renderer window. We cannot destroy 
    840                      * the stream here since there is no callback to notify 
    841                      * the application. 
    842                      */ 
    843                     sdl_stream_stop(&strm->base); 
    844                     goto on_return; 
    845  
    846                 default: 
    847                     break; 
     797                    break; 
     798 
     799                case PJMEDIA_EVENT_WND_CLOSING: 
     800                    if (pevent.data.wnd_closing.cancel) { 
     801                        /* Cancel the closing operation */ 
     802                        break; 
     803                    } 
     804 
     805                    /* Proceed to cleanup SDL. App must still call 
     806                     * pjmedia_dev_stream_destroy() when getting WND_CLOSED 
     807                     * event 
     808                     */ 
     809                    strm->is_quitting = PJ_TRUE; 
     810                    notify_wnd_closed_event = PJ_TRUE; 
     811                    sdl_stream_stop(&strm->base); 
     812                    goto on_return; 
     813 
     814                default: 
     815                    /* Just to prevent gcc warning about unused enums */ 
     816                    break; 
     817                } 
    848818            } 
    849819        } 
     
    859829#endif 
    860830    strm->screen = NULL; 
    861  
    862     return strm->status; 
     831    saved_stream_status = strm->status; 
     832 
     833    if (notify_wnd_closed_event) { 
     834        pjmedia_event pevent; 
     835 
     836        pjmedia_event_init(&pevent, PJMEDIA_EVENT_WND_CLOSED, &strm->last_ts, 
     837                           &strm->base.epub); 
     838        pjmedia_event_publish(&strm->base.epub, &pevent); 
     839    } 
     840 
     841    /* 
     842     * Note: don't access the stream after this point, it  might have 
     843     * been destroyed 
     844     */ 
     845 
     846    return saved_stream_status; 
     847} 
     848 
     849static void hello_world() 
     850{ 
    863851} 
    864852 
     
    901889    struct sdl_stream *stream = (struct sdl_stream*)strm; 
    902890    pj_status_t status = PJ_SUCCESS; 
     891 
     892    stream->last_ts.u64 = frame->timestamp.u64; 
    903893 
    904894    if (!stream->is_running) { 
     
    10241014    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb)); 
    10251015    strm->user_data = user_data; 
     1016    pjmedia_event_publisher_init(&strm->base.epub); 
    10261017 
    10271018    /* Create render stream here */ 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/v4l2_dev.c

    r3592 r3617  
    574574    stream->user_data = user_data; 
    575575    stream->fd = INVALID_FD; 
     576    pjmedia_event_publisher_init(&stream->base.epub); 
    576577 
    577578    stream->fd = v4l2_open(vdi->dev_name, O_RDWR | O_NONBLOCK, 0); 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/videodev.c

    r3608 r3617  
    751751} 
    752752 
     753PJ_DEF(pjmedia_event_publisher*) 
     754pjmedia_vid_dev_stream_get_event_publisher(pjmedia_vid_dev_stream *strm) 
     755{ 
     756    return &strm->epub; 
     757} 
     758 
    753759/* API: Start the stream. */ 
    754760PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm) 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_port.c

    r3615 r3617  
    2121#include <pjmedia/converter.h> 
    2222#include <pjmedia/errno.h> 
     23#include <pjmedia/event.h> 
    2324#include <pjmedia/vid_codec.h> 
    2425#include <pj/log.h> 
     
    5657    pjmedia_conversion_param conv_param; 
    5758 
     59    pjmedia_event_publisher  epub; 
     60    pjmedia_event_subscription esub_dev; 
     61 
    5862    pjmedia_clock           *clock; 
    59  
    6063    pjmedia_clock_src        clocksrc; 
    6164 
     
    8689                                       void *user_data, 
    8790                                       pjmedia_frame *frame); 
    88 static pj_status_t vidstream_event_cb(pjmedia_vid_dev_stream *stream, 
    89                                       void *user_data, 
    90                                       pjmedia_vid_event *event); 
     91static pj_status_t vidstream_event_cb(pjmedia_event_subscription *esub, 
     92                                      pjmedia_event *event); 
    9193 
    9294static void enc_clock_cb(const pj_timestamp *ts, void *user_data); 
     
    152154    vp->dir = prm->vidparam.dir; 
    153155//    vp->cap_size = vfd->size; 
     156    pjmedia_event_publisher_init(&vp->epub); 
    154157 
    155158    vparam = prm->vidparam; 
     
    203206    vid_cb.capture_cb = &vidstream_cap_cb; 
    204207    vid_cb.render_cb = &vidstream_render_cb; 
    205     vid_cb.on_event_cb = &vidstream_event_cb; 
    206208 
    207209    status = pjmedia_vid_dev_stream_create(&vparam, &vid_cb, vp, 
     
    216218              vparam.fmt.det.vid.size.w, vparam.fmt.det.vid.size.h, 
    217219              vparam.fmt.det.vid.fps.num, vparam.fmt.det.vid.fps.denum)); 
     220 
     221    /* Subscribe to device's events */ 
     222    pjmedia_event_subscription_init(&vp->esub_dev, vidstream_event_cb, vp); 
     223    pjmedia_event_subscribe( 
     224            pjmedia_vid_dev_stream_get_event_publisher(vp->strm), 
     225            &vp->esub_dev); 
    218226 
    219227    if (vp->dir & PJMEDIA_DIR_CAPTURE) { 
     
    339347} 
    340348 
     349PJ_DEF(pjmedia_event_publisher*) 
     350pjmedia_vid_port_get_event_publisher(pjmedia_vid_port *vid_port) 
     351{ 
     352    PJ_ASSERT_RETURN(vid_port, NULL); 
     353    return &vid_port->epub; 
     354} 
     355 
    341356PJ_DEF(pjmedia_vid_dev_stream*) 
    342357pjmedia_vid_port_get_stream(pjmedia_vid_port *vp) 
     
    498513*/ 
    499514 
    500 static pj_status_t vidstream_event_cb(pjmedia_vid_dev_stream *stream, 
    501                                       void *user_data, 
    502                                       pjmedia_vid_event *event) 
    503 { 
    504     pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data; 
     515static pj_status_t vidstream_event_cb(pjmedia_event_subscription *esub, 
     516                                      pjmedia_event *event) 
     517{ 
     518    pjmedia_vid_port *vp = (pjmedia_vid_port*)esub->user_data; 
    505519     
    506     if (vp->strm_cb.on_event_cb) 
    507         return (*vp->strm_cb.on_event_cb)(stream, vp->strm_cb_data, event); 
    508     return PJ_SUCCESS; 
     520    /* Just republish the event to our client */ 
     521    return pjmedia_event_publish(&vp->epub, event); 
    509522} 
    510523 
     
    530543    if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) { 
    531544        const pjmedia_video_format_detail *vfd; 
    532         pjmedia_vid_event pevent; 
     545        pjmedia_event pevent; 
    533546        pj_status_t status; 
    534547 
     
    593606 
    594607        /* Notify application of the format change. */ 
    595         pevent.event_type = PJMEDIA_EVENT_FMT_CHANGED; 
    596         pjmedia_format_copy(&pevent.event_desc.fmt_change.new_format, 
     608        pjmedia_event_init(&pevent, PJMEDIA_EVENT_FMT_CHANGED, NULL, &vp->epub); 
     609        pjmedia_format_copy(&pevent.data.fmt_changed.new_fmt, 
    597610                            &vp->client_port->info.fmt); 
    598         if (vp->strm_cb.on_event_cb) 
    599             (*vp->strm_cb.on_event_cb)(vp->strm, vp->strm_cb_data, &pevent); 
     611        pjmedia_event_publish(&vp->epub, &pevent); 
    600612 
    601613        pjmedia_vid_port_start(vp); 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_dev_test.c

    r3579 r3617  
    7373} 
    7474 
    75 static pj_status_t vid_event_cb(pjmedia_vid_dev_stream *stream, 
    76                                 void *user_data, 
    77                                 pjmedia_vid_event *event) 
    78 { 
    79     PJ_UNUSED_ARG(stream); 
    80     PJ_UNUSED_ARG(user_data); 
    81      
    82     if (event->event_type == PJMEDIA_EVENT_WINDOW_CLOSE) 
     75static pj_status_t vid_event_cb(pjmedia_event_subscription *esub, 
     76                                pjmedia_event *event) 
     77{ 
     78    if (event->type == PJMEDIA_EVENT_WND_CLOSED) 
    8379        is_quitting = PJ_TRUE; 
    8480 
     
    9591    pjmedia_video_format_detail *vfd; 
    9692    pjmedia_vid_cb cb; 
     93    pjmedia_event_subscription esub; 
    9794    pj_status_t status; 
    9895    int rc = 0, i; 
     
    160157 
    161158    /* Set event handler */ 
    162     pj_bzero(&cb, sizeof(cb)); 
    163     cb.on_event_cb = vid_event_cb; 
    164     pjmedia_vid_port_set_cb(renderer, &cb, NULL); 
     159    pjmedia_event_subscription_init(&esub, &vid_event_cb, NULL); 
     160    pjmedia_event_subscribe( 
     161            pjmedia_vid_port_get_event_publisher(renderer), 
     162            &esub); 
    165163 
    166164    /* Connect capture to renderer */ 
  • pjproject/branches/projects/2.0-dev/pjsip-apps/src/samples/aviplay.c

    r3579 r3617  
    104104} codec_port_data_t; 
    105105 
    106 static pj_status_t avi_event_cb(pjmedia_vid_dev_stream *stream, 
    107                                 void *user_data, 
    108                                 pjmedia_vid_event *event) 
     106static pj_status_t avi_event_cb(pjmedia_event_subscription *esub, 
     107                                pjmedia_event *event) 
    109108{ 
    110     avi_port_t *ap = (avi_port_t *)user_data; 
    111      
    112     PJ_UNUSED_ARG(stream); 
    113      
    114     switch (event->event_type) { 
    115     case PJMEDIA_EVENT_WINDOW_CLOSE: 
     109    avi_port_t *ap = (avi_port_t *)esub->user_data; 
     110     
     111    switch (event->type) { 
     112    case PJMEDIA_EVENT_WND_CLOSED: 
    116113        ap->is_quitting = PJ_TRUE; 
    117114        break; 
    118     case PJMEDIA_EVENT_MOUSEBUTTONDOWN: 
     115    case PJMEDIA_EVENT_MOUSE_BTN_DOWN: 
    119116        if (ap->is_running) { 
    120117            pjmedia_vid_port_stop(ap->vid_port); 
     
    191188    pjmedia_port *vid_port = NULL, *aud_port = NULL; 
    192189    pjmedia_vid_codec *codec=NULL; 
     190    pjmedia_event_subscription esub; 
    193191    avi_port_t avi_port; 
    194192     
     
    395393         
    396394        pj_bzero(&cb, sizeof(cb)); 
    397         cb.on_event_cb = avi_event_cb; 
    398395        avi_port.snd_port = snd_port; 
    399396        avi_port.vid_port = renderer; 
    400397        avi_port.is_running = PJ_TRUE; 
    401398        pjmedia_vid_port_set_cb(renderer, &cb, &avi_port); 
     399 
     400        /* subscribe events */ 
     401        pjmedia_event_subscription_init(&esub, &avi_event_cb, &avi_port); 
     402        pjmedia_event_subscribe( 
     403                pjmedia_vid_port_get_event_publisher(renderer), 
     404                &esub); 
    402405 
    403406        if (snd_port) { 
Note: See TracChangeset for help on using the changeset viewer.