致敬雷神【最简单的基于FFMPEG的视频编码器(YUV编码为H.264)】最新ffmpeg编译

Linux下FFmpeg安装配置好后,使用中的一些问题。 最近项目需要用到FFmpeg,于是按照网上的教程配置了一下,配置成功后在编译时出现了一些问题,这里记录一下。 这是安装成功后的情况 这个界面显示安装成功,并且环境也配置成功。在代码中使用时出现一些问题。我的代码中包含头文件 #include <libavutil/opt.h> #include <libavcodec/avcodec.h> #include &lt... 阅读详情

最近开始学习ffmpeg.学到 雷神的

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

https://blog.youkuaiyun.com/leixiaohua1020/article/details/25430425

发觉2020.5月的版本编译使用时已经运行不正确。后来修改了一点东西才成功yuvb编码出mp4.

首先是yuv文件。我没下他对应的工程文件,用的是640x360_yuv420p.yuv

对应要修改下

int in_w=640,in_h=360;                              //Input data's width and height

   int framenum=56;      

不然编码肯定会错的。

 

然后是原来代码运行会提示参数未指定

我只设置了格式和宽高,就能成功编码出mp4了。

    pFrame->format=    AV_PIX_FMT_YUV420P;
    pFrame->width = in_w;  
    pFrame->height = in_h;

 

运行

目录下看有个ds.mp4  111 KB (113,923 字节)

播放器打开能正常播放。

至于提示api已经不建议。暂时我就不管了。才学习。先把旧的搞懂。

 

把const char* out_file = "ds.h264";  运行,也能成功生成ds.h264. 正常播放。

 

下面是完整代码

#include "stdafx.h"
#include <stdio.h>
 
#define __STDC_CONSTANT_MACROS
 
#ifdef _WIN32
//Windows
extern "C"
{
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#ifdef __cplusplus
};
#endif
#endif
 
 
int flush_encoder(AVFormatContext *fmt_ctx,unsigned int stream_index){
	int ret;
	int got_frame;
	AVPacket enc_pkt;
	if (!(fmt_ctx->streams[stream_index]->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 (fmt_ctx->streams[stream_index]->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(fmt_ctx, &enc_pkt);
		if (ret < 0)
			break;
	}
	return ret;
}
 
int main(int argc, char* argv[])
{
	AVFormatContext* pFormatCtx;
	AVOutputFormat* fmt;
	AVStream* video_st;
	AVCodecContext* pCodecCtx;
	AVCodec* pCodec;
	AVPacket pkt;
	uint8_t* picture_buf;
	AVFrame* pFrame;
	int picture_size;
	int y_size;
	int framecnt=0;
	//FILE *in_file = fopen("src01_480x272.yuv", "rb");	//Input raw YUV data 
	FILE *in_file = fopen("640x360_yuv420p.yuv", "rb");   //Input raw YUV data
	int in_w=640,in_h=360;                              //Input data's width and height
	int framenum=56;                                   //Frames to encode
	//const char* out_file = "src01.h264";              //Output Filepath 
	//const char* out_file = "src01.ts";
	//const char* out_file = "src01.hevc";
	const char* out_file = "ds.h264";
 
	av_register_all();
	//Method1.
	pFormatCtx = avformat_alloc_context();
	//Guess Format
	fmt = av_guess_format(NULL, out_file, NULL);
	pFormatCtx->oformat = fmt;
	
	//Method 2.
	//avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);
	//fmt = pFormatCtx->oformat;
 
 
	//Open output URL
	if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){
		printf("Failed to open output file! \n");
		return -1;
	}
 
	video_st = avformat_new_stream(pFormatCtx, 0);
	//video_st->time_base.num = 1; 
	//video_st->time_base.den = 25;  
 
	if (video_st==NULL){
		return -1;
	}
	//Param that must set
	pCodecCtx = video_st->codec;
	//pCodecCtx->codec_id =AV_CODEC_ID_HEVC;
	pCodecCtx->codec_id = fmt->video_codec;
	pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
	pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
	pCodecCtx->width = in_w;  
	pCodecCtx->height = in_h;
	pCodecCtx->bit_rate = 400000;  
	pCodecCtx->gop_size=250;
 
	pCodecCtx->time_base.num = 1;  
	pCodecCtx->time_base.den = 25;  
 
	//H264
	//pCodecCtx->me_range = 16;
	//pCodecCtx->max_qdiff = 4;
	//pCodecCtx->qcompress = 0.6;
	pCodecCtx->qmin = 10;
	pCodecCtx->qmax = 51;
 
	//Optional Param
	pCodecCtx->max_b_frames=3;
 
	// Set Option
	AVDictionary *param = 0;
	//H.264
	if(pCodecCtx->codec_id == AV_CODEC_ID_H264) {
		av_dict_set(&param, "preset", "slow", 0);
		av_dict_set(&param, "tune", "zerolatency", 0);
		//av_dict_set(param, "profile", "main", 0);
	}
	//H.265
	if(pCodecCtx->codec_id == AV_CODEC_ID_H265){
		av_dict_set(&param, "preset", "ultrafast", 0);
		av_dict_set(&param, "tune", "zero-latency", 0);
	}
 
	//Show some Information
	av_dump_format(pFormatCtx, 0, out_file, 1);
 
	pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
	if (!pCodec){
		printf("Can not find encoder! \n");
		return -1;
	}
	if (avcodec_open2(pCodecCtx, pCodec,&param) < 0){
		printf("Failed to open encoder! \n");
		return -1;
	}
 
 
	pFrame = av_frame_alloc();
	picture_size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
	picture_buf = (uint8_t *)av_malloc(picture_size);
	avpicture_fill((AVPicture *)pFrame, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
 
	pFrame->format=	AV_PIX_FMT_YUV420P;
	pFrame->width = in_w;  
	pFrame->height = in_h;

	//Write File Header
	avformat_write_header(pFormatCtx,NULL);
 
	av_new_packet(&pkt,picture_size);
 
	y_size = pCodecCtx->width * pCodecCtx->height;
 
	for (int i=0; i<framenum; i++){
		//Read raw YUV data
		if (fread(picture_buf, 1, y_size*3/2, in_file) <= 0){
			printf("Failed to read raw data! \n");
			return -1;
		}else if(feof(in_file)){
			break;
		}
		pFrame->data[0] = picture_buf;              // Y
		pFrame->data[1] = picture_buf+ y_size;      // U 
		pFrame->data[2] = picture_buf+ y_size*5/4;  // V
		//PTS
		//pFrame->pts=i;
		pFrame->pts=i*(video_st->time_base.den)/((video_st->time_base.num)*25);
		int got_picture=0;
		//Encode
		int ret = avcodec_encode_video2(pCodecCtx, &pkt,pFrame, &got_picture);
		if(ret < 0){
			printf("Failed to encode! \n");
			return -1;
		}
		if (got_picture==1){
			printf("Succeed to encode frame: %5d\tsize:%5d\n",framecnt,pkt.size);
			framecnt++;
			pkt.stream_index = video_st->index;
			ret = av_write_frame(pFormatCtx, &pkt);
			av_free_packet(&pkt);
		}
	}
	//Flush Encoder
	int ret = flush_encoder(pFormatCtx,0);
	if (ret < 0) {
		printf("Flushing encoder failed\n");
		return -1;
	}
 
	//Write file trailer
	av_write_trailer(pFormatCtx);
 
	//Clean
	if (video_st){
		avcodec_close(video_st->codec);
		av_free(pFrame);
		av_free(picture_buf);
	}
	avio_close(pFormatCtx->pb);
	avformat_free_context(pFormatCtx);
 
	fclose(in_file);
 
	return 0;
}

好像有人指出过雷神当时的代码忘了释放编码器什么的,我也不管了。以后自然就知道了

雷神的代码FFMpeg 实现音视频剪切(无编解码) 雷神的代码FFMpeg 实现音视频剪切(无编解码),工程是VS2015的x64,Debug已经配置好相关的FFmpeg包含的头文件与库文件 立即下载

相关推荐

ffmpeg大收藏 致敬雷神.pdf

ffmpeg的基础笔记大收藏了 我把学习的整理到PDF了

【雷神专栏整理】-- ffmpeg

目录前言目录第一章 概论1.1 如何学习1.2 helloworld1.3 ffplay使用1.4 ffmpeg使用1.5 通用函数第二章 结构体第三章 编解码3.1 编码3.2 解码3.3 H2643.3.1编码3.3.2 解码3.4 HEVC(H265)3.4.1 解码第四章 封装与解封装(复用与解复用)第五章 实战5.1 推流5.2 视频播放器5.3 音频播放器5.4 移动端:Android & IOS5.5 内存读写5.6 编码5.7 格式转换5.8 视频网站5.9 VC工程5.10跨平台5

hh5233的博客 6690

ArcMap新手必看:Shape属性中的点ZM值到底是什么?如何快速处理

本文深入解析ArcMap中Shape属性中的点ZM值,揭示其在GIS数据中的隐藏维度作用,包括Z值(高程值)和M值(测量值)。针对ZM值可能引发的服务发布问题,提供三种高效处理方案,帮助新手快速掌握数据导入时的ZM值管控策略及精准去除方法。

weixin_42561476的博客 431

ffpmeg笔记:(1)编译雷神的ffplay4MFC踩坑记录

参考文章:1.雷霄骅,3.略知12,4.码农突围,

hwd00001的博客 1033

NSGA(非支配排序遗传算法)

在多目标优化问题中,往往存在多个相互冲突的目标需要同时优化。传统的单目标优化算法无法直接应用于这类问题,因此需要专门的多目标优化算法。非支配排序遗传算法(Non-dominated Sorting Genetic Algorithm,NSGA)是一种经典的多目标优化算法,由印度科学家 Kalyanmoy Deb 等人于 1995 年提出。NSGA 通过非支配排序和拥挤度距离来引导种群向 Pareto 最优前沿进化,从而得到一组具有良好分布性和收敛性的 Pareto 最优解。

2969

基于相位检测与锁相环的DIY超声波风速仪设计与实现

相位检测是信号处理中的一项基础技术,它通过测量两个周期信号之间的相位差来获取信息。其核心原理在于,当信号在介质中传播时,外部因素(如风速)会改变其传播速度,从而导致接收端信号的相位发生偏移。锁相环(PLL)是实现高精度相位检测的关键电路,它能动态调整本地振荡器的频率,以跟踪并锁定输入信号的相位,从而将微小的相位变化转换为易于测量的电压信号。这项技术的工程价值在于其对电路精度要求相对较低,鲁棒性好,非常适合低成本、高灵敏度的测量应用。在气象监测、工业传感和消费电子等领域,相位检测技术被广泛用于风速风向测量、位

weixin_29540599的博客 387

FFmpeg视音频分离器----向雷神学习

本程序可以将封装格式中的视频码流数据和音频码流数据分离出来。 在该例子中, 将FLV的文件分离得到H.264视频码流文件和MP3 音频码流文件。

qqshenbaobao的博客 825

STM32 移植LwIP 实现网线插拔自动恢复

STM32 移植LwIP 之后,能正常联网通讯,但是发现2个问题, 1、上电初始化前,未插入网线,之后就无法获取到IP地址(DHCP) 2、正常通讯过程中,拔掉网线,然后插回去,不知道如何复位 先看一下LWIP初始化代码 /** * LwIP initialization function */ int MX_LWIP_Init() { /* Initilialize the LwIP stack with RTOS */ tcpip_init( NULL, NULL );

tiantangmoke的博客 8073

FFMPEG简单的音视频解码

因工作需求会用到视频处理,发现伟大的ffmpeg,跟着雷神的视频记录学习过程。

m0_46496887的博客 662

别再为SCI论文配图发愁了!手把手教你用PS+AI搞定从数据图到模式图的全流程

本文详细解析了如何利用Photoshop(PS)和Illustrator(AI)高效完成SCI论文配图的全流程,涵盖数据可视化、模式图设计及期刊适配性输出。通过实战案例,帮助科研人员掌握位图与矢量图的处理技巧,提升论文配图质量,满足不同期刊的出版要求。

weixin_28630185的博客 381

MATLAB - ROS 2 工具箱入门教程

ROS 工具箱提供了一个连接 MATLAB® 和 Simulink® 与机器人操作系统(ROS 和 ROS 2)的接口。利用该工具箱,您可以设计 ROS 节点网络,并将 MATLAB 或 Simulink 生成的 ROS 节点与现有的 ROS 网络相结合。工具箱包括 MATLAB 函数和 Simulink 块,可通过记录、导入和回放 rosbag 文件来可视化和分析 ROS 数据。您还可以连接到实时 ROS 网络,访问 ROS 消息。

机器人控制与仿真应用 3068

跟着雷神学FFmpeg(一)

引言 在网上看到很多的资料,都没有雷神讲的好,下面以一个初学者的角度,去总结FFmpeg,对音视频没有任何基础的做一些基础知识的扫盲。 并且做一些C++的demo,以供学习 目录 封装格式(MP4,rmvb) 视频编码数据(H.246) 音频编码数据(AAC) 视频像素数据(显卡显示,RGB) 音频采样数据(PCM) 视频播放器原理 蓝色表示解码操作 当我们打开视频文件,就要分析有哪些视频...

Osean_li的博客 6979

YOLOv11改进策略【模型轻量化】| 使用 MoblieOne 模块,引入结构重参数化,提高模型检测效率

本文记录的是基于MobileOne的YOLOv11骨干网络改进方法研究。MobileOne的基础模块通过重参数化,。在将其替换YOLOv11的骨干网络后,实现模型轻量化。

Limiiiing的博客 1424

FFmpeg跬步浅析——雷神《YUV编码为H.264》

    首先致敬雷神!这篇博客是基于雷神的《最简单的基于FFMPEG的视频编码器(YUV编码为H.264)》编写的,自己研究了两天终于算是明白了雷神的这个例子。现在分析给大家,如果有不对的地方希望大家能指正出来。大家可以根据这个图中显示的object的关系来理解雷神的代码,下面说几处不太好理解的地方:1)AVDictionary 结构体,这个结构体是用来设置ffmpeg中一些上下文的选项用的,ke...

一只猿 还是一只鱼 3657

安装keil软件时安装不了芯片包怎么回事?芯片包安装路径放在Keill里的packs下面,弹框提示报错:Errors retumned from cpackget...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 2207

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

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

转载,转自http://blog.csdn.net/leixiaohua1020/article/details/25430425/广院的师哥,可惜天妒英才,早早地走了最近做5G项目需要传输摄像头传感器采集的视频裸数据,用H.264压缩编码格式,故复习一下对视频采用H.264 编码的方法本文介绍一个最简单的基于FFMPEG的视频编码器。该编码器实现了YUV420P的像素数据编码为H.264的压缩编码

LynnUCAS的专栏 635

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

FFmpeg重要结构体(转自雷神)

结构体间联系 a)解协议(http,rtsp,rtmp,mms) AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。URLProtocol存储输入视音频使用的封装格式。每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”) b)解封装(flv,avi,rmvb,mp4) AVFormatContext主要存储视音频封装格式中包含的信息;AVInputFormat存储输入视音频使用的封装格式。

try_zp_catch的博客 624

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

跟着雷神学FFmpeg(二)

引言 在前面已经扫盲式的恶补了相关的音视频的知识点,下面将根据雷神的思路写一些demo 书写第一个FFmpeg控制台程序 // FFmpegLen2.cpp : 定义控制台应用程序的入口点。 // // #include "stdafx.h" #include &lt;stdio.h&gt; //下面是为了兼容调用FFmpeg #define __STDC_CONSTANT_MACROS #...

Osean_li的博客 1872

FFmpeg音视频流媒体开发-【雷神专栏整理】

本文以雷神的专栏内容为基准,为了更方便个人学习,因此将专栏中的各个内容按照板块进行排序,以个人主观的知识块分章节,仅供参考!需要说明的是ffmpeg已经更新到4.x,ffmpeg中许多函数弃用、更新,雷神的专栏可以作为入门参考,深入学习的话还得自己找资料补充。原文 链接。

xiaoshuaijinniu的博客 430

Libavutil详解:理论与实战

libavutil 是一个实用库,用于辅助多媒体编程,本文记录 libavutil 库学习及 demo 例程展示。libavutil 是一个实用库,用于辅助多媒体编程。此库包含安全的可移植字符串函数、随机数生成器、数据结构、附加数学函数、加密和多媒体相关功能(如像素和样本格式的枚举)。libavcodec 和 libavformat 并不依赖此库。数学函数字符串操作内存管理相关数据结构相关错误码及错误处理日志输出其他辅助信息,比如密钥、哈希值、宏、库版本、常量等AVLog。

明天你好的博客 2173

FFmpeg中av_opt_set()的使用

在使用FFmpeg库进行编码的时候,由于需要设置AVCodecContext的参数值,需要使用到av_opt_set()这个函数,该函数被声明在libavutil\opt.h中,用来设置AVOption。这个函数的兄弟成员有: int av_opt_set (void *obj, const char *name, const char *val, int search_flags); int av_opt_set_int (void *obj, const char *name,

cchao985771161的博客 2699

FFMPEG视音频编解码学习总结

本文为雷神博客学习总结记录,主要针对FFmpeg视频编码部分学习

布想学习 892

FFMPEG源码分析之 av_opt_set_dict()

1 av_opt_set_dict() av_opt_set_dict() 声明: 所属库:libavutil(lavu) 头文件:libavutil/opt.h 声明:功能:设置所有的选项到一个对象中入参obj:将被应用选项的对象,该对象必须第一个成员为AVClass*,也即obj应该是某个上下文结构体对象入参options:需要被应用的选项字典。输入的选项字典将被释放,并且会被一个新的...

ice_ly000的博客 2807

基于 FFMPEG 的视频编码(libavcodec ,致敬雷霄骅)

基于 FFMPEG 的视频编码(libavcodec ,致敬雷霄骅) 本文参考了雷博士的博客: 最简单的基于FFmpeg的视频编码器-更新版(YUV编码为HEVC(H.265)) 还参考了另一篇博客: Qt与FFmpeg联合开发指南(三)——编码(1):代码流程演示 在为了代码简洁,代码中还用到了 Qt 。先不讲解具体的实现代码。大家先看看我封装后的类的使用方法。下面是一个简单的例子。这个例子先生成了一些 QImage 图像。然后把这些图像插入到视频中。 #include <QCoreApplicat

Ivan 的专栏 3113
上一篇: ffmpeg流方式的几种方法
下一篇: ffmpeg 官方例子encode_audio.c
smwhotjay
博客等级 码龄19年 218粉丝 135原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值