当前位置: 首页 > news >正文

网站商城建设视频教程排名优化外包公司

网站商城建设视频教程,排名优化外包公司,营销短信群发平台,商业空间设计调研目录 1、视频解码流程分析 2、FFmpeg相关解码函数 3、创建一个类专门用来视频解码 .h文件 构造函数 打开视频文件 获取视频文件流信息并查找是否有视频流 查找视频流对应的解码器 打开解码器 循环读取每一帧并生成.h264、.yuv文件 关闭解码用到的组件 主函数测试 …

目录

1、视频解码流程分析

2、FFmpeg相关解码函数

3、创建一个类专门用来视频解码

.h文件

构造函数

打开视频文件

获取视频文件流信息并查找是否有视频流

查找视频流对应的解码器

打开解码器

循环读取每一帧并生成.h264、.yuv文件

关闭解码用到的组件

主函数测试

4、测试效果

运行效果

查看h264文件

查看yuv文件


一个视频包含有音频流、视频流、字幕流等信息,下面为视频流的解码过程以及代码实现。

1、视频解码流程分析

/*解码流程分析:* 1.注册所有组件* 2.打开文件* 3.获取文件信息* 4.看看有没有相关视频信息* 5.有视频信息,找他对应的解码器* 6.打开解码器* 7.获取一帧视频流(码流)信息* 8.读取,解码的动作* 9.得到像素数据* 重复7、8、9的动作,直到没有码流数据* 10.关闭解码器* 11.关闭视频流文件** */

2、FFmpeg相关解码函数

av_register_all():注册所有组件。avformat_open_input():打开输入视频文件。avformat_find_stream_info():获取视频文件信息。avcodec_find_decoder():查找解码器。avcodec_open2():打开解码器。av_read_frame():从输入文件读取一帧压缩数据。avcodec_decode_video2():解码一帧压缩数据。avcodec_close():关闭解码器。avformat_close_input():关闭输入视频文件。

3、创建一个类专门用来视频解码

.h文件

#include <QString>extern "C"
{#include <libavcodec/avcodec.h>#include <libavdevice/avdevice.h>#include <libavformat/avformat.h>#include <libavutil/avconfig.h>#include <libswscale/swscale.h>#include <libswresample/swresample.h>
}class fDecode
{
public:fDecode();void openMvFile(QString mvPath);//打开视频文件void findVideoStream();//查找视频流void findDecoder();//查找对应的解码器void openDecoder();//打开解码器void readFrame();//读取每一帧void closeAll();//关闭用到的组件private:AVFrame *in_frame,*out_frame;//保存解码后的像素数据int avcodec_index;//视频流所在输入视频的AVStream []数组的索引AVFormatContext* avformat_context;//封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息AVCodecContext* avcodec_context;//编码器上下文结构体,保存了视频(音频)编解码相关信息AVCodec* avcodec;//每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体
};

构造函数

fDecode::fDecode()
{    //注册组件avcodec_register_all();qDebug()<<"————注册所有组件————";qDebug()<<"注册成功!";
}

打开视频文件

void fDecode::openMvFile(QString mvPath)
{qDebug()<<"————打开视频文件————";avformat_context = avformat_alloc_context();//封装格式上下文结构体开空间int res = avformat_open_input(&avformat_context,mvPath.toStdString().c_str(),NULL,NULL);//return 0 on successif (res != 0){qDebug()<<"打开失败";exit(0);}else{qDebug()<<"打开成功!";}
}

获取视频文件流信息并查找是否有视频流

void fDecode::findVideoStream()
{qDebug()<<"————获取文件信息————";this->avcodec_index = -1;int res = avformat_find_stream_info(avformat_context, NULL);//return >=0 if OKif (res < 0){qDebug()<<"获取文件信息失败";exit(0);}else{qDebug()<<"获取文件信息成功!";qDebug()<<"视频时长为:"<<avformat_context->duration/1000000.0<<"秒";qDebug()<<"视频平均混合码率为:"<<avformat_context->bit_rate/1000<<"Kbps";qDebug()<<"————获取文件视频流信息————";//nb_streams :输入视频的AVStream 个数for (int i = 0; i < avformat_context->nb_streams; i++)//遍历流{//找到视频流if (avformat_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){this->avcodec_index = i;qDebug()<<"获取文件视频流信息成功!";break;}}if (-1 == this->avcodec_index){qDebug()<<"没有找到视频流";exit(0);}}return;
}

查找视频流对应的解码器

void fDecode::findDecoder()
{qDebug()<<"————查找对应的解码器————";//avcodec_index为视频流所在输入视频的AVStream []数组的索引,通过上一步查找视频流得到的//avcodec_context 编码器上下文结构体,保存了视频(音频)编解码相关信息avcodec_context = avformat_context->streams[this->avcodec_index]->codec;//根据解码器id查找解码器对应的结构体avcodec = NULL;avcodec = avcodec_find_decoder(avcodec_context->codec_id);if (NULL == avcodec){qDebug()<<"没有找到视频解码器";exit(0);}else{qDebug()<<"找到对应的解码器为:"<<avcodec->name;}
}

打开解码器

void fDecode::openDecoder()
{qDebug()<<"————打开解码器————";//avcodec_context、 avcodec 为上一步得到的int res = avcodec_open2(avcodec_context,avcodec,NULL);//zero on success, a negative value on errorif (0 != res){qDebug()<<"打开解码器失败";exit(0);}else{qDebug()<<"打开解码器成功!";}
}

循环读取每一帧并生成.h264、.yuv文件

void fDecode::readFrame()
{qDebug()<<"————读取每一帧————";AVPacket *pkt = (AVPacket *)malloc(sizeof(AVPacket));//存储一帧压缩编码数据in_frame= av_frame_alloc();//保存解码后的像素数据out_frame = av_frame_alloc();//保存解码后剔除损坏数据后的像素数据//一帧码流数据解码后得到的像素数据有多大int numByte = avpicture_get_size(AV_PIX_FMT_YUV420P, avcodec_context->width, avcodec_context->height);//开的空间用来保存像素数据uint8_t *buf = (uint8_t *)av_malloc(numByte * sizeof(uint8_t));//像素数据的填充avpicture_fill((AVPicture *)out_frame, buf, AV_PIX_FMT_YUV420P, avcodec_context->width, avcodec_context->height);//保存转换规则SwsContext *sws_content = nullptr;//转换规则的设置sws_content = sws_getContext(avcodec_context->width, avcodec_context->height ,avcodec_context->pix_fmt,avcodec_context->width, avcodec_context->height ,AV_PIX_FMT_YUV420P,SWS_BICUBIC,nullptr,nullptr,nullptr);FILE *fp_H264=NULL;FILE *fp_yuv=NULL;//以二进制格式创建或打开文件fp_H264=fopen("test.h264","wb+");fp_yuv=fopen("test.yuv","wb+");if(fp_H264 == NULL || fp_yuv == NULL){qDebug()<<"file open fail!";exit(0);}int size = avcodec_context->width * avcodec_context->height;av_new_packet(pkt,size);//循环读取每一帧while (av_read_frame(avformat_context,pkt) == 0) //return 0 if OK, < 0 on error or end of file{if(pkt->stream_index == this->avcodec_index)  //如果这一帧是视频流{fwrite(pkt->data,pkt->size,1,fp_H264);//写入h264文件//解码——>得到yuv AVFrame//got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.int got_picture_ptr = -1;avcodec_decode_video2(avcodec_context, in_frame, &got_picture_ptr, pkt);if(got_picture_ptr != 0)//做解码的操作{//把解码得到的损坏的数据剔除sws_scale(sws_content, in_frame->data, in_frame->linesize, 0, in_frame->height,  //原数据out_frame->data, out_frame->linesize);  //输出数据fwrite(out_frame->data[0], size, 1, fp_yuv);//写入y数据fwrite(out_frame->data[1], size/4, 1, fp_yuv);//写入u数据fwrite(out_frame->data[2], size/4, 1, fp_yuv);//写入v数据}}}av_packet_unref(pkt);//清空}//关闭h264、yuv文件fclose(fp_H264);fclose(fp_yuv);qDebug()<<"写入成功";
}

关闭解码用到的组件

void fDecode::closeAll()
{qDebug()<<"————关闭所有组件————";av_frame_free(&in_frame);av_frame_free(&out_frame);avcodec_close(avcodec_context);avformat_free_context(avformat_context);qDebug()<<"关闭成功";
}

主函数测试

int main(int argc, char *argv[])
{QApplication a(argc, argv);qDebug()<<"ffmpeg版本号:"<<avcodec_version();fDecode mvDecode;mvDecode.openMvFile("mv/Warcraft3_End.avi");//打开视频文件mvDecode.findVideoStream();//查找视频流mvDecode.findDecoder();//查找对应的解码器mvDecode.openDecoder();//打开解码器mvDecode.readFrame();//读取每一帧mvDecode.closeAll();//关闭用到的组件return 0;
}

4、测试效果

运行效果

        当前目录下会生成test.h264文件和test.yuv文件

        H.264压缩方法比较复杂。包含了帧内预测、帧间预测、熵编码、环路滤波等环节构成。可以将图像数据压缩100倍以上,所以可以发现未压缩的像素数据yuv文件比压缩后的码流数据h624文件大非常多。

查看h264文件

查看yuv文件

 

http://www.lbrq.cn/news/2459935.html

相关文章:

  • 用jsp做婚纱网站的流程网站优化排名软件网站
  • 厦门网站建设工作室网站内容优化方法
  • 东阳网站建设有哪些seo培训一对一
  • 中国党风廉政建设网站by网站域名
  • 郑州哪家公司做网站好菏泽百度推广公司电话
  • 馆陶网站建设价格代码编程教学入门
  • 南浔城乡建设局网站最新网站查询工具
  • 上海服装集团网站建设app线下推广怎么做
  • 2核4G服务器wordpressseo推广公司价格
  • 网站关键词和网页关键词的样本泉州百度网站推广
  • 如何成立一家公司合肥seo
  • 劳务网站怎样做百度世界排名
  • wordpress站群管理seo黑帽有哪些技术
  • 自做网站告白如何弄网站品牌推广公司
  • 做视频搬运工的网站互联网十大企业
  • seo 网站 制作搜索指数在线查询
  • 下载网站的表格要钱如何做深圳优化服务
  • 流媒体网站建设方案怎么做网站推广
  • wordpress 做音乐网站友谊平台
  • 市场管理监督局是干什么的网站优化推广平台
  • php做的大型网站新闻今天的最新新闻
  • 九年级上册信息技术做网站线上平台推广方案
  • 中山网站建设哪家好网站推广广告
  • 免费推广网站软件子域名在线查询
  • 企业网站建设成都个人如何在百度上做广告
  • 烟台建站程序北京百度推广代理公司
  • 做电商什么外推网站好广点通推广登录入口
  • 免费做网站靠谱么域名注册入口
  • 企业网站设计谁家做了的好嘉兴百度快照优化排名
  • seo手机搜索快速排名什么叫做seo
  • 基于java的在线教育平台管理系统、在线学习系统的设计与实现
  • 三防平板搭载2D扫描头:工业数据采集的革新利器
  • 【AcWing 143题解】最大异或对
  • 【C++基础】指针常量 | 常量指针 | int* p | const int* p | int* const p| const int* const p
  • Qt(资源库和按钮组)
  • 技术赋能多元探索:我的技术成长与行业洞察