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

常州网站建设麦策电商外国网站翻墙怎么做

常州网站建设麦策电商,外国网站翻墙怎么做,珠海中企网站建设,广西建设网站首页主函数逐句解析: 由于代码太多我们只解析主函数,(其他封装函数见前面文章,同时用到了解码编码封装代码)。 初始化和参数处理 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/603023.html

相关文章:

  • 传奇免费网站模板下载网站建设需要什么资料
  • 网站互联网接入商网站 系统概述
  • 西安网站制作公司哪家好如何开发网站建设业务
  • 如何做网站公证如何搭建一个app
  • 台州公司建站模板本地wordpress安装教程
  • 洪梅镇网站建设深圳福永
  • 企业网站建设设计任务书广告公司名称大全最新
  • 怎么能创建自己的网站p2p网站开发的多少钱
  • 怎么给网站有一字做标记洋河门户平台
  • 网站商城建设要多少钱网站管理系统 手机
  • 设计广告公司网站建设做牛津纺衬衫的网站
  • 赣州人才网站区块链开发公司
  • 网站建设和优化内容最重要性Wordpress 微博评论
  • 综合门户网站什么意思江苏城乡与住房建设部网站
  • 公司网站建设情况说明学编程的培训机构
  • 政务网站建设具体指导意见Wordpress 跨域登录
  • 网站后台安全传播易广告投放平台
  • 旅游网站开发流程恒大地产
  • 我要在58上面做网站网站的描述 都应该写 什么 优化
  • 公司网站可以自己做怎么看网站备案号
  • 如何做网站插件网站域名详解
  • 推广网站发布文章简单的网站设计开发
  • 奉贤区做网站一个网站的后台怎么做
  • pc网站是什么app和微网站的区别
  • 长沙网站建设长沙建设银行网络设计一个月多少钱
  • 韩雪冬个人网站哪些网站可以做淘宝推广
  • 恩施网站定制广州番禺区怎么样
  • 现在哪个网站做网站好手机网站推荐大全
  • 网站群建设意见国外 图片网站
  • 参考文献 教学网站建设网页版微信可以发朋友圈吗