QT 使用FFmpeg4将bgra的Qimage转换成YUV422P

前言

用FFmpeg4实现一个非常简单的argb转换yuv422p的函数

1.通过QPixmap获取QLabel显示界面并转成image,在传入转换函数

QPixmap pixmap(subtitleLabel->size());
pixmap.fill(Qt::transparent);//设置pixmap背景透明
subtitleLabel->render(&pixmap);
QImage image = pixmap.toImage();
unsigned char *imgBuf = image.bits();
argbToyuv(image.width(),image.height(),imgBuf);

2.创建rgbBuffer并填充image的rgbBuf数据,创建yuvBuffer,创建SwsContext转换上下文,使用sws_scale进行转换

#define HI_ALIGN_UP(x, a)           ( ( ((x) + ((a) - 1) ) / (a) ) * (a) )
int argbToyuv(int width, int height, unsigned char *rgbBuf)
{
    int ret, numBytes = 0;
    uint8_t *src_data[4], *dst_data[4];
    int src_linesize[4], dst_linesize[4];
    int src_w = width, src_h = height, dst_w, dst_h;
    dst_w = HI_ALIGN_UP(src_w, 16);//像素对齐
    dst_h = HI_ALIGN_UP(src_h, 16);
    enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_ARGB, dst_pix_fmt = AV_PIX_FMT_YUV422P;
    SwsContext *sws_ctx = NULL;

	/* create argbBuffer 创建转换前,填充image数据的buffer*/
    numBytes = av_image_get_buffer_size(src_pix_fmt, src_w, src_h, 1);//1920*1080*4
    uint8_t *bgraBuffer = NULL;
    (uint8_t*)av_malloc(numBytes*sizeof(uint8_t));
    av_image_fill_arrays(src_data, src_linesize, bgraBuffer, src_pix_fmt, src_w, src_h, 1);
    src_data[0] = rgbBuf;
    src_data[1] = src_data[0]+(width*height);
    src_data[2] = src_data[1]+(width*2*height);

//    FILE *output_rgb=fopen("/opt/vw30/bin/subtitle_rgb","ab+");
//    fwrite(rgbBuf,(src_w*src_h)*3,1,output_rgb);
//    fclose(output_rgb);

	/* create yuvBuffer 创建转换后接收的buffer*/
    numBytes = av_image_get_buffer_size(dst_pix_fmt, dst_w, dst_h, 1);
    uint8_t *yuvBuffer = NULL;
    yuvBuffer = (uint8_t*)av_malloc(numBytes*sizeof(uint8_t));
    av_image_fill_arrays(dst_data, dst_linesize, yuvBuffer ,dst_pix_fmt, dst_w, dst_h, 1);

    /* create scaling context 创建转换上下文*/
    sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt,
                             dst_w, dst_h, dst_pix_fmt,
                             SWS_BILINEAR, NULL, NULL, NULL);
    if (!sws_ctx) {
        fprintf(stderr,
                "Impossible to create scale context for the conversion "
                "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
                av_get_pix_fmt_name(src_pix_fmt), src_w, src_h,
                av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h);
        ret = AVERROR(EINVAL);
        goto end;
    }
    /*sws_scale 转换函数*/
    ret = sws_scale(sws_ctx, src_data, src_linesize, 0, src_h, dst_data, dst_linesize);
    if (ret < 0){
        qDebug()<<"sws_scale error";
        goto end;
    }

end:
    if(yuvBuffer){
        av_free(yuvBuffer);
    }
    if(bgraBuffer){
       av_free(bgraBuffer);
    }
    if(sws_ctx){
       sws_freeContext(sws_ctx);
    }

//    FILE *output=fopen("/opt/vw30/bin/subtitle.yuv","ab+");
//    fwrite(dst_data[0],dst_w*dst_h,1,output);
//    fwrite(dst_data[1],dst_w*dst_h/4,1,output);
//    fwrite(dst_data[2],dst_w*dst_h/4,1,output);
    return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值