您的位置:首页 > 汽车 > 时评 > 北京网站制作很好 乐云践新_怎么自创公众号_百度指数app官方下载_seo关键词词库

北京网站制作很好 乐云践新_怎么自创公众号_百度指数app官方下载_seo关键词词库

2025/2/24 16:12:08 来源:https://blog.csdn.net/wh9109/article/details/144951846  浏览:    关键词:北京网站制作很好 乐云践新_怎么自创公众号_百度指数app官方下载_seo关键词词库
北京网站制作很好 乐云践新_怎么自创公众号_百度指数app官方下载_seo关键词词库

yuv转h264格式步骤

  1. 初始化FFmpeg库:通过 av_register_all() avcodec_register_all() 来初始化必要的组件。
  2. 查找编码器:使用 avcodec_find_encoder 查找H.264编码器。
  3. 配置编码上下文:使用avcodec_alloc_context3分配编码上下文,并设置必要的参数。
  4. 打开编码器:通过 avcodec_open2 打开编码器。
  5. 准备输入数据:从文件中读取YUV数据,并将其填充到 AVFrame 中。
  6. 编码帧:使用 avcodec_send_frame 发送帧到编码器,并通过 avcodec_receive_packet 获取编码后的数据包。
  7. 输出H.264数据:将编码后的数据包写入输出文件。
  8. 清理资源:释放所有分配的资源,确保没有内存泄漏。

详细代码如下:

#include "ffmpegs.h"
#include <QFile>
#include <QDebug>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
}#define ERROR_BUF(ret) \char errbuf[1024]; \av_strerror(ret,errbuf,sizeof(errbuf));
ffmpegs::ffmpegs()
{}//检查像素格式
static int check_pix_fmt(const AVCodec *codec,enum AVPixelFormat pixFmt)
{const enum AVPixelFormat *p = codec->pix_fmts;while(*p != AV_PIX_FMT_NONE){if(*p == pixFmt){return 1;}p++;}return 0;
}//音频编码,返回负数:中途出现了错误,返回0:编码操作正常完成
static int encode(AVCodecContext *ctx,AVFrame *frame,AVPacket *pkt,QFile &outFile)
{int ret = avcodec_send_frame(ctx,frame);if(ret < 0){ERROR_BUF(ret);qDebug() << "avcodec_send_frame error" << errbuf;return 0;}//不断从编码器中取出编码后的数据while(ret >= 0){ret = avcodec_receive_packet(ctx,pkt);if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){//继续读取数据到frame,然后送到编码器return 0;}else if(ret < 0)//其他错误{return ret;}//成功从编码器拿到的数据outFile.write((char*)pkt->data,pkt->size);//释放pkt内部资源av_packet_unref(pkt);}
}void ffmpegs::h264Encode(VideoEncodeSpec &in,const char *outFileName,QString &str)
{//文件QFile inFile(in.filename);QFile outFile(outFileName);//一帧图片的大小int imgSize = av_image_get_buffer_size(in.pixFmt,in.width,in.height,1);int ret = 0;                            //返回结果const AVCodec *codec = nullptr;         //编码器AVCodecContext *ctx = nullptr;          //编码上下文AVFrame *frame = nullptr;               //存放编码前的数据(yuv)AVPacket *pkt = nullptr;                //存放编码后的数据(h264)//uint8_t *buf = nullptr;//获取编码器codec = avcodec_find_encoder_by_name("libx264");if(!codec){qDebug() << "encoder not found";return;}qDebug() << codec->name;//libfdk_aac对输入数据的要求:采样格式必须是16位整数//检查输入数据的采样格式if(!check_pix_fmt(codec,in.pixFmt)){qDebug() << "unsupported pixel format" << av_get_pix_fmt_name(in.pixFmt);return;}//创建编码器上下文ctx = avcodec_alloc_context3(codec);if(!ctx){qDebug() << "avcodec_alloc_context3 error";return;}//设置yuv参数ctx->width = in.width;ctx->height = in.height;ctx->pix_fmt = in.pixFmt;//设置帧率(1秒钟显示多少帧)ctx->time_base = {1,in.fps};//打开编码器ret = avcodec_open2(ctx,codec,nullptr);if(ret < 0){ERROR_BUF(ret);qDebug() << "avcodec_open2_error" << errbuf;goto end;}//创建AVFrame  -- AVFrame用来存放编码前的数据frame = av_frame_alloc();if(!frame){qDebug() << "av_frame_alloc error";goto end;}//创建AVFrameframe->width = ctx->width;frame->height = ctx->height;frame->format = ctx->pix_fmt;frame->pts = 0;//利用width、height、format创建缓冲区ret = av_image_alloc(frame->data,frame->linesize,in.width,in.height,in.pixFmt,1);if(ret < 0){ERROR_BUF(ret);qDebug() << "avcodec_open2_error" << errbuf;goto end;}//    //创建输入缓冲区(方法2)
//    buf = (uint8_t*)av_malloc(imgSize);//实际buf和frame->data[0]地址一样
//    ret = av_image_fill_arrays(frame->data,frame->linesize,
//                               buf,
//                               in.pixFmt,in.width,in.height,1);
//    if(ret < 0)
//    {
//        ERROR_BUF(ret);
//        qDebug() << "av_image_fill_arrays error" << errbuf;
//        goto end;
//    }//创建AVPacketpkt = av_packet_alloc();if(!pkt){qDebug() << "av_packet_alloc error";goto end;}//打开文件if(!inFile.open(QFile::ReadOnly)){qDebug() << "file open error" << in.filename;goto end;}if(!outFile.open(QFile::WriteOnly)){qDebug() << "file open error" << outFileName;goto end;}//读取数据到frame中while((ret = inFile.read((char*)frame->data[0],imgSize)) > 0){//进行编码if(encode(ctx,frame,pkt,outFile) < 0){goto end;}//设置帧的序号frame->pts++;}//刷新缓冲区encode(ctx,frame,pkt,outFile);end://关闭文件inFile.close();outFile.close();//av_freep(&buf);//释放资源if(frame){av_freep(&frame->data[0]);av_frame_free(&frame);}av_packet_free(&pkt);avcodec_free_context(&ctx);
}

版权声明:

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

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