Changeset 3435


Ignore:
Timestamp:
Mar 2, 2011 8:37:31 AM (9 years ago)
Author:
nanang
Message:

Re #1182:

  • Added remote frame-rate detection in to video stream.
  • Fixed bitrate settings in ffmpeg codec.
  • Fixed SDL dev to update internal SDL info when format changed.
  • Minor fixes/updates, e.g:
    • added cleanup steps, fixed logs, etc, in sample app simpleua.c and vid_streamutil.c
    • fixed/added docs of the new APIs in the jitter buffer.
Location:
pjproject/branches/projects/2.0-dev
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/jbuf.h

    r3420 r3435  
    327327 
    328328 
     329/** 
     330 * Get a frame from the jitter buffer. The jitter buffer will return the 
     331 * oldest frame from it's buffer, when it is available. 
     332 * 
     333 * @param jb            The jitter buffer. 
     334 * @param frame         Buffer to receive the payload from the jitter buffer. 
     335 *                      @see pjmedia_jbuf_get_frame().     
     336 * @param size          Pointer to receive frame size. 
     337 * @param p_frm_type    Pointer to receive frame type. 
     338 *                      @see pjmedia_jbuf_get_frame().     
     339 * @param bit_info      Bit precise info of the frame, e.g: a frame may not  
     340 *                      exactly start and end at the octet boundary, so this 
     341 *                      field may be used for specifying start & end bit offset. 
     342 * @param ts            Frame timestamp. 
     343 * @param seq           Frame sequence number. 
     344 */ 
    329345PJ_DECL(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,  
    330346                                      void *frame,  
     
    332348                                      char *p_frm_type, 
    333349                                      pj_uint32_t *bit_info, 
    334                                       pj_uint32_t *ts); 
    335  
     350                                      pj_uint32_t *ts, 
     351                                      int *seq); 
     352 
     353 
     354/** 
     355 * Peek a frame from the jitter buffer. The jitter buffer state will not be 
     356 * modified. 
     357 * 
     358 * @param jb            The jitter buffer. 
     359 * @param offset        Offset from the oldest frame to be peeked. 
     360 * @param frame         Buffer to receive the payload from the jitter buffer. 
     361 *                      @see pjmedia_jbuf_get_frame().     
     362 * @param size          Pointer to receive frame size. 
     363 * @param p_frm_type    Pointer to receive frame type. 
     364 *                      @see pjmedia_jbuf_get_frame().     
     365 * @param bit_info      Bit precise info of the frame, e.g: a frame may not  
     366 *                      exactly start and end at the octet boundary, so this 
     367 *                      field may be used for specifying start & end bit offset. 
     368 * @param ts            Frame timestamp. 
     369 * @param seq           Frame sequence number. 
     370 */ 
    336371PJ_DECL(void) pjmedia_jbuf_peek_frame(pjmedia_jbuf *jb, 
    337                                       unsigned idx, 
     372                                      unsigned offset, 
    338373                                      const void **frame,  
    339374                                      pj_size_t *size,  
    340375                                      char *p_frm_type, 
    341376                                      pj_uint32_t *bit_info, 
    342                                       pj_uint32_t *ts); 
    343  
     377                                      pj_uint32_t *ts, 
     378                                      int *seq); 
     379 
     380 
     381/** 
     382 * Remove frames from the jitter buffer. 
     383 * 
     384 * @param jb            The jitter buffer. 
     385 * @param frame_cnt     Number of frames to be removed. 
     386 * 
     387 * @return              The number of frame successfully removed. 
     388 */ 
    344389PJ_DECL(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,  
    345390                                            unsigned frame_cnt); 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c

    r3432 r3435  
    182182                                                /**< expected output format of  
    183183                                                     ffmpeg decoder         */ 
    184     struct SwsContext               *sws_ctx;   /**< the format converter for  
    185                                                      post decoding          */ 
    186  
    187184} ffmpeg_private; 
    188185 
     
    207204    pjmedia_vid_codec_info       info; 
    208205    pjmedia_format_id            base_fmt_id; 
     206    pj_uint32_t                  avg_bps; 
     207    pj_uint32_t                  max_bps; 
    209208    func_packetize               packetize; 
    210209    func_unpacketize             unpacketize; 
     
    248247    { 
    249248        {PJMEDIA_FORMAT_H263P,  {"H263-1998",9},    PJMEDIA_RTP_PT_H263}, 
    250         PJMEDIA_FORMAT_H263, 
     249        PJMEDIA_FORMAT_H263,    1000000,    2000000, 
    251250        &h263_packetize, &h263_unpacketize, &h263_parse_fmtp, 
    252251        {2, { {{"CIF",3}, {"2",1}}, {{"QCIF",4}, {"1",1}}, } }, 
     
    254253    { 
    255254        {PJMEDIA_FORMAT_H263,   {"H263",4},         PJMEDIA_RTP_PT_H263}, 
    256         0, 
     255        0,                      1000000,    2000000, 
    257256        &h263_packetize, &h263_unpacketize, &h263_parse_fmtp, 
    258257        {2, { {{"CIF",3}, {"2",1}}, {{"QCIF",4}, {"1",1}}, } }, 
     
    802801    attr->dec_fmtp = desc->dec_fmtp; 
    803802 
     803    /* Bitrate */ 
     804    attr->enc_fmt.det.vid.avg_bps = desc->avg_bps; 
     805    attr->enc_fmt.det.vid.max_bps = desc->max_bps; 
     806 
    804807    return PJ_SUCCESS; 
    805808} 
     
    989992            ctx->time_base.num = vfd->fps.denum; 
    990993            ctx->time_base.den = vfd->fps.num; 
    991             if (vfd->avg_bps) 
     994            if (vfd->avg_bps) { 
    992995                ctx->bit_rate = vfd->avg_bps; 
    993             if (vfd->max_bps) 
    994                 ctx->rc_max_rate = vfd->max_bps; 
     996                if (vfd->max_bps) 
     997                    ctx->bit_rate_tolerance = vfd->max_bps - vfd->avg_bps; 
     998            } 
    995999 
    9961000            /* For encoder, should be better to be strict to the standards */ 
     
    11241128        av_free(ff->dec_ctx); 
    11251129    } 
    1126     if (ff->sws_ctx) { 
    1127         sws_freeContext(ff->sws_ctx); 
    1128     } 
    11291130    ff->enc_ctx = NULL; 
    11301131    ff->dec_ctx = NULL; 
    1131     ff->sws_ctx = NULL; 
    11321132    pj_mutex_unlock(ff_mutex); 
    11331133 
     
    14091409#ifdef _MSC_VER 
    14101410#   pragma comment( lib, "avcodec.lib") 
    1411 #   pragma comment( lib, "swscale.lib") 
    14121411#endif 
    14131412 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c

    r3432 r3435  
    447447                    if (strm->overlay) 
    448448                        SDL_FreeYUVOverlay(strm->overlay); 
     449 
     450                    /* Update SDL info for the new format */ 
     451                    sdl_info = get_sdl_format_info(fmt->id); 
    449452 
    450453                    if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB) { 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/jbuf.c

    r3420 r3435  
    264264                                  pjmedia_jb_frame_type *p_type, 
    265265                                  pj_uint32_t *bit_info, 
    266                                   pj_uint32_t *ts)  
     266                                  pj_uint32_t *ts, 
     267                                  int *seq)  
    267268{ 
    268269    if (framelist->size) { 
     
    289290            if (ts) 
    290291                *ts = framelist->ts[framelist->head]; 
     292            if (seq) 
     293                *seq = framelist->origin; 
    291294 
    292295            //pj_bzero(framelist->content +  
     
    314317 
    315318static pj_bool_t jb_framelist_peek(jb_framelist_t *framelist, 
    316                                    unsigned idx, 
     319                                   unsigned offset, 
    317320                                   const void **frame, 
    318321                                   pj_size_t *size, 
    319322                                   pjmedia_jb_frame_type *type, 
    320323                                   pj_uint32_t *bit_info, 
    321                                    pj_uint32_t *ts)  
    322 { 
    323     unsigned pos; 
    324  
    325     if (idx >= jb_framelist_eff_size(framelist)) 
     324                                   pj_uint32_t *ts, 
     325                                   int *seq)  
     326{ 
     327    unsigned pos, idx; 
     328 
     329    if (offset >= jb_framelist_eff_size(framelist)) 
    326330        return PJ_FALSE; 
    327331 
    328332    pos = framelist->head; 
     333    idx = offset; 
    329334 
    330335    /* Find actual peek position, note there may be discarded frames */ 
     
    351356    if (ts) 
    352357        *ts = framelist->ts[pos]; 
     358    if (seq) 
     359        *seq = framelist->origin + offset; 
    353360 
    354361    return PJ_TRUE; 
     
    932939                                     char *p_frame_type) 
    933940{ 
    934     pjmedia_jbuf_get_frame3(jb, frame, NULL, p_frame_type, NULL, NULL); 
     941    pjmedia_jbuf_get_frame3(jb, frame, NULL, p_frame_type, NULL, 
     942                            NULL, NULL); 
    935943} 
    936944 
     
    944952                                     pj_uint32_t *bit_info) 
    945953{ 
    946     pjmedia_jbuf_get_frame3(jb, frame, size, p_frame_type, bit_info, NULL); 
     954    pjmedia_jbuf_get_frame3(jb, frame, size, p_frame_type, bit_info, 
     955                            NULL, NULL); 
    947956} 
    948957 
     
    955964                                     char *p_frame_type, 
    956965                                     pj_uint32_t *bit_info, 
    957                                      pj_uint32_t *ts) 
     966                                     pj_uint32_t *ts, 
     967                                     int *seq) 
    958968{ 
    959969    if (jb->jb_status == JB_STATUS_PREFETCHING) { 
     
    980990        /* Try to retrieve a frame from frame list */ 
    981991        res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,  
    982                                bit_info, ts); 
     992                               bit_info, ts, seq); 
    983993        if (res) { 
    984994            /* We've successfully retrieved a frame from the frame list, but 
     
    10501060 
    10511061PJ_DEF(void) pjmedia_jbuf_peek_frame( pjmedia_jbuf *jb, 
    1052                                       unsigned idx, 
     1062                                      unsigned offset, 
    10531063                                      const void **frame,  
    10541064                                      pj_size_t *size,  
    10551065                                      char *p_frm_type, 
    10561066                                      pj_uint32_t *bit_info, 
    1057                                       pj_uint32_t *ts) 
     1067                                      pj_uint32_t *ts, 
     1068                                      int *seq) 
    10581069{ 
    10591070    pjmedia_jb_frame_type ftype; 
    10601071    pj_bool_t res; 
    10611072 
    1062     res = jb_framelist_peek(&jb->jb_framelist, idx, frame, size, &ftype, bit_info, ts); 
     1073    res = jb_framelist_peek(&jb->jb_framelist, offset, frame, size, &ftype, 
     1074                            bit_info, ts, seq); 
    10631075    if (!res) 
    10641076        *p_frm_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/stream.c

    r3425 r3435  
    27422742 
    27432743static const pj_str_t ID_AUDIO = { "audio", 5}; 
    2744 static const pj_str_t ID_VIDEO = { "video", 5}; 
    2745 static const pj_str_t ID_APPLICATION = { "application", 11}; 
    27462744static const pj_str_t ID_IN = { "IN", 2 }; 
    27472745static const pj_str_t ID_IP4 = { "IP4", 3}; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c

    r3425 r3435  
    6969    void                   *buf;            /**< Output buffer.             */ 
    7070    unsigned                buf_size;       /**< Size of output buffer.     */ 
    71     unsigned                buf_len;    /**< Length of data in buffer.  */ 
     71    unsigned                buf_len;        /**< Length of data in buffer.  */ 
    7272    pjmedia_rtp_session     rtp;            /**< RTP session.               */ 
    7373} pjmedia_vid_channel; 
     
    135135 
    136136    pjmedia_vid_codec       *codec;         /**< Codec instance being used. */ 
     137    pj_uint32_t              last_dec_ts;    /**< Last decoded timestamp.   */ 
     138    int                      last_dec_seq;   /**< Last decoded sequence.    */ 
    137139}; 
    138140 
     
    841843    pjmedia_vid_channel *channel = stream->dec; 
    842844    pjmedia_frame frame_in; 
     845    pj_bool_t fps_changed = PJ_FALSE; 
     846    pjmedia_ratio new_fps = {0}; 
    843847    pj_status_t status; 
    844848 
     
    857861        pj_size_t psize, data_len; 
    858862        pj_uint32_t ts, last_ts; 
    859         pj_bool_t got_frame; 
     863        int seq; 
     864        pj_bool_t got_frame, check_fps; 
    860865        unsigned i; 
    861866 
     
    863868        last_ts = 0; 
    864869        got_frame = PJ_FALSE; 
     870        check_fps = PJ_FALSE; 
    865871 
    866872        /* Lock jitter buffer mutex first */ 
     
    870876            /* Get frame from jitter buffer. */ 
    871877            pjmedia_jbuf_peek_frame(stream->jb, i, &p, &psize, &ptype, 
    872                                     NULL, &ts); 
     878                                    NULL, &ts, &seq); 
    873879            if (ptype == PJMEDIA_JB_NORMAL_FRAME) { 
    874                 if (last_ts == 0) 
     880                if (last_ts == 0) { 
    875881                    last_ts = ts; 
     882                    check_fps = stream->last_dec_ts && 
     883                                (seq - stream->last_dec_seq == 1) && 
     884                                (last_ts > stream->last_dec_ts); 
     885                } 
    876886 
    877887                if (ts != last_ts) { 
     
    880890                    break; 
    881891                } 
    882                  
     892 
    883893                data = (pj_uint8_t*)channel->buf + channel->buf_len; 
    884894                data_len = channel->buf_size - channel->buf_len; 
     
    901911            return PJ_SUCCESS; 
    902912        } 
     913 
     914        /* Learn remote frame rate */ 
     915        if (check_fps) { 
     916            pj_uint32_t ts_diff; 
     917            pjmedia_video_format_detail *vfd; 
     918 
     919            ts_diff = last_ts - stream->last_dec_ts; 
     920            vfd = pjmedia_format_get_video_format_detail( 
     921                                    &channel->port.info.fmt, PJ_TRUE); 
     922            if (ts_diff * vfd->fps.num != 
     923                stream->info.codec_info.clock_rate * vfd->fps.denum) 
     924            { 
     925                /* Frame rate changed */ 
     926                fps_changed = PJ_TRUE; 
     927                new_fps.num = stream->info.codec_info.clock_rate; 
     928                new_fps.denum = ts_diff; 
     929            } 
     930        } 
     931 
     932        /* Update last frame seq and timestamp */ 
     933        stream->last_dec_seq = seq - 1; 
     934        stream->last_dec_ts = last_ts; 
    903935    } 
    904936 
     
    924956 
    925957        /* Update decoding channel port info */ 
    926         pjmedia_format_copy(&stream->dec->port.info.fmt, 
     958        pjmedia_format_copy(&channel->port.info.fmt, 
    927959                            &stream->info.codec_param->dec_fmt); 
    928960    } 
    929      
     961 
     962    if (fps_changed) { 
     963        pjmedia_video_format_detail *vfd; 
     964 
     965        /* Update decoding channel port info */ 
     966        vfd = pjmedia_format_get_video_format_detail( 
     967                                &channel->port.info.fmt, PJ_TRUE); 
     968        vfd->fps = new_fps; 
     969 
     970        /* Update stream info */ 
     971        vfd = pjmedia_format_get_video_format_detail( 
     972                                &stream->info.codec_param->dec_fmt, PJ_TRUE); 
     973        vfd->fps = new_fps; 
     974 
     975        /* Set bit_info */ 
     976        frame->bit_info |= PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED; 
     977 
     978        PJ_LOG(4, (channel->port.info.name.ptr, "Frame rate changed to %.2ffps", 
     979                   (1.0 * new_fps.num / new_fps.denum))); 
     980    } 
     981 
    930982    return PJ_SUCCESS; 
    931983} 
     
    11341186        return status; 
    11351187 
    1136     /* Get the frame size */ 
    1137     stream->frame_size = vfd_enc->max_bps * vfd_enc->fps.denum / 
     1188    /* Estimate the maximum frame size */ 
     1189    stream->frame_size = vfd_enc->size.w * vfd_enc->size.h * 4; 
     1190 
     1191#if 0 
     1192    stream->frame_size = vfd_enc->max_bps/8 * vfd_enc->fps.denum / 
    11381193                         vfd_enc->fps.num; 
    11391194     
     
    11421197     * frame size value for safety. 
    11431198     */ 
    1144     stream->frame_size <<= 2; 
     1199    stream->frame_size <<= 4; 
     1200#endif 
    11451201 
    11461202    /* Validate the frame size */ 
     
    15621618 
    15631619 
    1564 static const pj_str_t ID_AUDIO = { "audio", 5}; 
    15651620static const pj_str_t ID_VIDEO = { "video", 5}; 
    1566 static const pj_str_t ID_APPLICATION = { "application", 11}; 
    15671621static const pj_str_t ID_IN = { "IN", 2 }; 
    15681622static const pj_str_t ID_IP4 = { "IP4", 3}; 
     
    15721626//static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 }; 
    15731627static const pj_str_t ID_RTPMAP = { "rtpmap", 6 }; 
    1574 static const pj_str_t ID_TELEPHONE_EVENT = { "telephone-event", 15 }; 
    15751628 
    15761629static const pj_str_t STR_INACTIVE = { "inactive", 8 }; 
  • pjproject/branches/projects/2.0-dev/pjsip-apps/src/samples/simpleua.c

    r3425 r3435  
    548548    dump_pool_usage(THIS_FILE, &cp); 
    549549 
     550    /* Destroy stream */ 
     551    if (g_med_stream) 
     552        pjmedia_stream_destroy(g_med_stream); 
     553    if (g_med_vstream) 
     554        pjmedia_vid_stream_destroy(g_med_vstream); 
     555 
     556    /* Destroy audio ports */ 
     557    if (g_snd_player) 
     558        pjmedia_snd_port_destroy(g_snd_player); 
     559    if (g_snd_rec) 
     560        pjmedia_snd_port_destroy(g_snd_rec); 
     561 
     562    /* Destroy video ports */ 
     563    if (g_vid_capturer) 
     564        pjmedia_vid_port_destroy(g_vid_capturer); 
     565    if (g_vid_renderer) 
     566        pjmedia_vid_port_destroy(g_vid_renderer); 
     567 
     568    /* Destroy media transports */ 
     569    for (i = 0; i < MAX_MEDIA_CNT; ++i) { 
     570        if (g_med_transport[i]) 
     571            pjmedia_transport_close(g_med_transport[i]); 
     572    } 
     573 
     574    /* Deinit ffmpeg codec */ 
     575    pjmedia_codec_ffmpeg_deinit(); 
     576 
     577    /* Deinit pjmedia endpoint */ 
     578    if (g_med_endpt) 
     579        pjmedia_endpt_destroy(g_med_endpt); 
     580 
     581    /* Deinit pjsip endpoint */ 
     582    if (g_endpt) 
     583        pjsip_endpt_destroy(g_endpt); 
     584 
     585    /* Release pool */ 
    550586    pj_pool_release(pool); 
    551587 
  • pjproject/branches/projects/2.0-dev/pjsip-apps/src/samples/vid_streamutil.c

    r3432 r3435  
    126126} 
    127127 
     128/*  
     129 * Register all codecs.  
     130 */ 
     131static void deinit_codecs() 
     132{ 
     133#if defined(PJMEDIA_HAS_FFMPEG_CODEC) && PJMEDIA_HAS_FFMPEG_CODEC != 0 
     134    pjmedia_codec_ffmpeg_deinit(); 
     135#endif 
     136} 
     137 
    128138static pj_status_t create_file_player( pj_pool_t *pool, 
    129139                                       const char *file_name, 
     
    616626        file_vfd = pjmedia_format_get_video_format_detail(&play_port->info.fmt, 
    617627                                                          PJ_TRUE); 
    618         PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d %c%c%c%c @%.2dfps", 
     628        PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d %c%c%c%c @%.2ffps", 
    619629                   file_vfd->size.w, file_vfd->size.h, 
    620630                   ((play_port->info.fmt.id & 0x000000FF) >> 0), 
     
    622632                   ((play_port->info.fmt.id & 0x00FF0000) >> 16), 
    623633                   ((play_port->info.fmt.id & 0xFF000000) >> 24), 
    624                    file_vfd->fps.num/file_vfd->fps.denum)); 
     634                   (1.0*file_vfd->fps.num/file_vfd->fps.denum))); 
    625635 
    626636        /* Allocate file read buffer */ 
     
    658668                goto on_exit; 
    659669 
     670            codec_param2.dir = PJMEDIA_DIR_DECODING; 
    660671            status = play_decoder->op->open(play_decoder, &codec_param2); 
    661672            if (status != PJ_SUCCESS) 
     
    706717                goto on_exit; 
    707718 
    708             pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt); 
     719            pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.enc_fmt); 
     720            vpp.vidparam.fmt.id = codec_param.dec_fmt.id; 
    709721            vpp.vidparam.dir = PJMEDIA_DIR_CAPTURE; 
    710722             
     
    836848 
    837849    if (dir & PJMEDIA_DIR_ENCODING) 
    838         PJ_LOG(2, (THIS_FILE, "Sending %dx%d %.*s @%.2dfps", 
     850        PJ_LOG(2, (THIS_FILE, "Sending %dx%d %.*s @%.2ffps", 
    839851                   codec_param.enc_fmt.det.vid.size.w, 
    840852                   codec_param.enc_fmt.det.vid.size.h, 
    841853                   codec_info->encoding_name.slen, 
    842854                   codec_info->encoding_name.ptr, 
    843                    codec_param.enc_fmt.det.vid.fps.num/ 
    844                    codec_param.enc_fmt.det.vid.fps.denum)); 
     855                   (1.0*codec_param.enc_fmt.det.vid.fps.num/ 
     856                    codec_param.enc_fmt.det.vid.fps.denum))); 
    845857 
    846858    for (;;) { 
     
    880892 
    881893    /* Destroy file decoder */ 
    882     if (play_decoder) 
     894    if (play_decoder) { 
    883895        play_decoder->op->close(play_decoder); 
     896        pjmedia_vid_codec_mgr_dealloc_codec(NULL, play_decoder); 
     897    } 
    884898 
    885899    /* Destroy video devices */ 
     
    899913    } 
    900914 
     915    /* Deinit codecs */ 
     916    deinit_codecs(); 
     917 
    901918    /* Shutdown video subsystem */ 
    902919    pjmedia_vid_subsys_shutdown(); 
Note: See TracChangeset for help on using the changeset viewer.