Changeset 5399


Ignore:
Timestamp:
Jul 27, 2016 7:49:14 AM (3 years ago)
Author:
nanang
Message:

Misc (re #1945): Updated ffmpeg video device to query supported format from the device/ffmpeg instead of hardcoded to RGB24.

File:
1 edited

Legend:

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

    r5303 r5399  
    5959#define MAX_DEV_CNT     8 
    6060 
     61#ifndef PJMEDIA_USE_OLD_FFMPEG 
     62#  define av_close_input_stream(ctx) avformat_close_input(&ctx) 
     63#endif 
     64 
     65 
    6166typedef struct ffmpeg_dev_info 
    6267{ 
     
    170175    AVDictionary *format_opts = NULL; 
    171176    char buf[128]; 
     177    enum AVPixelFormat av_fmt; 
    172178#else 
    173179    AVFormatParameters fp; 
    174180#endif 
    175181    pjmedia_video_format_detail *vfd; 
     182    pj_status_t status; 
    176183    int err; 
    177184 
     
    179186    PJ_ASSERT_RETURN(param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO, 
    180187                     PJ_EINVAL); 
     188 
     189    status = pjmedia_format_id_to_PixelFormat(param->fmt.id, &av_fmt); 
     190    if (status != PJ_SUCCESS) { 
     191        avformat_free_context(*ctx); 
     192        return status; 
     193    } 
    181194 
    182195    vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE); 
     
    191204    snprintf(buf, sizeof(buf), "%dx%d", vfd->size.w, vfd->size.h); 
    192205    av_dict_set(&format_opts, "video_size", buf, 0); 
    193     av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(PIX_FMT_BGR24), 0); 
     206    av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(av_fmt), 0); 
    194207 
    195208    /* Open capture stream */ 
     
    201214    fp.width = vfd->size.w; 
    202215    fp.height = vfd->size.h; 
    203     fp.pix_fmt = PIX_FMT_BGR24; 
     216    fp.pix_fmt = av_fmt; 
    204217    fp.time_base.num = vfd->fps.denum; 
    205218    fp.time_base.den = vfd->fps.num; 
     
    220233{ 
    221234    if (ctx) 
    222 #if LIBAVFORMAT_VER_AT_LEAST(53,2) 
    223         avformat_close_input(&ctx); 
    224 #else 
    225235        av_close_input_stream(ctx); 
    226 #endif 
    227236} 
    228237 
     
    295304    p = av_iformat_next(NULL); 
    296305    while (p) { 
    297         if (p->flags & AVFMT_NOFILE) { 
    298             unsigned i; 
    299  
    300             info = &ff->dev_info[ff->dev_count++]; 
    301             pj_bzero(info, sizeof(*info)); 
    302             pj_ansi_strncpy(info->base.name, "default",  
    303                             sizeof(info->base.name)); 
    304             pj_ansi_snprintf(info->base.driver, sizeof(info->base.driver), 
    305                              "%s (ffmpeg)", p->name); 
    306             info->base.dir = PJMEDIA_DIR_CAPTURE; 
    307             info->base.has_callback = PJ_FALSE; 
    308  
    309             info->host_api = p; 
     306        AVFormatContext *ctx; 
     307        AVCodecContext *codec = NULL; 
     308        pjmedia_format_id fmt_id; 
     309        pj_status_t status; 
     310        unsigned i; 
     311         
     312        if ((p->flags & AVFMT_NOFILE)==0 || p->read_probe) { 
     313            goto next_format; 
     314        } 
     315 
     316        info = &ff->dev_info[ff->dev_count]; 
     317        pj_bzero(info, sizeof(*info)); 
     318        pj_ansi_strncpy(info->base.name, "default",  
     319                        sizeof(info->base.name)); 
     320        pj_ansi_snprintf(info->base.driver, sizeof(info->base.driver), 
     321                         "%s (ffmpeg)", p->name); 
     322        info->base.dir = PJMEDIA_DIR_CAPTURE; 
     323        info->base.has_callback = PJ_FALSE; 
     324 
     325        info->host_api = p; 
    310326 
    311327#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \ 
    312328    (defined(PJ_WIN64) && PJ_WIN64!=0) 
    313             info->def_devname = "0"; 
     329        info->def_devname = "0"; 
    314330#elif defined(PJ_LINUX) && PJ_LINUX!=0 
    315             info->def_devname = "/dev/video0"; 
     331        info->def_devname = "/dev/video0"; 
    316332#endif 
    317333 
    318             /* Set supported formats, currently hardcoded to RGB24 only */ 
    319             info->base.caps = PJMEDIA_VID_DEV_CAP_FORMAT; 
    320             info->base.fmt_cnt = 1; 
    321             for (i = 0; i < info->base.fmt_cnt; ++i) { 
    322                 pjmedia_format *fmt = &info->base.fmt[i]; 
    323  
    324                 fmt->id = PJMEDIA_FORMAT_RGB24; 
    325                 fmt->type = PJMEDIA_TYPE_VIDEO; 
    326                 fmt->detail_type = PJMEDIA_FORMAT_DETAIL_NONE; 
    327             } 
    328         } 
    329         p = av_iformat_next(p); 
     334        ctx = avformat_alloc_context(); 
     335        if (!ctx || avformat_open_input(&ctx, info->def_devname, p, NULL)!=0) 
     336            goto next_format; 
     337 
     338        for(i = 0; i < ctx->nb_streams; i++) { 
     339            if (ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { 
     340                codec = ctx->streams[i]->codec; 
     341                break; 
     342            } 
     343        } 
     344        if (!codec) { 
     345            av_close_input_stream(ctx); 
     346            goto next_format; 
     347        } 
     348 
     349        status = PixelFormat_to_pjmedia_format_id(codec->pix_fmt, &fmt_id); 
     350        if (status != PJ_SUCCESS) { 
     351            av_close_input_stream(ctx); 
     352            goto next_format; 
     353        } 
     354 
     355        /* Set supported formats */ 
     356        info->base.caps = PJMEDIA_VID_DEV_CAP_FORMAT; 
     357        info->base.fmt_cnt = 1; 
     358        for (i = 0; i < info->base.fmt_cnt; ++i) { 
     359            pjmedia_format *fmt = &info->base.fmt[i]; 
     360            pjmedia_format_init_video(fmt, fmt_id, 
     361                                      codec->width, codec->height, 15, 1); 
     362        } 
     363 
     364        av_close_input_stream(ctx); 
     365 
     366        ff->dev_count++; 
     367 
     368next_format: 
     369        p = av_iformat_next(p); 
    330370    } 
    331371 
Note: See TracChangeset for help on using the changeset viewer.