致敬雷神【最简单的基于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

电商数据分析18——电商广告投放的数据分析与优化

在当今的电商行业中,广告投放是提高品牌知名度、吸引潜在客户和增加销售额的关键策略之一。随着市场竞争的加剧,仅仅依靠直观判断和传统方法已经无法满足广告投放的需求。数据分析在这里扮演了至关重要的角色,它可以帮助企业更准确地定位目标受众,评估广告效果,优化广告内容,从而提高广告效率和投资回报率(ROI)。

theskylife的博客 5702

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

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

hwd00001的博客 1033

线上专利申请(超详细)| 签名确认

在【法人登录】页面点击【证书登录】按钮,弹出证书登录提示框,点击【确 认】按钮,进入到输入证书密码页面,点击【取消】按钮,取消本次操作。企业在提交申请时,需要增加签名,如使用企业账户点击提交,会弹出“法人、代理机构不能签名,请使用经办人签名”,这个时候就需要换个账号了。在需要签名时,将专利官网的登录方式点击法人登录,选择扫码登录,使用移动端经办人账户的扫一扫功能扫描登录。登录完成后,再点击签名,使用移动端扫一扫功能,扫描签名,输入证书号,确认签名,并提交。最后,祝大家的申请都成功!

weixin_62112323的博客 9110

复用浏览器之跳过扫码登录

复用浏览器 1、通过命令启动浏览器:chrome --remote-debugging-port=9222(前提是退出所有的chrome浏览器) 2、启动浏览器之后,在地址栏输入127.0.01:9222,成功复用如下图所示:

qq_43911915的博客 2033

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

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

qqshenbaobao的博客 825

OpenCV图像去畸变实战指南:从原理到参数调优(附完整代码与效果对比)

本文深入解析了OpenCV图像去畸变的原理与实战技巧,详细对比了标准透视、鱼眼及全能型omnidir三种校正函数的核心参数调优方法。通过分析alpha、balance、centerX/Y及focalScale四大参数对输出效果的影响,并结合完整代码与效果对比图,帮助开发者精准校正镜头畸变,提升计算机视觉任务精度。

weixin_29046611的博客 341

FFMPEG简单的音视频解码

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

m0_46496887的博客 662

大地坐标系与经纬度转换(一):大地坐标系简介

一、大地坐标系 大地坐标系是大地测量中以参考椭球面为基准面建立起来的坐标系。地面点的位置用大地经度、大地纬度和大地高度表示。 二、地心坐标系 ...

qq_42895926的博客 6万+

ros2 humble中使用realsense t265与d435

前提,安装realsense SDK 2.51.1版本并且能成功启动realsense-viewer V2.51.1想要在ros2中使用realsense t265,必须配合realsense SDK v2.51.1使用realsense-ros 4.51.1版本,因为新版本realsense ros2不再对t265支持下面记录源码编译安装 realsense-ros 4.51.1版本。

m0_72797388的博客 952

跟着雷神学FFmpeg(一)

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

Osean_li的博客 6979

保姆级教程:在瑞芯微RV1126B上部署轻量化YOLOv8,实现端侧实时目标检测

本文详细介绍了在瑞芯微RV1126B芯片上部署轻量化YOLOv8模型的完整流程,包括开发环境搭建、模型训练优化、量化转换及嵌入式部署。通过利用RV1126B的3TOPS NPU算力和AI-ISP特性,实现端侧实时目标检测,提升边缘AI应用的性能和效率。

weixin_30329623的博客 266

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

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

一只猿 还是一只鱼 3657

【科研数据获取】根据Excel表个中的企业/公司信息批量获取经纬度坐标,并进行地图可视化

批量获取企业/公司的经纬度坐标,并进行地图可视化1 需求2 实现途径3 需求逐步实现 1 需求 在做项目的时候,老板或者项目答辩时候甲方最喜欢看到的就是可视化结果,尤其是涉及到地图可视化。很多时候会遇到企业/公司的数据,想要做地图可视化,必不可少的就是要获取它们具体地址:第一种就是像查户口一样精准一下具体的城镇街道,还有一种就是经纬度信息,前一种属于文字内容往往用于管理方面,第二种数字信息多用于数据处理与分析。 2 实现途径 获取地理信息数据,自然需要使用到地图的功能,这里直接采用百度地图的拾取坐标系统,

lys_828的博客 2336

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

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

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

LynnUCAS的专栏 635

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

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

try_zp_catch的博客 624

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

跟着雷神学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、付费专栏及课程。

余额充值