用ffmpeg把H264数据流解码成YUV420P

简介: 在网上找了很久这方面的内容,发现网上的代码都太旧了,所使用的函数旧到连最新版本的ffmpeg都已经不包含了,所以对于我这个初学者来说太坑拉。不过经过多次查找ffmpeg的头文件和结合网上的内容,终于成功可以解码拉。

在网上找了很久这方面的内容,发现网上的代码都太旧了,所使用的函数旧到连最新版本的ffmpeg都已经不包含了,所以对于我这个初学者来说太坑拉。不过经过多次查找ffmpeg的头文件和结合网上的内容,终于成功可以解码拉。现在贴出来。

首先是初始化一些参数

 

[cpp]  view plain copy
 
 
  1. //下面初始化h264解码库  
  2. avcodec_init();  
  3. av_register_all();  
  4.   
  5. AVFrame *pFrame_ = NULL;  
  6.   
  7. AVCodecContext *codec_ = avcodec_alloc_context();  
  8.   
  9. /* find the video encoder */  
  10. AVCodec *videoCodec = avcodec_find_decoder(CODEC_ID_H264);  
  11.   
  12. if (!videoCodec)   
  13. {  
  14.     cout << "codec not found!" << endl;  
  15.     return -1;  
  16. }  
  17.   
  18. //初始化参数,下面的参数应该由具体的业务决定  
  19. codec_->time_base.num = 1;  
  20. codec_->frame_number = 1; //每包一个视频帧  
  21. codec_->codec_type = AVMEDIA_TYPE_VIDEO;  
  22. codec_->bit_rate = 0;  
  23. codec_->time_base.den = 30;//帧率  
  24. codec_->width = 1280;//视频宽  
  25. codec_->height = 720;//视频高  
  26.   
  27. if(avcodec_open(codec_, videoCodec) >= 0)  
  28.     pFrame_ = avcodec_alloc_frame();// Allocate video frame  
  29. else  
  30.     return -1;  


下面是具体的解码的代码

 

[cpp]  view plain copy
 
 
  1. AVPacket packet = {0};  
  2. int frameFinished = dwBufsize;//这个是随便填入数字,没什么作用  
  3.   
  4. packet.data = pBuffer;//这里填入一个指向完整H264数据帧的指针  
  5. packet.size = dwBufsize;//这个填入H264数据帧的大小  
  6.   
  7. //下面开始真正的解码  
  8. avcodec_decode_video2(codec_, pFrame_, &frameFinished, &packet);  
  9. if(frameFinished)//成功解码  
  10. {  
  11.     int picSize = codec_->height * codec_->width;  
  12.     int newSize = picSize * 1.5;  
  13.   
  14.     //申请内存  
  15.     unsigned char *buf = new unsigned char[newSize];  
  16.   
  17.     int height = p->codec->height;  
  18.     int width = p->codec->width;  
  19.   
  20.   
  21.     //写入数据  
  22.     int a=0,i;   
  23.     for (i=0; i<height; i++)   
  24.     {   
  25.         memcpy(buf+a,pFrame_->data[0] + i * pFrame_->linesize[0], width);   
  26.         a+=width;   
  27.     }   
  28.     for (i=0; i<height/2; i++)   
  29.     {   
  30.         memcpy(buf+a,pFrame_->data[1] + i * pFrame_->linesize[1], width/2);   
  31.         a+=width/2;   
  32.     }   
  33.     for (i=0; i<height/2; i++)   
  34.     {   
  35.         memcpy(buf+a,pFrame_->data[2] + i * pFrame_->linesize[2], width/2);   
  36.         a+=width/2;   
  37.     }  
  38.   
  39.     //===============  
  40.     //到这里,buf里面已经是yuv420p的数据了,可以对它做任何的处理拉!  
  41.     //===============  
  42.     delete [] buf;  
  43. }  



 

 

不过我发现这样解码很耗cpu资源,我的Core2  E7400 2.8G的处理器,解码1920X1080分辨率每秒30帧的视频时,CPU占用率能用到差不多50%。

 

PS:原来avcodec_decode_video2这个函数会修改codec_里面的参数的,也就是说如果原来里面填的分别率是1280X720,运行avcodec_decode_video2后codec_里面会变成实际视频的分辨率。

目录
相关文章
|
数据采集 大数据 Python
FFmpeg 在爬虫中的应用案例:流数据解码详解
在大数据背景下,网络爬虫与FFmpeg结合,高效采集小红书短视频。需准备FFmpeg、Python及库如Requests和BeautifulSoup。通过设置User-Agent、Cookie及代理IP增强隐蔽性,解析HTML提取视频链接,利用FFmpeg下载并解码视频流。示例代码展示完整流程,强调代理IP对避免封禁的关键作用,助你掌握视频数据采集技巧。
260 7
FFmpeg 在爬虫中的应用案例:流数据解码详解
|
Linux 编解码 Python
FFmpeg开发笔记(二十四)Linux环境给FFmpeg集成AV1的编解码器
AV1是一种高效免费的视频编码标准,由AOM联盟制定,相比H.265压缩率提升约27%。各大流媒体平台倾向使用AV1。本文介绍了如何在Linux环境下为FFmpeg集成AV1编解码库libaom、libdav1d和libsvtav1。涉及下载源码、配置、编译和安装步骤,包括设置环境变量以启用这三个库。
778 3
FFmpeg开发笔记(二十四)Linux环境给FFmpeg集成AV1的编解码器
|
语音技术 C语言 Windows
语音识别------ffmpeg的使用01,ffmpeg的安装,会做PPT很好,ffmpeg不具备直接使用,只可以操作解码数据,ffmpeg用C语言写的,得学C语言,ffmpeg的安装
语音识别------ffmpeg的使用01,ffmpeg的安装,会做PPT很好,ffmpeg不具备直接使用,只可以操作解码数据,ffmpeg用C语言写的,得学C语言,ffmpeg的安装
|
编解码 Linux 计算机视觉
python 调用ffmpeg使用usb摄像头录制视频,输出h264格式,自动获取摄像头的最佳帧率和最大画面尺寸
使用 Python 调用 FFmpeg 进行 USB 摄像头视频录制,需先确保安装 FFmpeg 和 Python 的 `subprocess` 模块。代码示例展示了如何自动获取摄像头的最佳帧率和最大分辨率,然后录制视频。首先通过 FFmpeg 列出摄像头格式获取信息,解析出帧率和分辨率,选择最优值。之后调用 FFmpeg 命令录制视频,设置帧率、分辨率等参数。注意 `/dev/video0` 是 Linux 的摄像头设备路径,Windows 系统需相应调整。代码中未直接实现自动获取最佳参数,通常需要借助其他库如 OpenCV。
1485 3
|
编解码 5G Linux
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
AVS3是中国首个8K及5G视频编码标准,相比AVS2和HEVC性能提升约30%。解码器libuavs3d支持8K/60P视频实时解码,兼容多种平台。《FFmpeg开发实战》书中介绍了在Windows环境下如何集成libuavs3d到FFmpeg。集成步骤包括下载源码、使用Visual Studio 2022编译、调整配置、安装库文件和头文件,以及重新配置和编译FFmpeg以启用libuavs3d。
384 0
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
|
编解码 Linux 5G
FFmpeg开发笔记(二十)Linux环境给FFmpeg集成AVS3解码器
AVS3,中国制定的第三代音视频标准,是首个针对8K和5G的视频编码标准,相比AVS2和HEVC性能提升约30%。uavs3d是AVS3的解码器,支持8K/60P实时解码,且在各平台有优秀表现。要为FFmpeg集成AVS3解码器libuavs3d,需从GitHub下载最新源码,解压后配置、编译和安装。之后,重新配置FFmpeg,启用libuavs3d并编译安装,通过`ffmpeg -version`确认成功集成。
389 0
FFmpeg开发笔记(二十)Linux环境给FFmpeg集成AVS3解码器
|
11月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
1074 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
11月前
|
编解码 语音技术 内存技术
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
287 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
12月前
|
XML Java Android开发
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
GSYVideoPlayer是一款国产移动端视频播放器,支持弹幕、滤镜、广告等功能,采用IJKPlayer、Media3(EXOPlayer)、MediaPlayer及AliPlayer多种内核。截至2024年8月,其GitHub星标数达2万。集成时需使用新版Android Studio,并按特定步骤配置依赖与权限。提供了NormalGSYVideoPlayer、GSYADVideoPlayer及ListGSYVideoPlayer三种控件,支持HLS、RTMP等多种直播链接。
401 18
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer