ffmpeg学习日记8-YUV的几个知识点

ffmpeg学习日记8-YUV的几个知识点

介绍yuv相关的文章有很多,其中找到的相关概念我就不在这里介绍了,我在这里记录几点我作为新手是琢磨了很久才理解几个点。

YUV420P的存储读写问题

frame结构中存储的就是yuv数据,yuv三种数据在内存中是连续的,当pix_fmt=PIX_FMT_YUV420P时,data中的数据是按照YUV的格式存储的,也就是:

data -->YYYYYYYYYYYYYYUUUUUUUUUUUUUVVVVVVVVVVVV
^ ^ ^
| | |
data[0] data[1] data[2]
linesize是指对应于每一行的大小,所以整段读取yuv数据时,需要如下操作:

av_image_copy(video_dst_data, video_dst_linesize,
                  (const uint8_t **)(frame->data), frame->linesize,
                  pix_fmt, width, height);

    /* write to rawvideo file */
    fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);

如果要分开读取yuv数据时,如下操作:

int y_size = pCodecCtx->width * pCodecCtx->height;
// y 亮度信息写完了
fwrite(yuvFrame->data[0], 1, y_size, fp_yuv);
fwrite(yuvFrame->data[1], 1, y_size/4, fp_yuv);
fwrite(yuvFrame->data[2], 1, y_size/4, fp_yuv);

上面两种之所以取出的yuv数据都是相同的就是因为他们的存储是在连续的同一段内存中。

读取文件里的一段yuv数据,char* 格式(或者uint* 格式等),填入avframe结构中,需要如下操作:

AVFrame* picture;
AVCodecContext* c;  
        c = video_st->codec;  
        size = c->width * c->height;  
  
        if (fread(picture_buf, 1, size*3/2, fin) < 0)  
        {  
            break;  
        }  
          
        picture->data[0] = picture_buf;  // 亮度  
        picture->data[1] = picture_buf+ size;  // 色度   
        picture->data[2] = picture_buf+ size*5/4; //

解释一下,picture_buf是数据的首地址,data[1]指向u分量地址,size是分辨率大小,也是y分量大小,所以picture_buf+ size就指向了u, data[2]指向v分量地址,u分量和v分量的大小都是y大小的1/4,所以 picture_buf+ size*5/4指向v分量

YUV和RGB格式转换推理

H264里面的YUV应属于YCbCr。yuv和rgb的转换关系如下:

Y’ = 0.257*R' + 0.504*G' + 0.098*B' + 16
Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
R' = 1.164*(Y’-16) + 1.596*(Cr'-128)
G' = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)
B' = 1.164*(Y’-16) + 2.017*(Cb'-128)

就那黑色来举例,黑色的rgb值(0,0,0),转换成yuv值,y值却不是0了,而是16,16的推理如下:
将黑色的rgb(0,0,0)代入公式,可以得到:

0 = 1.164*(Y’-16) + 1.596*(Cr'-128)
0 = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)
0 = 1.164*(Y’-16) + 2.017*(Cb'-128)

转换得到:

(Cr'-128) = xxx
(Cb'-128) = xxx

将上面两个值代入公式:

0 = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)

求得:

Y = 16 
Cr = 128
Cb = 128

此问题的来源于视频叠加算法-白色素材叠加一文中的黑色像素处理。

frame中YUV的定位问题

参考

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 wencoo824。QQ:1419440391。

技术交流

欢迎加微信,搜索"wencoo824",进行技术交流,备注”博客音视频技术交流“

音视频领域其他技术文章的链接

opengl相关文章

ffmpeg相关文章

ffmpeg原理相关文章

ffmpeg源码分析相关文章

ffmpeg指令相关文章

ffmpeg报错相关文章

libass相关文章

c/c++相关文章

linux相关文章

后面都是一些废话,不用看,刷分的

推广一个AI学习网站

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

中国软件行业倡议书

精简软件开发,电脑性能越来越好,打出的程序安装包越来越大,磁盘,内存越吃越多,这不是好现象,手机同理,大家觉得呢,欢迎发表看法,各抒己见。

作者有话说

个人简介:多年工作工程经验,擅长linux下软件开发,qt,ffmpeg音视频二次开发。

欢迎各位叨扰作者,如果有什么项目合作,创业合伙需要研发,网站推广等等,尽管来联系,对于能挣钱的事,作者可是很感兴趣的哦。

关于内卷

劝大家一句,不要内卷,内卷只能害了别人,害了自己。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WenCoo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值