欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ffmpeg--yuv数据采集

程序员文章站 2022-03-04 23:41:17
...

1.打开视频设备

static AVFormatContext* open_dev()
{
    int ret = 0;
    char errors[1024] ={0,};
    
    AVFormatContext *fmt_ctx = NULL;
    AVDictionary *options= NULL;
    
    //0:0 前面的0是视频设备,后面的0是音频设备,这里只采集视频
    //0 是机器摄像头
    //1 是桌面
    char * devicename = "0";
    
    //av_register_all();
    
    // 1.注册所有的编解码器和音视频格式
    avdevice_register_all();
                           
    //2.选取mac对应的avfoundation库
    //mac 上使用avfoundation,windows上面使用directshow,linux使用alsa
    AVInputFormat *iformat = av_find_input_format("avfoundation");
    
    //video_size 指定分辨率的大小
    av_dict_set(&options,"video_size","640x480", 0);
    av_dict_set(&options,"framerate","30", 0);
    av_dict_set(&options,"pixel_format","nv12", 0);
    //av_dict_set(&options,"list_devices","true",0);
    
    //打开设备上下文
    ret = avformat_open_input(&fmt_ctx, devicename, iformat,&options);
    if(ret < 0)
    {
        av_strerror(ret, errors, 1024);
        fprintf(stderr, "Failed to open device,[%d]%s\n",ret,errors);
        return NULL;
    }
    
    return fmt_ctx;
}`在这里插入代码片`

2.yuv数据采集

void rec_video()
{
    int ret = 0;
    
    AVFormatContext *fmt_ctx = NULL;
    
    AVPacket pkt;
    
    av_log_set_level(AV_LOG_DEBUG);
    
    rec_status = 1;
    
    char *out ="/users/test/Downloads/video.yuv";
    
    FILE * outfile = fopen(out,"wb+");
    
    fmt_ctx = open_dev();
    if(NULL == fmt_ctx)
    {
        av_log(NULL, AV_LOG_DEBUG, "=====ERROR======!\n");
        goto __ERROR;
    }
    
    av_log(NULL, AV_LOG_DEBUG, "test 11111111!\n");
    
    while(rec_status)
    {
        ret = av_read_frame(fmt_ctx, &pkt);
        if (ret == 0)
        { // 读取成功
            // 将数据写入文件
            //(宽x高)x(yuv420=1.5/yuv422=2/yuv444=3)字节
            //fwrite的第三个形参长度是以为字节为单位的
            //nv12是yuv420的一种存储格式
            fwrite(pkt.data,1,460800, outfile);
            // 释放资源,此处必须释放,每次av_read_frame都会增加引用计数,av_packet_unref释放引用计数,等到引用计数为0的时候,资源被释放
            av_packet_unref(&pkt);
        }
        else if (ret == AVERROR(EAGAIN))
        { // 资源临时不可用
        	//此处会引起cpu占用率过高
            continue;
        }
        else
        { // 其他错误
            //errbuf[1024];
            //av_strerror(ret, errbuf, sizeof (errbuf));
            //av_log(NULL, AV_LOG_INFO, "errbuf  is %s \n",errbuf);
            break;
        }

    // 必须要加,释放pkt内部的资源
        av_packet_unref(&pkt);
    }
    
__ERROR:
    if(outfile)
    {
        fclose(outfile);
    }
    
    if(fmt_ctx)
    {
        avformat_close_input(&fmt_ctx);
    }
    
    av_log(NULL, AV_LOG_DEBUG, "finish!\n");
    
    return;
}
相关标签: 音视频 音视频