惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
I
InfoQ
B
Blog RSS Feed
D
DataBreaches.Net
S
SegmentFault 最新的问题
P
Proofpoint News Feed
A
About on SuperTechFans
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
博客园 - 司徒正美
小众软件
小众软件
博客园 - Franky
有赞技术团队
有赞技术团队
D
Docker
T
Tailwind CSS Blog
雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Blog — PlanetScale
Blog — PlanetScale
酷 壳 – CoolShell
酷 壳 – CoolShell
B
Blog
V
Visual Studio Blog
宝玉的分享
宝玉的分享
爱范儿
爱范儿

博客园 - 飘杨......

为ZLMediaKit在windows10编译srtp Windows10安装部署ZLMediaKit SurfaceView+EGL+OpenGL ES+ffmpeg播放视频并解决黑屏不显示画面的问题 SurfaceView+ANativeWindow+ffmpeg播放视频并解决花屏问题 SDL播放音频工具类封装 Qt QWidget中dropEvent(QDropEvent* e)拖拽放开不接收事件/不执行,且拖拽到目标后鼠标显示禁用符号 ffmpeg视频转码遇到H264黑屏问题 ffmpeg根据输入的参数截取视频 ffmpeg将视频流录制下来并保存到本地 ffmpeg解封装mp4并解码渲染(SDL2) Qt+ffmpeg+SDL硬件解码并渲染 ffmpeg+sdl播放H264/H265文件 FFmpeg实战:录制Windows屏幕并用FFmpeg压缩成H.264/H.265并保存 H264/H265 NALU的nalu_unit_type解析 ffmpeg码率控制模式详解 ffmpeg-H264/H265常用编解码预设参数 Qt+FFmpeg+SDL 实现多路多格式原始视频播放工具:从像素处理到实时渲染 Qt+SDL 实战:多格式视频播放工具开发 —— 支持 RGBA/ARGB/RGB24/YUV420P 的完整实现 SDL将YUV视频渲染到Qt窗口播放
ffmpeg SwsContext像素格式转换BGRA转YUV420P
飘杨...... · 2025-05-21 · via 博客园 - 飘杨......

一、概述

  ffmpeg提供了一个很有用的工具进行像素格式的转换。在实际的应用场景中可以根据需求来定制转换过程。

  本例通过BGRA转YUV420P来展现这个过程

  注意事项:

    • 输入输出不能搞错,特别是输入的像素格式是什么,要求的输出像素格式是什么
    • 如果输入和输出的宽高不一致像素格式一致,则是在进行裁剪操作,如果宽高和像素格式不一致,则进行裁剪+转换操作
    • 注意其中的一个参数:linesize,linesize表示的是图像一行像素的字节数。如:YUV420P的linesize=width,RGBA的linesize=width*4,RGB24的linesize=width*3等。

二、代码示例

  1. 导入库
    extern "C"
    {
    #include "libswscale/swscale.h"
    #include "libavutil/avutil.h"
    }
  2. 初始化SwsContext
    swsCtx = sws_getCachedContext(swsCtx,
        mContext->width, mContext->height, AV_PIX_FMT_BGRA,//输入的宽高及像素格式
        mContext->width, mContext->height,//输出的宽高
        AV_PIX_FMT_YUV420P,//输出的像素格式
        SWS_BILINEAR,//双线性插值算法
        0, 0, 0
    );
    if (!swsCtx)
    {
        qDebug() << "sws_getCachedContext failed!";
    }
  3. 开始转换
    const uint8_t* srcData[AV_NUM_DATA_POINTERS];
    srcData[0] = inData;
    int srcLines[AV_NUM_DATA_POINTERS];
    srcLines[0] = mContext->width * 4;
    int ret = sws_scale(swsCtx
        , srcData, srcLines, 0, mContext->height,
        frame->data, frame->linesize
    );
    if (ret <= 0)
    {
        PrintErr(ret);
    }
  4. 销毁
    if (swsCtx)
    {
        sws_freeContext(swsCtx);
        swsCtx = nullptr;
    }
  5. 使用
    encoder->scale((uint8_t*)data, frame);
    auto pkt = encoder->Encode(frame);