Changeset 3623


Ignore:
Timestamp:
Jul 12, 2011 10:03:02 AM (8 years ago)
Author:
ming
Message:

Closed #1304: Video port refactoring

  • Refactor video port functions for active/passive role, active/passive stream role, encoding/decoding
  • Converter creation if necessary
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_port.c

    r3622 r3623  
    123123} 
    124124 
     125static pj_status_t create_converter(pjmedia_vid_port *vp) 
     126{ 
     127    /* Instantiate converter if necessary */ 
     128    if (vp->conv_param.src.id != vp->conv_param.dst.id || 
     129        vp->conv_param.src.det.vid.size.w != vp->conv_param.dst.det.vid.size.w || 
     130        vp->conv_param.src.det.vid.size.h != vp->conv_param.dst.det.vid.size.h) 
     131    { 
     132        pj_status_t status; 
     133 
     134        /* Yes, we need converter */ 
     135        const pjmedia_video_format_info *vfi; 
     136        pjmedia_video_apply_fmt_param vafp; 
     137 
     138        if (vp->conv) { 
     139            pjmedia_converter_destroy(vp->conv); 
     140            vp->conv = NULL; 
     141        } 
     142 
     143        status = pjmedia_converter_create(NULL, vp->pool, &vp->conv_param, 
     144                                          &vp->conv); 
     145        if (status != PJ_SUCCESS) { 
     146            PJ_PERROR(4,(THIS_FILE, status, "Error creating converter")); 
     147            return status; 
     148        } 
     149 
     150        /* Allocate buffer for conversion */ 
     151        vfi = pjmedia_get_video_format_info(NULL, vp->conv_param.dst.id); 
     152        if (!vfi) 
     153            return PJMEDIA_EBADFMT; 
     154 
     155        pj_bzero(&vafp, sizeof(vafp)); 
     156        vafp.size = vp->conv_param.dst.det.vid.size; 
     157        status = vfi->apply_fmt(vfi, &vafp); 
     158        if (status != PJ_SUCCESS) 
     159            return PJMEDIA_EBADFMT; 
     160 
     161        if (vafp.framebytes > vp->conv_buf_size) { 
     162            vp->conv_buf = pj_pool_alloc(vp->pool, vafp.framebytes); 
     163            vp->conv_buf_size = vafp.framebytes; 
     164        } 
     165    } 
     166 
     167    return PJ_SUCCESS; 
     168} 
     169 
    125170PJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool, 
    126171                                             const pjmedia_vid_port_param *prm, 
     
    153198    /* Allocate videoport */ 
    154199    vp = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_port); 
    155     vp->pool = pool; 
     200    vp->pool = pj_pool_create(pool->factory, "video port", 500, 500, NULL); 
    156201    vp->role = prm->active ? ROLE_ACTIVE : ROLE_PASSIVE; 
    157202    vp->dir = prm->vidparam.dir; 
     
    236281    } 
    237282 
    238     /* Instantiate converter if necessary */ 
    239     if (vparam.fmt.id != prm->vidparam.fmt.id || 
    240         vparam.fmt.det.vid.size.w != prm->vidparam.fmt.det.vid.size.w || 
    241         vparam.fmt.det.vid.size.h != prm->vidparam.fmt.det.vid.size.h /*|| 
    242         vparam.fmt.det.vid.fps.num != prm->vidparam.fmt.det.vid.fps.num || 
    243         vparam.fmt.det.vid.fps.denum != prm->vidparam.fmt.det.vid.fps.denum*/) 
    244     { 
    245         /* Yes, we need converter */ 
    246         const pjmedia_video_format_info *vfi; 
    247         pjmedia_video_apply_fmt_param vafp; 
    248  
    249         status = pjmedia_converter_create(NULL, pool, &vp->conv_param, 
    250                                           &vp->conv); 
    251         if (status != PJ_SUCCESS) { 
    252             PJ_PERROR(4,(THIS_FILE, status, "Error creating converter")); 
    253             goto on_error; 
    254         } 
    255  
    256         /* Allocate buffer for conversion */ 
    257         vfi = pjmedia_get_video_format_info(NULL, vp->conv_param.dst.id); 
    258         if (!vfi) 
    259             return PJMEDIA_EBADFMT; 
    260  
    261         pj_bzero(&vafp, sizeof(vafp)); 
    262         vafp.size = vp->conv_param.dst.det.vid.size; 
    263         status = vfi->apply_fmt(vfi, &vafp); 
    264         if (status != PJ_SUCCESS) 
    265             return PJMEDIA_EBADFMT; 
    266  
    267         vp->conv_buf = pj_pool_alloc(pool, vafp.framebytes); 
    268         vp->conv_buf_size = vafp.framebytes; 
    269     } 
     283    status = create_converter(vp); 
     284    if (status != PJ_SUCCESS) 
     285        goto on_error; 
    270286 
    271287    if (vp->role==ROLE_ACTIVE && vp->stream_role==ROLE_PASSIVE) { 
     
    489505    PJ_LOG(4,(THIS_FILE, "Closing %s..", vp->dev_name.ptr)); 
    490506 
     507    if (vp->conv) { 
     508        pjmedia_converter_destroy(vp->conv); 
     509        vp->conv = NULL; 
     510    } 
    491511    if (vp->clock) { 
    492512        pjmedia_clock_destroy(vp->clock); 
     
    506526        vp->frm_mutex = NULL; 
    507527    } 
     528    pj_pool_release(vp->pool); 
    508529} 
    509530 
     
    548569} 
    549570 
    550 static pj_status_t convert_frame(pjmedia_vid_port *vp, 
    551                                  pjmedia_frame *src_frame, 
    552                                  pjmedia_frame *dst_frame) 
    553 { 
    554     pj_status_t status = PJ_SUCCESS; 
    555  
    556     if (vp->conv) { 
    557         dst_frame->buf  = vp->conv_buf; 
    558         dst_frame->size = vp->conv_buf_size; 
    559         status = pjmedia_converter_convert(vp->conv, 
    560                                            src_frame, dst_frame); 
    561     } 
    562      
    563     return status; 
    564 } 
    565  
    566571static pj_status_t client_port_event_cb(pjmedia_event_subscription *esub, 
    567572                                        pjmedia_event *event) 
     
    572577        const pjmedia_video_format_detail *vfd; 
    573578        pj_status_t status; 
    574  
     579         
    575580        ++event->proc_cnt; 
    576581 
    577582        pjmedia_vid_port_stop(vp); 
    578  
     583         
    579584        /* Retrieve the video format detail */ 
    580         vfd = pjmedia_format_get_video_format_detail( 
    581                   &vp->client_port->info.fmt, PJ_TRUE); 
     585        vfd = pjmedia_format_get_video_format_detail(&vp->client_port->info.fmt, 
     586                                                    PJ_TRUE); 
    582587        if (!vfd) 
    583588            return PJMEDIA_EVID_BADFORMAT; 
    584589        pj_assert(vfd->fps.num); 
    585  
    586         if (vp->conv) { 
    587             /* Change the destination format to the new format */ 
    588             pjmedia_format_copy(&vp->conv_param.src, 
    589                                 &vp->client_port->info.fmt); 
    590             /* Only copy the size here */ 
    591             vp->conv_param.dst.det.vid.size = 
    592                 vp->client_port->info.fmt.det.vid.size, 
    593  
    594             /* Recreate converter */ 
    595             pjmedia_converter_destroy(vp->conv); 
    596             status = pjmedia_converter_create(NULL, vp->pool, 
    597                                               &vp->conv_param, 
    598                                               &vp->conv); 
    599             if (status != PJ_SUCCESS) { 
    600                 PJ_PERROR(4,(THIS_FILE, status, "Error recreating converter")); 
    601                 return status; 
    602             } 
    603         } else { 
    604             vp->conv_param.dst = vp->client_port->info.fmt; 
     590         
     591        /* Change the destination format to the new format */ 
     592        pjmedia_format_copy(&vp->conv_param.src, 
     593                            &vp->client_port->info.fmt); 
     594        /* Only copy the size here */ 
     595        vp->conv_param.dst.det.vid.size = 
     596        vp->client_port->info.fmt.det.vid.size, 
     597 
     598        status = create_converter(vp); 
     599        if (status != PJ_SUCCESS) { 
     600            PJ_PERROR(4,(THIS_FILE, status, "Error recreating converter")); 
     601            return status; 
    605602        } 
    606  
    607         status = pjmedia_vid_dev_stream_set_cap( 
    608                      vp->strm, 
    609                      PJMEDIA_VID_DEV_CAP_FORMAT, 
    610                      &vp->conv_param.dst); 
     603         
     604        status = pjmedia_vid_dev_stream_set_cap(vp->strm, 
     605                                                PJMEDIA_VID_DEV_CAP_FORMAT, 
     606                                                &vp->conv_param.dst); 
    611607        if (status != PJ_SUCCESS) { 
    612608            PJ_LOG(3, (THIS_FILE, "failure in changing the format of the " 
    613                                   "video device")); 
     609                       "video device")); 
    614610            PJ_LOG(3, (THIS_FILE, "reverting to its original format: %s", 
    615                                   status != PJMEDIA_EVID_ERR ? "success" : 
    616                                   "failure")); 
     611                       status != PJMEDIA_EVID_ERR ? "success" : 
     612                       "failure")); 
    617613            return status; 
    618614        } 
    619  
     615         
    620616        if (vp->stream_role == ROLE_PASSIVE) { 
    621617            pjmedia_vid_param vid_param; 
    622618            pjmedia_clock_param clock_param; 
    623  
     619             
    624620            /** 
    625621             * Initially, frm_buf was allocated the biggest 
     
    633629            pjmedia_clock_modify(vp->clock, &clock_param); 
    634630        } 
    635  
     631         
    636632        pjmedia_vid_port_start(vp); 
    637633    } 
    638  
     634     
    639635    /* Republish the event */ 
    640636    return pjmedia_event_publish(&vp->epub, event); 
     637} 
     638 
     639static pj_status_t convert_frame(pjmedia_vid_port *vp, 
     640                                 pjmedia_frame *src_frame, 
     641                                 pjmedia_frame *dst_frame) 
     642{ 
     643    pj_status_t status = PJ_SUCCESS; 
     644 
     645    if (vp->conv) { 
     646        dst_frame->buf  = vp->conv_buf; 
     647        dst_frame->size = vp->conv_buf_size; 
     648        status = pjmedia_converter_convert(vp->conv, 
     649                                           src_frame, dst_frame); 
     650    } 
     651     
     652    return status; 
     653} 
     654 
     655/* Copy frame to buffer. */ 
     656static void copy_frame_to_buffer(pjmedia_vid_port *vp, 
     657                                        pjmedia_frame *frame) 
     658{ 
     659    pj_mutex_lock(vp->frm_mutex); 
     660    pjmedia_frame_copy(vp->frm_buf, frame); 
     661    pj_mutex_unlock(vp->frm_mutex); 
     662} 
     663 
     664/* Get frame from buffer and convert it if necessary. */ 
     665static pj_status_t get_frame_from_buffer(pjmedia_vid_port *vp, 
     666                                         pjmedia_frame *frame) 
     667{ 
     668    pj_status_t status = PJ_SUCCESS; 
     669 
     670    pj_mutex_lock(vp->frm_mutex); 
     671    if (vp->conv) 
     672        status = convert_frame(vp, vp->frm_buf, frame); 
     673    else 
     674        pjmedia_frame_copy(frame, vp->frm_buf); 
     675    pj_mutex_unlock(vp->frm_mutex); 
     676     
     677    return status; 
    641678} 
    642679 
     
    647684     */ 
    648685    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data; 
    649     pjmedia_frame frame; 
    650686    pj_status_t status; 
    651687 
     
    664700    //save_rgb_frame(vp->cap_size.w, vp->cap_size.h, vp->frm_buf); 
    665701 
    666     if (convert_frame(vp, vp->frm_buf, &frame) != PJ_SUCCESS) 
    667         return; 
    668  
    669     status = pjmedia_port_put_frame(vp->client_port, 
    670                                     (vp->conv? &frame: vp->frm_buf)); 
     702    vidstream_cap_cb(vp->strm, vp, vp->frm_buf); 
    671703} 
    672704 
     
    679711    pj_status_t status; 
    680712    pjmedia_frame frame; 
    681     unsigned frame_ts = vp->clocksrc.clock_rate / 1000 * 
    682                         vp->clocksrc.ptime_usec / 1000; 
    683713 
    684714    pj_assert(vp->role==ROLE_ACTIVE && vp->stream_role==ROLE_PASSIVE); 
     
    689719        return; 
    690720 
    691     if (vp->sync_clocksrc.sync_clocksrc) { 
    692         pjmedia_clock_src *src = vp->sync_clocksrc.sync_clocksrc; 
    693         pj_int32_t diff; 
    694         unsigned nsync_frame; 
    695  
    696         /* Synchronization */ 
    697         /* Calculate the time difference (in ms) with the sync source */ 
    698         diff = pjmedia_clock_src_get_time_msec(&vp->clocksrc) - 
    699                pjmedia_clock_src_get_time_msec(src) - 
    700                vp->sync_clocksrc.sync_delta; 
    701  
    702         /* Check whether sync source made a large jump */ 
    703         if (diff < 0 && -diff > PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC) { 
    704             pjmedia_clock_src_update(&vp->clocksrc, NULL); 
    705             vp->sync_clocksrc.sync_delta =  
    706                 pjmedia_clock_src_get_time_msec(src) - 
    707                 pjmedia_clock_src_get_time_msec(&vp->clocksrc); 
    708             vp->sync_clocksrc.nsync_frame = 0; 
    709             return; 
    710         } 
    711  
    712         /* Calculate the difference (in frames) with the sync source */ 
    713         nsync_frame = abs(diff) * 1000 / vp->clocksrc.ptime_usec; 
    714         if (nsync_frame == 0) { 
    715             /* Nothing to sync */ 
    716             vp->sync_clocksrc.nsync_frame = 0; 
    717         } else { 
    718             pj_int32_t init_sync_frame = nsync_frame; 
    719  
    720             /* Check whether it's a new sync or whether we need to reset 
    721              * the sync 
    722              */ 
    723             if (vp->sync_clocksrc.nsync_frame == 0 || 
    724                 (vp->sync_clocksrc.nsync_frame > 0 && 
    725                  nsync_frame > vp->sync_clocksrc.nsync_frame)) 
    726             { 
    727                 vp->sync_clocksrc.nsync_frame = nsync_frame; 
    728                 vp->sync_clocksrc.nsync_progress = 0; 
    729             } else { 
    730                 init_sync_frame = vp->sync_clocksrc.nsync_frame; 
    731             } 
    732  
    733             if (diff >= 0) { 
    734                 unsigned skip_mod; 
    735  
    736                 /* We are too fast */ 
    737                 if (vp->sync_clocksrc.max_sync_ticks > 0) { 
    738                     skip_mod = init_sync_frame /  
    739                                vp->sync_clocksrc.max_sync_ticks + 2; 
    740                 } else 
    741                     skip_mod = init_sync_frame + 2; 
    742  
    743                 PJ_LOG(5, (THIS_FILE, "synchronization: early by %d ms", 
    744                            diff)); 
    745                 /* We'll play a frame every skip_mod-th tick instead of 
    746                  * a complete pause 
    747                  */ 
    748                 if (++vp->sync_clocksrc.nsync_progress % skip_mod > 0) { 
    749                     pjmedia_clock_src_update(&vp->clocksrc, NULL); 
    750                     return; 
    751                 } 
    752             } else { 
    753                 unsigned i, ndrop = init_sync_frame; 
    754  
    755                 /* We are too late, drop the frame */ 
    756                 if (vp->sync_clocksrc.max_sync_ticks > 0) { 
    757                     ndrop /= vp->sync_clocksrc.max_sync_ticks; 
    758                     ndrop++; 
    759                 } 
    760                 PJ_LOG(5, (THIS_FILE, "synchronization: late, " 
    761                                       "dropping %d frame(s)", ndrop)); 
    762  
    763                 if (ndrop >= nsync_frame) { 
    764                     vp->sync_clocksrc.nsync_frame = 0; 
    765                     ndrop = nsync_frame; 
    766                 } else 
    767                     vp->sync_clocksrc.nsync_progress += ndrop; 
    768  
    769                 for (i = 0; i < ndrop; i++) { 
    770                     vp->frm_buf->size = vp->frm_buf_size; 
    771                     status = pjmedia_port_get_frame(vp->client_port, 
    772                                                     vp->frm_buf); 
    773                     if (status != PJ_SUCCESS) { 
    774                         pjmedia_clock_src_update(&vp->clocksrc, NULL); 
    775                         return; 
    776                     } 
    777  
    778                     pj_add_timestamp32(&vp->clocksrc.timestamp, 
    779                                        frame_ts); 
    780                 } 
    781             } 
    782         } 
    783     } 
    784  
    785     vp->frm_buf->size = vp->frm_buf_size; 
    786     status = pjmedia_port_get_frame(vp->client_port, vp->frm_buf); 
    787     if (status != PJ_SUCCESS) { 
    788         pjmedia_clock_src_update(&vp->clocksrc, NULL); 
    789         return; 
    790     } 
    791     pj_add_timestamp32(&vp->clocksrc.timestamp, frame_ts); 
    792     pjmedia_clock_src_update(&vp->clocksrc, NULL); 
    793  
    794     if (convert_frame(vp, vp->frm_buf, &frame) != PJ_SUCCESS) 
     721    status = vidstream_render_cb(vp->strm, vp, &frame); 
     722    if (status != PJ_SUCCESS) 
    795723        return; 
    796  
    797     status = pjmedia_vid_dev_stream_put_frame(vp->strm, 
    798                                               (vp->conv? &frame: vp->frm_buf)); 
     724     
     725    status = pjmedia_vid_dev_stream_put_frame(vp->strm, &frame); 
    799726} 
    800727 
     
    814741 
    815742        if (vp->client_port) 
    816             return pjmedia_port_put_frame(vp->client_port,  
     743            status = pjmedia_port_put_frame(vp->client_port,  
    817744                                          (vp->conv? &frame_: frame)); 
     745        if (status != PJ_SUCCESS) 
     746            return status; 
    818747    } else { 
    819         pj_mutex_lock(vp->frm_mutex); 
    820         pjmedia_frame_copy(vp->frm_buf, frame); 
    821         pj_mutex_unlock(vp->frm_mutex); 
    822     } 
    823 /* 
     748        /* We are passive while the stream is active so we just store the 
     749         * frame in the buffer. 
     750         * The decoding counterpart is located in vid_pasv_port_put_frame() 
     751         */ 
     752        copy_frame_to_buffer(vp, frame); 
     753    } 
     754    /* This is tricky since the frame is still in its original unconverted 
     755     * format, which may not be what the application expects. 
     756     */ 
    824757    if (vp->strm_cb.capture_cb) 
    825758        return (*vp->strm_cb.capture_cb)(stream, vp->strm_cb_data, frame); 
    826  */ 
    827759    return PJ_SUCCESS; 
    828760} 
     
    836768     
    837769    if (vp->role==ROLE_ACTIVE) { 
    838         if (vp->client_port) { 
    839             return pjmedia_port_get_frame(vp->client_port, frame); 
     770        unsigned frame_ts = vp->clocksrc.clock_rate / 1000 * 
     771                            vp->clocksrc.ptime_usec / 1000; 
     772 
     773        if (!vp->client_port) 
     774            return status; 
     775         
     776        if (vp->sync_clocksrc.sync_clocksrc) { 
     777            pjmedia_clock_src *src = vp->sync_clocksrc.sync_clocksrc; 
     778            pj_int32_t diff; 
     779            unsigned nsync_frame; 
     780             
     781            /* Synchronization */ 
     782            /* Calculate the time difference (in ms) with the sync source */ 
     783            diff = pjmedia_clock_src_get_time_msec(&vp->clocksrc) - 
     784                   pjmedia_clock_src_get_time_msec(src) - 
     785                   vp->sync_clocksrc.sync_delta; 
     786             
     787            /* Check whether sync source made a large jump */ 
     788            if (diff < 0 && -diff > PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC) { 
     789                pjmedia_clock_src_update(&vp->clocksrc, NULL); 
     790                vp->sync_clocksrc.sync_delta =  
     791                    pjmedia_clock_src_get_time_msec(src) - 
     792                    pjmedia_clock_src_get_time_msec(&vp->clocksrc); 
     793                vp->sync_clocksrc.nsync_frame = 0; 
     794                return status; 
     795            } 
     796             
     797            /* Calculate the difference (in frames) with the sync source */ 
     798            nsync_frame = abs(diff) * 1000 / vp->clocksrc.ptime_usec; 
     799            if (nsync_frame == 0) { 
     800                /* Nothing to sync */ 
     801                vp->sync_clocksrc.nsync_frame = 0; 
     802            } else { 
     803                pj_int32_t init_sync_frame = nsync_frame; 
     804                 
     805                /* Check whether it's a new sync or whether we need to reset 
     806                 * the sync 
     807                 */ 
     808                if (vp->sync_clocksrc.nsync_frame == 0 || 
     809                    (vp->sync_clocksrc.nsync_frame > 0 && 
     810                     nsync_frame > vp->sync_clocksrc.nsync_frame)) 
     811                { 
     812                    vp->sync_clocksrc.nsync_frame = nsync_frame; 
     813                    vp->sync_clocksrc.nsync_progress = 0; 
     814                } else { 
     815                    init_sync_frame = vp->sync_clocksrc.nsync_frame; 
     816                } 
     817                 
     818                if (diff >= 0) { 
     819                    unsigned skip_mod; 
     820                     
     821                    /* We are too fast */ 
     822                    if (vp->sync_clocksrc.max_sync_ticks > 0) { 
     823                        skip_mod = init_sync_frame /  
     824                        vp->sync_clocksrc.max_sync_ticks + 2; 
     825                    } else 
     826                        skip_mod = init_sync_frame + 2; 
     827                     
     828                    PJ_LOG(5, (THIS_FILE, "synchronization: early by %d ms", 
     829                               diff)); 
     830                    /* We'll play a frame every skip_mod-th tick instead of 
     831                     * a complete pause 
     832                     */ 
     833                    if (++vp->sync_clocksrc.nsync_progress % skip_mod > 0) { 
     834                        pjmedia_clock_src_update(&vp->clocksrc, NULL); 
     835                        return status; 
     836                    } 
     837                } else { 
     838                    unsigned i, ndrop = init_sync_frame; 
     839                     
     840                    /* We are too late, drop the frame */ 
     841                    if (vp->sync_clocksrc.max_sync_ticks > 0) { 
     842                        ndrop /= vp->sync_clocksrc.max_sync_ticks; 
     843                        ndrop++; 
     844                    } 
     845                    PJ_LOG(5, (THIS_FILE, "synchronization: late, " 
     846                               "dropping %d frame(s)", ndrop)); 
     847                     
     848                    if (ndrop >= nsync_frame) { 
     849                        vp->sync_clocksrc.nsync_frame = 0; 
     850                        ndrop = nsync_frame; 
     851                    } else 
     852                        vp->sync_clocksrc.nsync_progress += ndrop; 
     853                     
     854                    for (i = 0; i < ndrop; i++) { 
     855                        vp->frm_buf->size = vp->frm_buf_size; 
     856                        status = pjmedia_port_get_frame(vp->client_port, 
     857                                                        vp->frm_buf); 
     858                        if (status != PJ_SUCCESS) { 
     859                            pjmedia_clock_src_update(&vp->clocksrc, NULL); 
     860                            return status; 
     861                        } 
     862                         
     863                        pj_add_timestamp32(&vp->clocksrc.timestamp, 
     864                                           frame_ts); 
     865                    } 
     866                } 
     867            } 
    840868        } 
     869         
     870        vp->frm_buf->size = vp->frm_buf_size; 
     871        status = pjmedia_port_get_frame(vp->client_port, vp->frm_buf); 
     872        if (status != PJ_SUCCESS) { 
     873            pjmedia_clock_src_update(&vp->clocksrc, NULL); 
     874            return status; 
     875        } 
     876        pj_add_timestamp32(&vp->clocksrc.timestamp, frame_ts); 
     877        pjmedia_clock_src_update(&vp->clocksrc, NULL); 
     878 
     879        frame = vp->frm_buf; 
     880        if (convert_frame(vp, vp->frm_buf, frame) != PJ_SUCCESS) 
     881            return status; 
    841882    } else { 
    842         pj_mutex_lock(vp->frm_mutex); 
    843         if (vp->conv) 
    844             status = convert_frame(vp, vp->frm_buf, frame); 
    845         else 
    846             pjmedia_frame_copy(frame, vp->frm_buf); 
    847         pj_mutex_unlock(vp->frm_mutex); 
     883        /* The stream is active while we are passive so we need to get the 
     884         * frame from the buffer. 
     885         * The encoding counterpart is located in vid_pasv_port_get_frame() 
     886         */ 
     887        get_frame_from_buffer(vp, frame); 
    848888    } 
    849889    if (vp->strm_cb.render_cb) 
     
    859899 
    860900    if (vp->stream_role==ROLE_PASSIVE) { 
     901        /* We are passive and the stream is passive. 
     902         * The encoding counterpart is in vid_pasv_port_get_frame(). 
     903         */ 
    861904        pj_status_t status; 
    862905        pjmedia_frame frame_; 
     
    869912                                                (vp->conv? &frame_: frame)); 
    870913    } else { 
    871         pj_mutex_lock(vp->frm_mutex); 
    872         pjmedia_frame_copy(vp->frm_buf, frame); 
    873         pj_mutex_unlock(vp->frm_mutex); 
     914        /* We are passive while the stream is active so we just store the 
     915         * frame in the buffer. 
     916         * The encoding counterpart is located in vidstream_cap_cb() 
     917         */ 
     918        copy_frame_to_buffer(vp, frame); 
    874919    } 
    875920 
     
    885930 
    886931    if (vp->stream_role==ROLE_PASSIVE) { 
     932        /* We are passive and the stream is passive. 
     933         * The decoding counterpart is in vid_pasv_port_put_frame(). 
     934         */ 
    887935        status = pjmedia_vid_dev_stream_get_frame(vp->strm, 
    888936                                                  (vp->conv? vp->frm_buf: 
     
    893941        status = convert_frame(vp, vp->frm_buf, frame); 
    894942    } else { 
    895         pj_mutex_lock(vp->frm_mutex); 
    896         if (vp->conv) 
    897             status = convert_frame(vp, vp->frm_buf, frame); 
    898         else 
    899             pjmedia_frame_copy(frame, vp->frm_buf); 
    900         pj_mutex_unlock(vp->frm_mutex); 
     943        /* The stream is active while we are passive so we need to get the 
     944         * frame from the buffer. 
     945         * The decoding counterpart is located in vidstream_rend_cb() 
     946         */ 
     947        get_frame_from_buffer(vp, frame); 
    901948    } 
    902949 
Note: See TracChangeset for help on using the changeset viewer.