Changeset 3470


Ignore:
Timestamp:
Mar 22, 2011 9:46:04 AM (10 years ago)
Author:
nanang
Message:

Re #1213:

  • Added encoding format conversion (only format ID) in video port.
  • Fixed few bugs in direct show capture device:
    • VIDEOINFOHEADER.AvgTimePerFrame? calculation overflow which caused failure in opening capture device.
    • AM_MEDIA_TYPE.formattype validation to avoid bad type casting (of VIDEOINFOHEADER).
Location:
pjproject/branches/projects/2.0-dev/pjmedia/src
Files:
3 edited

Legend:

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

    r3459 r3470  
    611611 
    612612                    for (i = 0; i < icount; i++) { 
    613                         RPC_STATUS rpcstatus; 
     613                        RPC_STATUS rpcstatus, rpcstatus2; 
    614614 
    615615                        hr = IAMStreamConfig_GetStreamCaps(streamcaps, i, 
     
    619619                            continue; 
    620620 
    621                         if (UuidCompare(&mediatype->subtype, 
    622                                         (UUID *)dshow_format, 
    623                                         &rpcstatus) == 0 && 
    624                             rpcstatus == RPC_S_OK) 
     621                        if (UuidCompare(&mediatype->subtype,  
     622                                        (UUID*)dshow_format, 
     623                                        &rpcstatus) == 0 &&  
     624                            rpcstatus == RPC_S_OK && 
     625                            UuidCompare(&mediatype->formattype, 
     626                                        (UUID*)&FORMAT_VideoInfo, 
     627                                        &rpcstatus2) == 0 && 
     628                            rpcstatus2 == RPC_S_OK) 
    625629                        { 
    626630                            srcpin = pPin; 
    627631                            graph->mediatype = mediatype; 
    628                             break; 
     632                            break; 
    629633                        } 
    630634                    } 
     
    674678    if (vfd->fps.num != 0) 
    675679        video_info->AvgTimePerFrame = (LONGLONG) (10000000 *  
    676                                       vfd->fps.denum / 
    677                                       (double)vfd->fps.num); 
     680                                                  (double)vfd->fps.denum / 
     681                                                  vfd->fps.num); 
    678682    video_info->bmiHeader.biSizeImage = DIBSIZE(video_info->bmiHeader); 
    679683    mediatype->lSampleSize = DIBSIZE(video_info->bmiHeader); 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshowclasses.cpp

    r3392 r3470  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
    1818 */ 
    19 #undef _DEBUG 
    20 #undef DEBUG 
     19 
     20#include <pjmedia-videodev/config.h> 
     21 
     22#if PJMEDIA_VIDEO_DEV_HAS_DSHOW 
    2123 
    2224#include <streams.h> 
    2325 
    24 #pragma comment(lib, "Strmbase.lib") 
     26#if PJ_DEBUG 
     27#   pragma comment(lib, "Strmbasd.lib") 
     28#else 
     29#   pragma comment(lib, "Strmbase.lib") 
     30#endif 
    2531 
    2632typedef void (*input_callback)(void *user_data, IMediaSample *pMediaSample); 
     
    208214    ((OutputPin *)src->GetPin(0))->bufSize = size; 
    209215} 
     216 
     217#endif  /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */ 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/videoport.c

    r3459 r3470  
    1919#include <pjmedia/videoport.h> 
    2020#include <pjmedia/clock.h> 
     21#include <pjmedia/converter.h> 
     22#include <pjmedia/errno.h> 
    2123#include <pjmedia/vid_codec.h> 
    2224#include <pj/log.h> 
     
    4850    pj_bool_t            destroy_client_port; 
    4951 
     52    pjmedia_converter   *cap_conv; 
     53    void                *cap_conv_buf; 
     54    pj_size_t            cap_conv_buf_size; 
     55 
    5056    pjmedia_clock       *enc_clock, 
    5157                        *dec_clock; 
     
    116122    pj_status_t status; 
    117123    unsigned ptime_usec; 
     124    pjmedia_vid_param vparam; 
    118125 
    119126    PJ_ASSERT_RETURN(pool && prm && p_vid_port, PJ_EINVAL); 
     
    152159        return status; 
    153160 
     161    vparam = prm->vidparam; 
     162 
     163    /* Check if we need converter */ 
     164    if (vp->dir & PJMEDIA_DIR_CAPTURE) { 
     165        unsigned i; 
     166 
     167        for (i = 0; i < di.fmt_cnt; ++i) { 
     168            if (prm->vidparam.fmt.id == di.fmt[i].id) 
     169                break; 
     170        } 
     171 
     172        if (i == di.fmt_cnt) { 
     173            /* Yes, we need converter */ 
     174            pjmedia_conversion_param conv_param; 
     175            const pjmedia_video_format_info *vfi; 
     176            pjmedia_video_apply_fmt_param vafp; 
     177 
     178            pjmedia_format_copy(&conv_param.src, &prm->vidparam.fmt); 
     179            pjmedia_format_copy(&conv_param.dst, &prm->vidparam.fmt); 
     180            for (i = 0; i < di.fmt_cnt; ++i) { 
     181                conv_param.src.id = di.fmt[i].id; 
     182                status = pjmedia_converter_create(NULL, pool, &conv_param,  
     183                                                  &vp->cap_conv); 
     184                if (status == PJ_SUCCESS) 
     185                    break; 
     186            } 
     187            if (status != PJ_SUCCESS) 
     188                return status; 
     189 
     190            /* Update format ID for the capture device */ 
     191            vparam.fmt.id = conv_param.src.id; 
     192 
     193            /* Allocate buffer for conversion */ 
     194            vfi = pjmedia_get_video_format_info(NULL, conv_param.dst.id); 
     195            if (!vfi) 
     196                return PJMEDIA_EBADFMT; 
     197 
     198            pj_bzero(&vafp, sizeof(vafp)); 
     199            vafp.size = vfd->size; 
     200            status = vfi->apply_fmt(vfi, &vafp); 
     201            if (status != PJ_SUCCESS) 
     202                return PJMEDIA_EBADFMT; 
     203 
     204            vp->cap_conv_buf = pj_pool_alloc(pool, vafp.framebytes); 
     205            vp->cap_conv_buf_size = vafp.framebytes; 
     206        } 
     207    } 
     208 
    154209    PJ_LOG(4,(THIS_FILE, "Opening %s..", di.name)); 
    155210 
     
    175230    vid_cb.on_event_cb = &vidstream_event_cb; 
    176231 
    177     status = pjmedia_vid_dev_stream_create(&prm->vidparam, &vid_cb, vp, 
     232    status = pjmedia_vid_dev_stream_create(&vparam, &vid_cb, vp, 
    178233                                           &vp->strm); 
    179234    if (status != PJ_SUCCESS) 
     
    222277                                prm->vidparam.dir, &prm->vidparam.fmt); 
    223278 
    224         if (vp->stream_role == ROLE_ACTIVE) { 
     279        if (vp->stream_role == ROLE_ACTIVE || vp->cap_conv) { 
    225280            need_frame_buf = PJ_TRUE; 
    226281        } 
     
    231286        pjmedia_video_apply_fmt_param vafp; 
    232287 
    233         vfi = pjmedia_get_video_format_info(NULL, prm->vidparam.fmt.id); 
     288        vfi = pjmedia_get_video_format_info(NULL, vparam.fmt.id); 
    234289        if (!vfi) { 
    235290            status = PJ_ENOTFOUND; 
     
    535590     */ 
    536591    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data; 
     592    pjmedia_frame frame; 
    537593    pj_status_t status; 
    538594 
     
    551607    //save_rgb_frame(vp->cap_size.w, vp->cap_size.h, vp->enc_frm_buf); 
    552608 
    553     status = pjmedia_port_put_frame(vp->client_port, vp->enc_frm_buf); 
     609    frame = *vp->enc_frm_buf; 
     610    if (vp->cap_conv) { 
     611        frame.buf  = vp->cap_conv_buf; 
     612        frame.size = vp->cap_conv_buf_size; 
     613        status = pjmedia_converter_convert(vp->cap_conv, 
     614                                           vp->enc_frm_buf, &frame); 
     615        if (status != PJ_SUCCESS) 
     616            return; 
     617    } 
     618 
     619    status = pjmedia_port_put_frame(vp->client_port, &frame); 
    554620} 
    555621 
     
    699765{ 
    700766    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data; 
     767    pjmedia_frame frame_; 
     768 
     769    frame_ = *frame; 
     770    if (vp->cap_conv) { 
     771        pj_status_t status; 
     772 
     773        frame_.buf  = vp->cap_conv_buf; 
     774        frame_.size = vp->cap_conv_buf_size; 
     775        status = pjmedia_converter_convert(vp->cap_conv, 
     776                                           frame, &frame_); 
     777        if (status != PJ_SUCCESS) 
     778            return status; 
     779    } 
    701780 
    702781    if (vp->role==ROLE_ACTIVE) { 
    703782        if (vp->client_port) 
    704             return pjmedia_port_put_frame(vp->client_port, frame); 
     783            return pjmedia_port_put_frame(vp->client_port, &frame_); 
    705784    } else { 
    706785        pj_mutex_lock(vp->enc_frm_mutex); 
    707         copy_frame(vp->enc_frm_buf, frame); 
     786        copy_frame(vp->enc_frm_buf, &frame_); 
    708787        pj_mutex_unlock(vp->enc_frm_mutex); 
    709788    } 
    710789    if (vp->strm_cb.capture_cb) 
    711         return (*vp->strm_cb.capture_cb)(stream, vp->strm_cb_data, frame); 
     790        return (*vp->strm_cb.capture_cb)(stream, vp->strm_cb_data, &frame_); 
    712791    return PJ_SUCCESS; 
    713792} 
     
    774853 
    775854    if (vp->stream_role==ROLE_PASSIVE) { 
    776         return pjmedia_vid_dev_stream_get_frame(vp->strm, frame); 
     855        if (vp->cap_conv) { 
     856            pj_status_t status; 
     857 
     858            vp->enc_frm_buf->size = vp->enc_frm_buf_size; 
     859            status = pjmedia_vid_dev_stream_get_frame(vp->strm, vp->enc_frm_buf); 
     860            if (status != PJ_SUCCESS) 
     861                return status; 
     862 
     863            status = pjmedia_converter_convert(vp->cap_conv, 
     864                                               vp->enc_frm_buf, frame); 
     865            if (status != PJ_SUCCESS) 
     866                return status; 
     867        } else { 
     868            return pjmedia_vid_dev_stream_get_frame(vp->strm, frame); 
     869        } 
    777870    } else { 
    778871        pj_mutex_lock(vp->enc_frm_mutex); 
Note: See TracChangeset for help on using the changeset viewer.