此程序和上一篇YUN编码为H264类似,仅仅是修改几个参数

程序源码

/*** 本程序实现了YUV像素数据编码为视频码流(H264)**/#include <stdio.h>#define __STDC_CONSTANT_MACROSextern "C"
{
#include "libavdevice/avdevice.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
};int flush_encoder(AVFormatContext *fmtCtx,unsigned int streamIndex){int ret;int got_frame;AVPacket enc_pkt;if (!(fmtCtx->streams[streamIndex]->codec->codec->capabilities & AV_CODEC_CAP_DELAY)){return 0;}while (1){enc_pkt.data = NULL;enc_pkt.size = 0;av_init_packet(&enc_pkt);ret = avcodec_encode_video2 (fmtCtx->streams[streamIndex]->codec, &enc_pkt,NULL, &got_frame);av_frame_free(NULL);if (ret < 0)break;if (!got_frame){ret=0;break;}printf("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n",enc_pkt.size);/* mux encoded frame */ret = av_write_frame(fmtCtx, &enc_pkt);if (ret < 0)break;}return ret;
}int main(int argc, char *argv[])
{AVFormatContext *pFormatCtx = NULL;AVCodecContext *pCodecCtx = NULL;AVCodec *pCodec = NULL;AVOutputFormat *pOutFmt = NULL;const char *inFilename = "input.yuv";
//  const char *outFilename = "output.h264";const char *outFilename = "output.hevc";//1.注册组件:编解码器等avdevice_register_all();//2.初始化封装格式上下文//方法一:
//  pFormatCtx = avformat_alloc_context();
//  pOutFmt = av_guess_format(NULL, outFilename, NULL);
//  pFormatCtx->oformat = pOutFmt;//方法二:avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, outFilename);pOutFmt = pFormatCtx->oformat;//3.打开输出文件if (avio_open(&pFormatCtx->pb, outFilename, AVIO_FLAG_WRITE) < 0){printf("can't open output file\n");return -1;}//4.创建输出码流AVStream *pOutStream = avformat_new_stream(pFormatCtx, NULL);if (!pOutStream){printf("can't allocate new stream\n");return -1;}//5.查找视频编码器//获取编码器上下文
//  avcodec_parameters_to_context(pCodecCtx, pOutStream->codecpar);pCodecCtx = pOutStream->codec;//设置编码器上下文参数pCodecCtx->codec_id = pOutFmt->video_codec;pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;//视频的宽度和高度:确保等于输入文件的宽度和高度pCodecCtx->width = 960;pCodecCtx->height = 544;//设置帧率25fpspCodecCtx->time_base.num = 1;pCodecCtx->time_base.den = 25;//设置码率pCodecCtx->bit_rate = 400000;//设置GOPpCodecCtx->gop_size = 250;//设置量化参数pCodecCtx->qmin = 10;pCodecCtx->qmax = 51;
//  pCodecCtx->max_b_frames = 0;//6.查找编码器pCodec = avcodec_find_encoder(pCodecCtx->codec_id);if (!pCodec){printf("can't find encoder\n");return -1;}printf("pCodec.name = %s\n", pCodec->name);//若是H264编码器,要设置一些参数AVDictionary *param = NULL;if (pCodecCtx->codec_id == AV_CODEC_ID_H264){av_dict_set(&param, "preset", "slow", 0);av_dict_set(&param, "tune", "zerolatency", 0);}//H.265if(pCodecCtx->codec_id == AV_CODEC_ID_H265){
//      av_dict_set(&param, "x265-params", "qp=20", 0);av_dict_set(&param, "preset", "ultrafast", 0);av_dict_set(&param, "tune", "zero-latency", 0);}//7.打开编码器if (avcodec_open2(pCodecCtx, pCodec, &param) < 0){printf("can't open encoder\n");return -1;}//8.写入头文件信息avformat_write_header(pFormatCtx, NULL);//9.循环编码YUV文件为H264//(1)开辟缓冲区int bufSize = av_image_get_buffer_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, 1);int ySize = pCodecCtx->width * pCodecCtx->height;uint8_t *outBuffer = (uint8_t *)av_malloc(bufSize);FILE *inFile = fopen(inFilename, "rb");if (!inFile){printf("can't find input file\n");return -1;}//(2) 内容空间填充AVFrame *pFrame = av_frame_alloc();//设置真的格式、宽度和高度,否则会出现//1.AVFrame.format is not set//AVFrame.width or height is not setpFrame->format = pCodecCtx->pix_fmt;pFrame->width = pCodecCtx->width;pFrame->height = pCodecCtx->height;av_image_fill_arrays(pFrame->data,pFrame->linesize,outBuffer,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,1);//(3)开辟packetAVPacket *pPacket = (AVPacket *)av_malloc(bufSize);int i = 0, frameIndex = 0;//(4)循环编码while(1){//从YUV文件里面读取缓冲区//读取大小:ySize * 3 / 2if (fread(outBuffer, 1, ySize * 3 / 2, inFile) <= 0){printf("finished to read data\n");break;}else if (feof(inFile)){break;}//将缓冲区数据转换成AVFrame类型pFrame->data[0] = outBuffer;           //Y值pFrame->data[1] = outBuffer + ySize;   //U值pFrame->data[2] = outBuffer + ySize * 5 / 4;   //V值pFrame->pts = i * (pOutStream->time_base.den) / (pOutStream->time_base.num * 25);//10.视频编码处理//(1)发送一帧视频像素数据if (avcodec_send_frame(pCodecCtx, pFrame) < 0){printf("failed to encoder\n");return -1;}//(2)接收一帧视频压缩数据格式(像素数据编码而来)if (avcodec_receive_packet(pCodecCtx, pPacket) >= 0){//编码成功//11.将视频写入到输出文件pPacket->stream_index = pOutStream->index;if (av_write_frame(pFormatCtx, pPacket) < 0){printf("failed to write frame\n");return -1;}printf("succeed to write frame: %d\tsize:%d\n", frameIndex++, pPacket->size);}av_packet_unref(pPacket);}//写入剩余帧数据->可能没有flush_encoder(pFormatCtx, 0);//写入文件尾部信息av_write_trailer(pFormatCtx);//释放内存avcodec_close(pCodecCtx);av_free(pFrame);av_free(outBuffer);av_packet_free(&pPacket);avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);fclose(inFile);return 0;
}

问题总结

出错问题1:Lookahead depth must be greater than the max consecutive bframe count

解决办法1:关闭B帧

//    pCodecCtx->max_b_frames = 0;

解决办法2:不设置zero-latency

//        av_dict_set(&param, "tune", "zero-latency", 0);

以上2种方法二选一即可

FFmpeg —— 13.示例程序(七):视频编码器(YUV编码为H265)相关推荐

  1. FFmpeg —— 12.示例程序(六):视频编码器(YUV编码为H264)

    流程 下面附一张使用FFmpeg编码视频的流程图.使用该流程,不仅可以编码H.264的视频,而且可以编码MPEG4/MPEG2/VP8等等各种FFmpeg支持的视频.图中蓝色背景的函数是实际输出数据的 ...

  2. FFmpeg示例程序合集-批量编译脚本

    此前做了一系列有关FFmpeg的示例程序,组成了< 最简单的FFmpeg示例程序合集>,其中包含了如下项目: simplest ffmpeg player:                 ...

  3. FFmpeg示例程序合集-Git批量获取脚本

    此前做了一系列有关FFmpeg的示例程序,组成了< FFmpeg示例程序合集>,其中包含了如下项目: simplest ffmpeg player:                  最简 ...

  4. 最简单的基于FFMPEG的视频编码器(YUV编码为H.264)

    ===================================================== 最简单的基于FFmpeg的视频编码器文章列表: 最简单的基于FFMPEG的视频编码器(YUV ...

  5. 最简单的基于FFMPEG的图像编码器(YUV编码为JPEG)

    伴随着毕业论文的完成,这两天终于腾出了空闲,又有时间搞搞FFMPEG的研究了.想着之前一直搞的都是FFMPEG解码方面的工作,很少涉及到FFMPEG编码方面的东西,于是打算研究一下FFMPEG的编码. ...

  6. 【Android FFMPEG 开发】FFMPEG 交叉编译配置 ( 下载 | 配置脚本 | 输出路径 | 函数库配置 | 程序配置 | 组件配置 | 编码解码配置 | 交叉编译配置 | 最终脚本 )

    文章目录 一.FFMPEG 源码下载 解压 二.交叉编译工具 三.configure 脚本及帮助命令 四.配置 configure 脚本 五.输出目录配置 六.函数库配置 七.程序配置选项 八.组件配 ...

  7. ffmpeg实战教程(三)音频PCM采样为AAC,视频YUV编码为H264/HEVC

    ffmpeg实战教程(三)音频PCM采样为AAC,视频YUV编码为H264/HEVC https://blog.csdn.net/King1425/article/details/71180330 音 ...

  8. 用x264和ffmpeg将YUV编码为.h264(1)

    参考: 1.http://blog.csdn.net/leixiaohua1020/article/details/25430425 2.http://blog.csdn.net/leixiaohua ...

  9. 玩转springboot2.x之搭建Thymeleaf官方示例程序

    1 thymeleaf 官方示例程序介绍 前面我已经介绍了如何在spirngboot2.0中使用freemarker和jsp,今天我们来说一下如何在springboot2.0中如何使用Thymelea ...

  10. Caysn打印机安卓平台开发包接口说明文档及打印示例程序_20170609

    Caysn打印机打印开发包接口说明文档中文版:PrinterLibs_For_Android_zh_CN_20170630 Caysn打印机打印开发包接口说明文档英文版:PrinterLibs_For ...

最新文章

  1. TinyMind人工智能社区5月热门技术文章排行榜TOP15
  2. 自己封装JSTL 自定义标签
  3. 【checkStyle】ignore some class
  4. commons-io_从Commons CLI迁移到picocli
  5. python3数据类型:Set(集合)
  6. glibc交叉编译_TSN之linuxptp交叉编译
  7. 判断三个数是否能构成三角形_三角形的面积
  8. 一篇文章搞懂数据仓库:数据仓库架构-Lambda和Kappa对比
  9. 【计算机视觉】运动目标检测算法文献阅读笔记
  10. 有关java的参考软件_Java的相关的排序实现(参考软件设计师教程)
  11. Failed to start Zabbix Agent.
  12. 用python编写程序实现分段函数的计算_编写程序,实现分段函数计算,如下表所示。 x y x0 0 0=x5 x 5=x10 3x-5 10=x20 0.5x-2 20=x 0_学小...
  13. windows注册表恢复方法
  14. 前言——前端转型之殇
  15. 生命,因追逐梦想而精彩
  16. 3dmax和python做3d动画_3D动画和影视建模,用什么软件或者多个什么软件结合做比较好?...
  17. matplotlib中文显示以及设置图片大小
  18. java 发送邮件 ip被网易拉黑,发信IP或者发件人地址被网易加入了黑名单,原因如下及解决方法!...
  19. 2017AP计算机科学5分线,2017各国际学校AP分数大比拼,看看你是啥水平
  20. CC00012.druid——|HadoopOLAP_Druid.V12|——|Druid.v12|实战|Druid实战案例.V1|

热门文章

  1. C#中的Socket
  2. 大学是不是每个专业都要学计算机,大学科目里计算机是必修课程吗?是不是每个专业都要学?...
  3. 什么是服务器、云服务的优缺点是什么、为什么要使用云服务器?
  4. linux unlink 函数,linux – unlink和rm有什么区别?
  5. 日历教程:如何使Mac和iPhone上的日历显示国家节假日安排?
  6. 绕过校园网Web认证
  7. 在计算机中移动硬盘一般用作什么,移动硬盘是什么
  8. 企业微信获取临时素材,此处接口为语音接口
  9. 主仆模式(Master-Slave)
  10. 运用c++编写一个计算三角形周长和面积的程序