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

推荐订阅源

J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
云风的 BLOG
云风的 BLOG
Martin Fowler
Martin Fowler
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位
Engineering at Meta
Engineering at Meta
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
Recent Announcements
Recent Announcements
罗磊的独立博客
B
Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
U
Unit 42
Microsoft Azure Blog
Microsoft Azure Blog
D
Docker
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog RSS Feed
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
V2EX

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

为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);