您的位置:首页 > 科技 > IT业 > b2b网站的特点_seo公司哪家_seo排名规则_如何软件网站优化公司

b2b网站的特点_seo公司哪家_seo排名规则_如何软件网站优化公司

2025/4/15 15:24:46 来源:https://blog.csdn.net/m0_50127633/article/details/147076652  浏览:    关键词:b2b网站的特点_seo公司哪家_seo排名规则_如何软件网站优化公司
b2b网站的特点_seo公司哪家_seo排名规则_如何软件网站优化公司

视频编码流程

在这里插入图片描述

  1. avcodec_find_encoder:首先,通过指定的编码器名称(如H.264、MPEG-4等)找到对应的编码器。
  2. avcodec_alloc_context3:为找到的编码器分配一个上下文结构,这个结构包含了编码器所需的各种参数和状态信息。
  3. 设置编码上下文参数:配置编码器上下文的参数,包括分辨率、帧率、比特率等。
  4. avcodec_open2:打开编码器,准备开始编码工作。
  5. av_packet_alloc:分配一个AVPacket结构,用于存储编码后的数据包。
  6. av_frame_alloc:分配一个AVFrame结构,用于存储原始视频帧的数据。
  7. 设置Frame参数:配置AVFrame结构,包括设置像素格式、宽度、高度等参数。
  8. av_frame_get_buffer:为AVFrame分配缓冲区,用于存储视频帧的数据。
  9. 读文件:从输入源读取视频帧数据。如果读取成功,则继续处理;如果读取失败,则跳转到flush_encode步骤。
  10. avcodec_send_frame:将AVFrame发送给编码器进行编码。
  11. avcodec_receive_packet:从编码器接收编码后的数据包。
  12. 写文件:将编码后的数据包写入输出文件。
  13. flush_encode:当读取文件失败时,调用flush_encode函数清理编码器中的剩余数据。
  14. 释放资源:释放之前分配的所有资源,包括AVFrame、AVPacket和编码器上下文。
//准备yuv文件//引入FFMPEG库#include<QDebug>
extern "C"{
#include<libavcodec/avcodec.h>
}const char* inFileName = "D:\\output.yuv";
const char* outFileName = "output.h264";/*** @brief 编码一帧数据并写入输出文件** @param codecContext 编码器上下文,包含编码器配置信息* @param packet 存储编码后的数据包* @param frame 待编码的原始帧数据* @param outFile 输出文件指针* @return int 成功返回0,失败返回错误码(负数)*/
int encode(AVCodecContext* codecContext, AVPacket* packet, AVFrame* frame, FILE* outFile) {// 1. 发送待编码的帧到编码器int ret = avcodec_send_frame(codecContext, frame);if (ret < 0) {qDebug() << "avcodec_send_frame failed";return -8; // 错误码-8:发送帧失败}// 2. 循环接收编码后的数据包while (ret == 0) {ret = avcodec_receive_packet(codecContext, packet);// 2.1 检查是否需要更多输入或已结束if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {return 0; // 正常情况:需要更多数据或编码完成}// 2.2 检查其他错误else if (ret < 0) {qDebug() << "avcodec_receive_packet failed";return -9; // 错误码-9:接收数据包失败}// 3. 成功接收到数据包,写入文件if (ret == 0) {fwrite(packet->data, 1, packet->size, outFile);}}return 0; // 正常结束
}int main(){int ret = 0;//准备编码器const AVCodec* codec = nullptr;AVCodecContext* codecContext = nullptr;AVPacket* packet = nullptr;AVFrame* frame = nullptr;FILE* inFile = nullptr;FILE* outFile = nullptr;//查找264编码器codec = avcodec_find_encoder(AV_CODEC_ID_H264);if(!codec){qDebug() << "avcodec_find_encoder failed";return -1;}//分配编码器上下文codecContext = avcodec_alloc_context3(codec);if(!codecContext){qDebug() << "avcodec_alloc_context3 failed";return -2;}//设置上下文参数codecContext->width = 1280; //设置视频的宽度为 1280 像素codecContext->height = 720; //设置视频的高度为 720 像素codecContext->time_base = AVRational{1, 25}; //设置时间基(time base)为 1/25 秒,这是时间戳的基本单位,表示每个时间单位代表 1/25 秒codecContext->pix_fmt = AV_PIX_FMT_YUV420P; //设置像素格式为 YUV420PcodecContext->framerate = AVRational{25, 1}; //设置帧率为 25 帧/秒//打开编码器ret = avcodec_open2(codecContext, codec, NULL);if(ret != 0){qDebug() << "avcodec_open2 failed";return -3;}packet = av_packet_alloc();if(!packet){qDebug() << "avcodec_open2 failed";return -4;}frame = av_frame_alloc();if(!frame){qDebug() << "av_frame_alloc failed";return -5;}//设置帧参数frame->width = 1280;frame->height = 720;frame->format = AV_PIX_FMT_YUV420P;// 申请frame的内存来存放帧数据ret = av_frame_get_buffer(frame, 0);if (ret < 0) {  // 修正:检查返回值是否为负数(失败)qDebug() << "av_frame_get_buffer failed, error:" << ret;return -6;}//我们开始打开输入文件读数据inFile = fopen(inFileName, "rb");if(inFile == nullptr){qDebug() << "open infile failed";return -7;}//打开输出文件写数据outFile = fopen(outFileName, "wb");if(outFile == nullptr){qDebug() << "open outFileName failed";return -7;}//循环读数据编码while(!feof(inFile)){//frame能不能写,我们需要将yuv数据填充到frame,检查是否可写ret = av_frame_is_writable(frame);if(ret < 0){//如果不可写,我们设置可写ret = av_frame_make_writable(frame);}//从yuv文件读取//y分量fread(frame->data[0], 1, frame->width * frame->height, inFile);//u分量fread(frame->data[1], 1, frame->width * frame->height / 4, inFile);//v分量fread(frame->data[2], 1, frame->width * frame->height / 4, inFile);//编码encode(codecContext, packet, frame, outFile);}//如果没有数据了,我们退出//flush_encodeencode(codecContext, packet, nullptr, outFile);  //刷新编码器qDebug()<<"编码完成";//释放资源av_packet_free(&packet);av_frame_free(&frame);avcodec_free_context(&codecContext);fclose(inFile);fclose(outFile);return 0;
}

音频编码实战

在这里插入图片描述

一、初始化阶段
  1. avcodec_find_encoder
    查找合适的音频编码器(如 AAC、MP3)。
  2. avcodec_alloc_context3
    分配编码器上下文。
  3. 设置编码器参数
    如采样率、通道数、比特率等。
  4. avcodec_open2
    打开编码器。
  5. avformat_alloc_output_context2
    创建输出格式上下文。
  6. avformat_new_stream
    新建输出音频流。
  7. avio_open
    打开输出文件。
  8. avformat_write_header
    写入文件头信息。
  9. swr_init
    初始化音频重采样(如果需要转换采样格式或通道布局)。
二、编码循环阶段
  1. av_frame_get_buffer
    获取一个音频帧缓冲区用于填充数据。
  2. 读取文件
    判断是否还有音频数据需要编码。
    • 如果有(true):
      • avcodec_send_frame:送入音频帧。
      • avcodec_receive_packet:从编码器接收压缩数据。
      • av_interleaved_write_frame:将编码后数据写入输出文件。
    • 如果没有(false):
      • flush_encode:刷新编码器内部缓存(送入空帧)。
      • av_write_trailer:写入文件尾。
      • 释放资源:关闭文件、释放上下文、帧、包等资源。
#include <QDebug>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
}int main(){char inputfile[] = "D:\\output.pcm";char outputfile[] = "audio.aac";//准备编码器const AVCodec* avCodec = avcodec_find_encoder(AV_CODEC_ID_AAC);if(!avCodec){qDebug() << "avcodec_find_encoder failed";return -1;}//准备编码上下文AVCodecContext* avCodecContext = avcodec_alloc_context3(avCodec);if(!avCodecContext){qDebug() << "avcodec_alloc_context3 failed";return -1;}//设置上下文参数int ret=0;avCodecContext->sample_rate = 44100;  //表示音频的采样率为 44.1kHz(CD 音质标准)。avCodecContext->channels = 2; //双声道avCodecContext->sample_fmt = AV_SAMPLE_FMT_FLTP; //表示浮点型平面(Planar)采样格式。avCodecContext->bit_rate = 64000;  //表示编码后的音频比特率为 64kbps。avCodecContext->channel_layout = AV_CH_LAYOUT_STEREO;  //明确指定声道布局为立体声(左右声道)。//打开解码器ret = avcodec_open2(avCodecContext, avCodec,NULL);if(ret<0){qDebug() << "avcodec_open2 failed";return -1;}//创建输出上下文AVFormatContext* avFormatContext = NULL;//初始化输出上下文avformat_alloc_output_context2(&avFormatContext, NULL, NULL, outputfile);if(!avFormatContext){qDebug() << "avformat_alloc_output_context2 failed";return -1;}// 新建输出音频流AVStream* st = avformat_new_stream(avFormatContext, NULL);st->codecpar->codec_tag = 0;//这个流需要获取编码器参数avcodec_parameters_from_context(st->codecpar, avCodecContext);//打开输出文件ret = avio_open(&avFormatContext->pb, outputfile, AVIO_FLAG_WRITE);if(ret<0){qDebug() << "avio_open failed";return -1;}//写入文件头信息avformat_write_header(avFormatContext, NULL);SwrContext* swrContext = NULL;// 设置参数, 1. 上下文 2.输出声道布局 4.输出采样率, 5.输入声道布局 6.输入样本格式 7.输入采样率 8.配音 9.日志swrContext = swr_alloc_set_opts(swrContext, avCodecContext->channel_layout, avCodecContext->sample_fmt, avCodecContext->sample_rate,AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 44100,0, 0);if(!swrContext){qDebug() << "swr_alloc_set_opts failed";return -1;}// 初始化音频重采样ret = swr_init(swrContext);if(ret<0){qDebug() << "swr_init failed";return -1;}//准备frameAVFrame* avFrame = av_frame_alloc();avFrame->format = AV_SAMPLE_FMT_FLTP;avFrame->channels=2;avFrame->channel_layout = AV_CH_LAYOUT_STEREO;avFrame->nb_samples=1024;// 获取一个音频帧缓冲区用于填充数据ret = av_frame_get_buffer(avFrame, 0);if(ret<0){qDebug() << "av_frame_get_buffer failed";return -1;}//开始读pcm->frameint readSize = avFrame->nb_samples*2*2; //双声道,float 16位,每次读取的大小char* pcms = new char[readSize]; //申请内存FILE* fp = fopen(inputfile, "rb");//开始编码for(;;){AVPacket pkt;av_init_packet(&pkt);int len = fread(pcms,1,readSize, fp);if(len <=0){break;}else{//开始重采样const uint8_t* data[1];data[0] = (uint8_t*)pcms;len = swr_convert(swrContext, avFrame->data, avFrame->nb_samples, data, avFrame->nb_samples);if(len <=0){qDebug() << "swr_convert failed";break;}//重采样成功,我们开始编码数据ret = avcodec_send_frame(avCodecContext, avFrame);if(ret < 0){qDebug() << "avcodec_send_frame failed";continue;}//ret = avcodec_receive_packet(avCodecContext, &pkt);if(ret == 0){av_interleaved_write_frame(avFormatContext, &pkt);}}}//写入结尾av_write_trailer(avFormatContext);//释放资源fclose(fp);avio_close(avFormatContext->pb);avcodec_close(avCodecContext);avcodec_free_context(&avCodecContext);avformat_free_context(avFormatContext);return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com