当前位置: 首页 > news >正文

三.ffmpeg对yuv的操作

一.windows

1.使用ffmpeg录制mp4视频

#获取音视频设备
ffmpeg -list_devices true -f dshow -i dummy
#录制视频
ffmpeg -f dshow -i video="xxxx" -c"v libx264 -pix_fmt yuv420p output.mp4

2.将mp4转换为yuv数据

//-i:输入文件选项;-an:不处理音频流;
//-c:v rawvideo 视频编码器的选项,使用原始视频格式进行编码(不进行压缩);
//-pix_fmt yuv420p:输出视频的像素格式
ffmpeg -i output.mp4 -an -c:v rawvideo -pix_fmt yuv420p out.yuv
//播放
ffplay -f rawvideo -pixel_format yuv420p -video_size 1280x720 out1.yuv

3.也可以单独播放单独分量

//播放yuv数据
ffplay -s 1280x720 -vf extractplanes='y' out.yuv
//提取yuv三个分量为三个文件
ffmpeg -s 1280x720 -pix_fmt yuv420p -i out.yuv -filter_complex "extractplanes=y+u+v[y][u][v]" -map "[y]" y.yuv -map "[u]" u.yuv -map "[v]" v.yuv
//播放单个分量 格式为gray
ffplay -s 1280x720 -pix_fmt gray y.yuv

播放出来y、u、v都是没有颜色的,为什么u和v表示蓝色和红色的差分量也没有颜色呢?

因为u和v分量的值是相对于y分量的,没有y分量它们都无法提供完整的颜色信息。

4.api调用 

#可以查看摄像头输出的视频数据的编码格式和像素格式
ffmpeg -list_options true -f dshow -i video="Integrated Camera" 

5.整体代码

//打开摄像头直接获取原始数据
int read_video()
{
    int ret = 0;
    char errors[1024];
    AVFormatContext *fmt_ctx = NULL;
    AVDictionary *options = NULL;
    AVAudioFifo *fifo = nullptr;
    // FILE *outfile = fopen("./out.yuv", "wb+");
    FILE *outfile_yuv = fopen("./out1.yuv", "wb+");
    if (outfile_yuv == nullptr)
    {
        printf("filed open out file\n");
    }

    AVPacket pkt;
    av_init_packet(&pkt);
    int frame_count = 0;

    // 找到采集工具
    const AVInputFormat *iformat = av_find_input_format("dshow");
    if (iformat == NULL)
    {
        printf("AVInputFormat find failed \n");
        return -1;
    }

    // 打开视频设备
    av_dict_set(&options, "video_size", "1280x720", 0);
    av_dict_set(&options, "framerate", "10", 0);
    av_dict_set(&options, "pixel_format", "yuyv422", 0);
    ret = open_dev(&fmt_ctx, "video=Integrated Camera", iformat, &options);
    int count = 0;
    while (av_read_frame(fmt_ctx, &pkt) >= 0)
    {
        printf("pkt-size:%d\n", pkt.size);
        fwrite(pkt.data, 1, pkt.size, outfile_yuv);
        fflush(outfile_yuv);
        av_packet_unref(&pkt);
        if (count++ > 50)
            break;
    }

    avformat_close_input(&fmt_ctx);
    fclose(outfile_yuv);
    av_log(NULL, AV_LOG_DEBUG, "end");

    return 0;
}

6.遇到问题

1.通过av_read_frame获取到的视频数据不是yuv420p的原始数据,而是通过mjpeg编码的yuv422p的数据。

7.解决问题

注意:打开使用设备时要注意自己摄像头支持的参数,我之前设置的1280x720 30fps yuyv422和1280x720 30fps yuv420p都不支持设置pixel_format,所以我没写pixel_format,导致1280x720 30fps默认使用vcodec=mjpeg编码器来进行编码。

解决办法:使用上面的这个指令来查看本机设备支持的格式和参数

ffmpeg -list_options true -f dshow -i video="Integrated Camera" 

相关文章:

  • SSH连接中断原因分析(SSH断开、SSH中断、SSH连接断开、远程断开、远程中断)(带宽不足、网络抖动与丢包、CPU资源耗尽、内存不足、磁盘I/O瓶颈)
  • 解锁物联网高效开发,Synaptics SYN43756E Wi-Fi 6E 芯片登场
  • 打造无缝智慧照明场景,涂鸦智能全新发布蓝牙Mesh照明解决方案
  • AI Agent系列(六) -基于ReAct架构搭建LLM Agent(Deepseek)
  • C语言中的函数
  • 动平衡仿真程序设计
  • SpringSecurity——如何获取当前登录用户的信息
  • jekins启动失败排查
  • matrix-breakout-2-morpheus通关攻略
  • 蓝桥杯 - 中等 - 新手引导
  • Oracle数据库与MySQL数据库的全面对比分析
  • SpringBoot对接DeepSeek
  • 模板方法设计模式在事件处理中的应用
  • JavaScript 金额运算精度丢失问题及解决方案
  • 【LLMs篇】05:RMSNorm
  • AI 大模型统一集成|微服务 + 认证中心:如何保障大模型 API 的安全调用!
  • docker 部署elk 设置账号密码
  • MAT 启动报错
  • MySQL数据库精研之旅第一期:开启数据管理新旅程
  • yum软件包乾坤大挪移(Yum Package Qiankun Great Migration)
  • 上海发布首份直播电商行业自律公约,禁止虚假宣传、商业诋毁
  • 悬疑推理联合书单|虫神山事件
  • 丹麦召见美外交官,强调“不能容忍”美在格陵兰岛间谍活动
  • 司法部:民营经济促进法明确禁止违规异地执法、利用行政或者刑事手段违法干预经济纠纷
  • 咖啡戏剧节举办第五年,上生新所“无店不咖啡,空间皆可戏”
  • 趣看 | 五一黄金周:你拍风景,拍风景的人在拍你