Ignore:
Timestamp:
Apr 10, 2012 11:54:04 AM (12 years ago)
Author:
ming
Message:

Re #1478: Add support to play encoded AVI file (H264 or MPEG4).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-videodev/avi_dev.c

    r4021 r4034  
    2323#include <pj/os.h> 
    2424#include <pj/rand.h> 
     25#include <pjmedia/vid_codec.h> 
    2526 
    2627#if defined(PJMEDIA_VIDEO_DEV_HAS_AVI) && PJMEDIA_VIDEO_DEV_HAS_AVI != 0 
     
    6970    pjmedia_vid_dev_cb               vid_cb;        /**< Stream callback.   */ 
    7071    void                            *user_data;     /**< Application data.  */ 
     72    pjmedia_vid_codec               *codec; 
     73    pj_uint8_t                      *enc_buf; 
     74    pj_size_t                        enc_buf_size; 
    7175}; 
    7276 
     
    433437    adi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT; 
    434438    adi->info.fmt_cnt = 1; 
    435     adi->info.fmt[0] = adi->vid->info.fmt; 
     439    pjmedia_format_copy(&adi->info.fmt[0], &adi->vid->info.fmt); 
    436440 
    437441    /* Set out vars */ 
     
    466470    struct avi_dev_info *adi; 
    467471    struct avi_dev_strm *strm; 
     472    pjmedia_format avi_fmt; 
     473    const pjmedia_video_format_info *vfi; 
     474    pj_status_t status = PJ_SUCCESS; 
    468475 
    469476    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL); 
     
    491498    strm->adi = adi; 
    492499 
    493     /* Override format (hack?) */ 
    494     pj_memcpy(&param->fmt, &adi->vid->info.fmt, sizeof(pjmedia_format)); 
     500    pjmedia_format_copy(&avi_fmt, &adi->vid->info.fmt); 
     501    vfi = pjmedia_get_video_format_info(NULL, avi_fmt.id); 
     502    /* Check whether the frame is encoded. */ 
     503    if (!vfi || vfi->bpp == 0) { 
     504        /* Yes, prepare codec */ 
     505        const pjmedia_vid_codec_info *codec_info; 
     506        pjmedia_vid_codec_param codec_param; 
     507        pjmedia_video_apply_fmt_param vafp; 
     508 
     509        /* Lookup codec */ 
     510        status = pjmedia_vid_codec_mgr_get_codec_info2(NULL, 
     511                                                       avi_fmt.id, 
     512                                                       &codec_info); 
     513        if (status != PJ_SUCCESS || !codec_info) 
     514            goto on_error; 
     515 
     516        status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info, 
     517                                                         &codec_param); 
     518        if (status != PJ_SUCCESS) 
     519            goto on_error; 
     520 
     521        /* Open codec */ 
     522        status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info, 
     523                                                   &strm->codec); 
     524        if (status != PJ_SUCCESS) 
     525            goto on_error; 
     526 
     527        status = pjmedia_vid_codec_init(strm->codec, strm->pool); 
     528        if (status != PJ_SUCCESS) 
     529            goto on_error; 
     530 
     531        codec_param.dir = PJMEDIA_DIR_DECODING; 
     532        codec_param.packing = PJMEDIA_VID_PACKING_WHOLE; 
     533        status = pjmedia_vid_codec_open(strm->codec, &codec_param); 
     534        if (status != PJ_SUCCESS) 
     535            goto on_error; 
     536 
     537        /* Allocate buffer */ 
     538        avi_fmt.id = codec_info->dec_fmt_id[0]; 
     539        vfi = pjmedia_get_video_format_info(NULL, avi_fmt.id); 
     540        pj_bzero(&vafp, sizeof(vafp)); 
     541        vafp.size = avi_fmt.det.vid.size; 
     542        status = vfi->apply_fmt(vfi, &vafp); 
     543        if (status != PJ_SUCCESS) 
     544            goto on_error; 
     545 
     546        strm->enc_buf = pj_pool_alloc(strm->pool, vafp.framebytes); 
     547        strm->enc_buf_size = vafp.framebytes; 
     548    } 
     549    pjmedia_format_copy(&param->fmt, &avi_fmt); 
    495550 
    496551    /* Done */ 
     
    500555 
    501556    return PJ_SUCCESS; 
     557 
     558on_error: 
     559    avi_dev_strm_destroy(&strm->base); 
     560    return status; 
    502561} 
    503562 
     
    552611{ 
    553612    struct avi_dev_strm *stream = (struct avi_dev_strm*)strm; 
    554     return pjmedia_port_get_frame(stream->adi->vid, frame); 
     613     
     614    if (stream->codec) { 
     615        pjmedia_frame enc_frame; 
     616        pj_status_t status; 
     617 
     618        enc_frame.buf = stream->enc_buf; 
     619        enc_frame.size = stream->enc_buf_size; 
     620        status = pjmedia_port_get_frame(stream->adi->vid, &enc_frame); 
     621        if (status != PJ_SUCCESS) 
     622            return status; 
     623 
     624        return pjmedia_vid_codec_decode(stream->codec, 1, &enc_frame, 
     625                                        frame->size, frame); 
     626    } else { 
     627        return pjmedia_port_get_frame(stream->adi->vid, frame); 
     628    } 
    555629} 
    556630 
     
    588662 
    589663    avi_dev_strm_stop(strm); 
     664 
     665    if (stream->codec) { 
     666        pjmedia_vid_codec_close(stream->codec); 
     667        stream->codec = NULL; 
     668    } 
    590669 
    591670    stream->adi->strm = NULL; 
Note: See TracChangeset for help on using the changeset viewer.