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

网站建设类公司可以拿哪些项目资金建e室内设计网公众号

网站建设类公司可以拿哪些项目资金,建e室内设计网公众号,洛杉矶网站建设,西宁网站建设制作公司主函数逐句解析: 由于代码太多我们只解析主函数,(其他封装函数见前面文章,同时用到了解码编码封装代码)。 初始化和参数处理 int main(int argc, char* argv[]) {/// 输入参数处理string useage "124_test_x…

主函数逐句解析:

由于代码太多我们只解析主函数,(其他封装函数见前面文章,同时用到了解码编码封装代码)。

初始化和参数处理 

int main(int argc, char* argv[])
{/// 输入参数处理string useage = "124_test_xformat 输入文件 输出文件 开始时间(秒) 结束时间(秒) 视频宽 视频高\n";useage += "124_test_xformat v1080.mp4 test_out.mp4 10 20 400 300";cout << useage << endl;if (argc < 3){return -1;}string in_file = argv[1];//输入文件参数string out_file = argv[2];//输出文件参数

 这段代码是程序的入口。它首先定义了程序的用法提示,并将其打印出来。然后,它检查命令行参数的数量是否正确,若不足三个参数,则程序退出。接着,它从命令行参数中获取输入文件和输出文件的路径。

截取时间参数和视频尺寸参数 

    /// 截取10 ~ 20 秒之间的音频视频 取多不取少// 假定 9 11秒有关键帧 我们取第9秒int begin_sec = 0;    //截取开始时间int end_sec = 0;      //截取结束时间if (argc > 3)begin_sec = atoi(argv[3]);if (argc > 4)end_sec = atoi(argv[4]);int video_width = 0;int video_height = 0;if (argc > 6)video_width = atoi(argv[5]);video_height = atoi(argv[6]);

 这段代码获取截取的开始和结束时间(以秒为单位),以及视频的宽度和高度。如果命令行参数中没有提供这些参数,则使用默认值。

解封装输入文件 

    /// 解封装//解封装输入上下文XDemux demux;AVFormatContext* demux_c = demux.Open(in_file.c_str());demux.set_c(demux_c);long long video_begin_pts = 0;long long audio_begin_pts = 0;  //音频的开始时间long long video_end_pts = 0;//开始截断秒数 算出输入视频的pts//if (begin_sec > 0){//计算视频的开始和结束播放pts if (demux.video_index() >= 0 && demux.video_time_base().num > 0){double t = (double)demux.video_time_base().den / (double)demux.video_time_base().num;video_begin_pts = t * begin_sec;video_end_pts = t * end_sec;demux.Seek(video_begin_pts, demux.video_index()); //移动到开始帧}//计算音频的开始播放ptsif (demux.audio_index() >= 0 && demux.audio_time_base().num > 0){double t = (double)demux.audio_time_base().den / (double)demux.audio_time_base().num;audio_begin_pts = t * begin_sec;}}

这段代码创建了解封装对象 XDemux 并打开输入文件。它计算开始和结束时间对应的视频和音频PTS(Presentation Timestamps),然后将解封装器定位到视频开始时间的关键帧。 

视频解码器初始化 

    /视频解码器的初始化并打开解码器XDecode decode;AVCodecContext* decode_c = decode.Create(demux.video_codec_id(), false);//设置视频解码器参数demux.CopyPara(demux.video_index(), decode_c);decode.set_c(decode_c);decode.Open();auto frame = decode.CreateFrame(); //解码后存储/

这段代码初始化视频解码器 XDecode 并打开解码器。它从解封装器中复制视频参数,并为解码后的帧数据分配内存。 

视频编码器初始化 

    /视频编码的初始化if (demux.video_index() >= 0){if (video_width <= 0)video_width = demux_c->streams[demux.video_index()]->codecpar->width;if (video_height <= 0)video_height = demux_c->streams[demux.video_index()]->codecpar->height;}XEncode encode;auto encode_c = encode.Create(AV_CODEC_ID_H265, true);encode_c->pix_fmt = AV_PIX_FMT_YUV420P;encode_c->width = video_width;encode_c->height = video_height;encode.set_c(encode_c);encode.Open();/

 这段代码初始化视频编码器 XEncode 并打开编码器。如果没有指定视频宽度和高度,则使用解封装器中的视频参数。编码器设置为 H.265 编码,像素格式为 YUV420P。

封装初始化 

    /// 封装//编码器上下文//const char* out_url = "test_mux.mp4";XMux mux;auto mux_c = mux.Open(out_file.c_str());mux.set_c(mux_c);auto mvs = mux_c->streams[mux.video_index()]; //视频流信息auto mas = mux_c->streams[mux.audio_index()]; //视频流信息//有视频if (demux.video_index() >= 0){mvs->time_base.num = demux.video_time_base().num;mvs->time_base.den = demux.video_time_base().den;//复制视频参数//demux.CopyPara(demux.video_index(), mvs->codecpar);// 复制编码器格式avcodec_parameters_from_context(mvs->codecpar, encode_c);}//有音频if (demux.audio_index() >= 0){mas->time_base.num = demux.audio_time_base().num;mas->time_base.den = demux.audio_time_base().den;//复制音频参数demux.CopyPara(demux.audio_index(), mas->codecpar);}// 写入头部,会改变timebasemux.WriteHead();

这段代码初始化封装器 XMux 并打开输出文件。它设置视频和音频流的时间基,并复制编码器参数到封装器。最后,它写入文件头。

为什么初始化封装器的时候复制编码器参数到封装器而不是解码器参数给封装器

在视频处理的流程中,封装器(muxer)初始化时需要复制编码器的参数,而不是解码器的参数,这是因为封装器的目的是将编码后的数据打包成一个文件格式,而不是处理原始解码后的数据。让我们具体看看原因:

  • 解码器参数:这些参数用于描述如何从压缩格式(如H.264、HEVC等)解码出原始的未压缩数据(如YUV帧)。解码器参数包括压缩格式、比特率、分辨率等,但这些参数主要用于解码过程。

  • 编码器参数:这些参数用于描述如何将原始的未压缩数据(如YUV帧)压缩成目标格式(如H.264、HEVC等)。编码器参数包括目标压缩格式、比特率、分辨率、帧率等。封装器需要这些参数来正确打包和封装编码后的数据流。

  • 封装器的任务是将已经编码的数据按照特定的容器格式(如MP4、MKV等)打包成文件。因此,它需要知道数据的编码方式(即编码器参数)来正确地打包数据流。

读取、解码、编码和写入数据

    int audio_count = 0;int video_count = 0;double total_sec = 0;AVPacket pkt;for (;;){if (!demux.Read(&pkt)){break;}// 视频 时间大于结束时间if (video_end_pts > 0&& pkt.stream_index == demux.video_index()&& pkt.pts > video_end_pts){av_packet_unref(&pkt);break;}if (pkt.stream_index == demux.video_index()) //视频{mux.RescaleTime(&pkt, video_begin_pts, demux.video_time_base());//解码视频if (decode.Send(&pkt)){while (decode.Recv(frame)){// 修改图像尺寸 //视频编码AVPacket* epkt = encode.Encode(frame);if (epkt){epkt->stream_index = mux.video_index();//写入视频帧 会清理pktmux.Write(epkt);//av_packet_free(&epkt);}}}video_count++;if (demux.video_time_base().den > 0)total_sec += pkt.duration * ((double)demux.video_time_base().num / (double)demux.video_time_base().den);av_packet_unref(&pkt);}else if (pkt.stream_index == demux.audio_index()){mux.RescaleTime(&pkt, audio_begin_pts, demux.audio_time_base());audio_count++;//写入音频帧 会清理pktmux.Write(&pkt);}else{av_packet_unref(&pkt);}}

这段代码读取、解码和编码数据。它从输入文件中读取数据包,并根据数据包的类型进行不同的处理。如果是视频数据包,则解码后编码并写入输出文件;如果是音频数据包,则直接写入输出文件。 

写入结尾并释放资源 

    //写入结尾 包含文件偏移索引mux.WriteEnd();demux.set_c(nullptr);mux.set_c(nullptr);encode.set_c(nullptr);cout << "输出文件" << out_file << ":" << endl;cout << "视频帧:" << video_count << endl;cout << "音频帧:" << audio_count << endl;cout << "总时长:" << total_sec << endl;getchar();return 0;
}

运行结果:

以h265重新编码了原视频,生成了一段视频。

 主函数代码总览:


#include <iostream>
#include <thread>
#include "xdemux.h"
#include "xmux.h"
#include "xdecode.h"
#include "xencode.h"
#include "xvideo_view.h"
using namespace std;
extern "C"
{ 
#include <libavformat/avformat.h>
}int main(int argc, char* argv[])
{/// 输入参数处理string useage = "124_test_xformat 输入文件 输出文件 开始时间(秒) 结束时间(秒) 视频宽 视频高\n";useage += "124_test_xformat v1080.mp4 test_out.mp4 10 20 400 300";cout << useage << endl;if (argc < 3){return -1;}string in_file = argv[1];//输入文件参数string out_file = argv[2];//输出文件参数/// 截取10 ~ 20 秒之间的音频视频 取多不取少// 假定 9 11秒有关键帧 我们取第9秒int begin_sec = 0;    //截取开始时间int end_sec = 0;      //截取结束时间if (argc > 3)begin_sec = atoi(argv[3]);if (argc > 4)end_sec = atoi(argv[4]);int video_width = 0;int video_height = 0;if (argc > 6)video_width = atoi(argv[5]);video_height = atoi(argv[6]);/// 解封装//解封装输入上下文XDemux demux;AVFormatContext* demux_c = demux.Open(in_file.c_str());demux.set_c(demux_c);long long video_begin_pts = 0;long long audio_begin_pts = 0;  //音频的开始时间long long video_end_pts = 0;//开始截断秒数 算出输入视频的pts//if (begin_sec > 0){//计算视频的开始和结束播放pts if (demux.video_index() >= 0 && demux.video_time_base().num > 0){double t = (double)demux.video_time_base().den / (double)demux.video_time_base().num;video_begin_pts = t * begin_sec;video_end_pts = t * end_sec;demux.Seek(video_begin_pts, demux.video_index()); //移动到开始帧}//计算音频的开始播放ptsif (demux.audio_index() >= 0 && demux.audio_time_base().num > 0){double t = (double)demux.audio_time_base().den / (double)demux.audio_time_base().num;audio_begin_pts = t * begin_sec;}}/视频解码器的初始化并打开解码器XDecode decode;AVCodecContext* decode_c = decode.Create(demux.video_codec_id(), false);//设置视频解码器参数demux.CopyPara(demux.video_index(), decode_c);decode.set_c(decode_c);decode.Open();auto frame = decode.CreateFrame(); //解码后存储//视频编码的初始化if (demux.video_index() >= 0){if (video_width <= 0)video_width = demux_c->streams[demux.video_index()]->codecpar->width;if (video_height <= 0)video_height = demux_c->streams[demux.video_index()]->codecpar->height;}XEncode encode;auto encode_c = encode.Create(AV_CODEC_ID_H265, true);encode_c->pix_fmt = AV_PIX_FMT_YUV420P;encode_c->width = video_width;encode_c->height = video_height;encode.set_c(encode_c);encode.Open();//// 封装//编码器上下文//const char* out_url = "test_mux.mp4";XMux mux;auto mux_c = mux.Open(out_file.c_str());mux.set_c(mux_c);auto mvs = mux_c->streams[mux.video_index()]; //视频流信息auto mas = mux_c->streams[mux.audio_index()]; //视频流信息//有视频if (demux.video_index() >= 0){mvs->time_base.num = demux.video_time_base().num;mvs->time_base.den = demux.video_time_base().den;//复制视频参数//demux.CopyPara(demux.video_index(), mvs->codecpar);// 复制编码器格式avcodec_parameters_from_context(mvs->codecpar, encode_c);}//有音频if (demux.audio_index() >= 0){mas->time_base.num = demux.audio_time_base().num;mas->time_base.den = demux.audio_time_base().den;//复制音频参数demux.CopyPara(demux.audio_index(), mas->codecpar);}// 写入头部,会改变timebasemux.WriteHead();int audio_count = 0;int video_count = 0;double total_sec = 0;AVPacket pkt;for (;;){if (!demux.Read(&pkt)){break;}// 视频 时间大于结束时间if (video_end_pts > 0&& pkt.stream_index == demux.video_index()&& pkt.pts > video_end_pts){av_packet_unref(&pkt);break;}if (pkt.stream_index == demux.video_index()) //视频{mux.RescaleTime(&pkt, video_begin_pts, demux.video_time_base());//解码视频if (decode.Send(&pkt)){while (decode.Recv(frame)){// 修改图像尺寸 //视频编码AVPacket* epkt = encode.Encode(frame);if (epkt){epkt->stream_index = mux.video_index();//写入视频帧 会清理pktmux.Write(epkt);//av_packet_free(&epkt);}}}video_count++;if (demux.video_time_base().den > 0)total_sec += pkt.duration * ((double)demux.video_time_base().num / (double)demux.video_time_base().den);av_packet_unref(&pkt);}else if (pkt.stream_index == demux.audio_index()){mux.RescaleTime(&pkt, audio_begin_pts, demux.audio_time_base());audio_count++;//写入音频帧 会清理pktmux.Write(&pkt);}else{av_packet_unref(&pkt);}}//写入结尾 包含文件偏移索引mux.WriteEnd();demux.set_c(nullptr);mux.set_c(nullptr);encode.set_c(nullptr);cout << "输出文件" << out_file << ":" << endl;cout << "视频帧:" << video_count << endl;cout << "音频帧:" << audio_count << endl;cout << "总时长:" << total_sec << endl;getchar();return 0;
}

http://www.dtcms.com/wzjs/711230.html

相关文章:

  • 深圳企业网站建设费用整站优化关键词推广
  • 国内做网站多少钱免费建站网站 百度一下
  • 做素材网站服务器wordpress可以商用吗
  • 网站流量 名词网页设计品牌故事
  • 推广网站挣钱 优帮云南宁做网站推广nnsom
  • PPT做的好的有哪些网站所有电商平台
  • 专业网站模仿做网站用的
  • 建设社区网站有什么借鉴之处网站建设又叫什么软件
  • 手机网站开发教程绵阳做绵阳做网站网站
  • 河南网站优化推广外包平台
  • wordpress 站中站石家庄市园林局招标
  • app充值网站开发长沙关键词排名首页
  • 网站制作容易吗住院证明图片在线制作
  • 快站登录环保网站设计
  • 威海自适应网站建设广告设计与制作基础知识
  • 快速建企业网站wordpress未收到数据库
  • 网站解析ip地址网站建设网络推广加盟
  • 化纤公司网站建设英文网站设计哪家好
  • 给公司做网站怎么样域名服务器在哪个国家
  • 新乡网站建设服务哪家好wordpress水印插件
  • 网站建设工程师面试30岁学网站开发
  • 如何在微信公众号里建设微网站网站后台难做吗
  • 营销型 手机网站网站建站网站的
  • 分析网站建设的论文asp.net wordpress
  • 建设部网站业绩补录动力无限做网站
  • 石家庄外贸网站制作注册企业网站
  • 网站建设管理视频企业品牌建设方案范文
  • 家电企业网站推广方案网站建设付款方式
  • 网站建设费用的财务核算中国域名有哪些
  • 服务器做网站上传快好还是下载快好搜狗竞价绑定网站要求