当前位置:网站首页>FFmpeg在win10上编译安装(配置libx264)
FFmpeg在win10上编译安装(配置libx264)
2022-08-09 11:58:00 【略知12】
背景
使用带h264的ffmpeg才是我们的最终目的!
一、先把x264搞定(包含环境)
https://blog.csdn.net/qq_37249793/article/details/115272864
二、Windows配置步骤
1.下载FFmpeg
官网(http://www.ffmpeg.org/)下载源码
2.配置环境
- 重命名C:/msys64/usr/bin/link.exe 为C:/msys64/usr/bin/link.bak, 避免和MSVC 的link.exe抵触
- 下载yasm(http://yasm.tortall.net/Download.html)改名为yasm.exe放在/usr/bin/中
- 把msys目录下的msys2_shell.cmd的
rem set MSYS2_PATH_TYPE=inherit
去掉rem可以继承vs的编译环境 - 打开[适用于 VS 2017 的 x64 本机工具命令提示],输入
msys2_shell.cmd -mingw64
- 检查环境是否搭建好:
which cl link yasm cpp
- 把编译好的x264和解压的FFmpeg放在msys/home中,在FFpeg下新建build.sh:
./configure --toolchain=msvc --target-os=win64 \
--arch=x86_64 \
--enable-shared \
--enable-small \
--enable-version3 \
--enable-gpl \
--enable-nonfree \
--disable-stripping \
--disable-encoders \
--disable-decoders \
--enable-decoder=h264 \
--enable-encoder=libx264 \
--enable-encoder=mjpeg \
--enable-encoder=mpeg4 \
--prefix=./build \
--enable-libx264 \
--extra-cflags="-I/home/x264/include" \
--extra-ldflags="-LIBPATH:/home/x264/lib"
最下面两行是x264对应目录
7. 输入命令sh build.sh
,如果保WARNING: using libx264 without pkg-config可以不用管
8. 接下来就是编译了:
make
make install
- 生成后,基本同上一篇部署,如果缺东西的话,另外把所有的dll(包括libx264的)都放在Windows\System32里就可以了
3.测试
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/imgutils.h"
#include "libswscale/swscale.h"
};
#include <afxwin.h>
#pragma warning(disable:4996)
using namespace std;
typedef struct
{
int startpos;
int endpos;
int len;
int code;
int startlen;
}FrameAna;
unsigned char m_outbuf[1024 * 1024];
typedef struct
{
uint8_t m_Head[4];
int m_len;
}FrameHead_t;
void Parser();
int main()
{
Parser();
return 0;
}
//mp4中获取yuv
void Parser()
{
AVFormatContext *pFormatCtx;
int videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
uint8_t *out_buffer;
AVPacket *packet;
int ret, got_picture;
struct SwsContext *img_convert_ctx;
char filepath[] = "000.mp4";//要解析的mp4文件
FILE *fp_h264 = NULL;
FrameAna m_FrameInfo[1024];
int m_FrameIndex = 0;
fopen_s(&fp_h264, "000.h264", "wb+");//MP4输出成.h264文件
/* 初始化一个AVFormatContext ,并打开文件 */
pFormatCtx = avformat_alloc_context();
avformat_open_input(&pFormatCtx, filepath, NULL, NULL);
/* 获取视频文件信息 */
avformat_find_stream_info(pFormatCtx, NULL);
/* 查找视频的编号 */
videoindex = -1;
for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoindex = (int)i;
break;
}
if (videoindex == -1)
{
AfxMessageBox(L"can't find video,error!");
return;
}
}
/* 查找解码器 */
pCodecCtx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoindex]->codecpar);
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
/* 打开解码器 */
avcodec_open2(pCodecCtx, pCodec, NULL);
pFrame = av_frame_alloc();
out_buffer = (uint8_t *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1));
packet = (AVPacket*)av_malloc(sizeof(AVPacket));
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
/* 获取流解析对象 */
unsigned char *h264_buf;
int h264_len;
AVBitStreamFilterContext* h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
int iNeedIFrame = 1;
int iDecoderCnt = 0;
while (av_read_frame(pFormatCtx, packet) >= 0)
{
/* 读取一帧压缩数据 */
if (packet->stream_index == videoindex)
{
/* 数据解码,可获取到YUV解码后数据 */
ret = avcodec_send_packet(pCodecCtx, packet);
if (ret < 0)
{
AfxMessageBox(L"Decoder one frame , Error !");
return;
}
got_picture = avcodec_receive_frame(pCodecCtx, pFrame);
if (0 == got_picture)
{
iDecoderCnt++;
if (nullptr != fp_h264)
{
fwrite(pFrame->data[0], 1, pFrame->width * pFrame->height, fp_h264);
fwrite(pFrame->data[1], 1, pFrame->width * pFrame->height / 4, fp_h264);
fwrite(pFrame->data[2], 1, pFrame->width * pFrame->height / 4, fp_h264);
printf("我在编啦");
//每一帧都调用tojpg函数转换为jpg图像
}
}
}
av_packet_unref(packet);
}
/* flush decoder */
/*当av_read_frame()循环退出的时候,实际上解码器中可能还包含剩余的几帧数据。因此需要通过“flush_decoder”将这几帧数据输出。“flush_decoder”功能简而言之即直接调用avcodec_decode_video2()获得AVFrame,而不再向解码器传递AVPacket。*/
while (1)
{
got_picture = avcodec_receive_frame(pCodecCtx, pFrame);
if (0 != got_picture)
break;
iDecoderCnt++;
}
sws_freeContext(img_convert_ctx);
/* 释放流解析对象 */
av_bitstream_filter_close(h264bsfc);
/* 关闭文件以及释放内存 */
fclose(fp_h264);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
CString m_str;
m_str.Format(L"Get FrameCnt = %d Success !!\n", iDecoderCnt);
AfxMessageBox(m_str);
return;
}
边栏推荐
猜你喜欢
The redis library cannot be imported
内网穿透工具ngrok使用教程
web course design
redis库没法引入
900页数学论文证明旋转的黑洞不会爆炸,丘成桐:30多年来广义相对论首次重大突破...
腾讯欲成育碧最大股东/ 米哈游招NLP内容生成研究员/ AI发现四千余物种濒临灭绝...今日更多新鲜事在此...
The latest interview summary in 20022 brought by Ali senior engineer is too fragrant
ABAP 面试题:如何使用 ABAP 编程语言的 System CALL 接口,直接执行 ABAP 服务器所在操作系统的 shell 命令?
00后写个暑假作业,被监控成这笔样
GRPC整体学习
随机推荐
Semaphore SIGCHLD use, how to make the parent that the child performs over, how to make the distinction between multiple child processes. The end
虚拟机安装出现的问题汇总
Blocking, non-blocking, multiplexing, synchronous, asynchronous, BIO, NIO, AIO all in one pot
实验记录:搭建网络过程
放下手机吧:实验表明花20分钟思考和上网冲浪同样快乐
微信小程序支付及退款整体流程
win10右键文件,一直转圈
Django 无法链接mysql数据库
2022 全球 AI 模型周报
proto3-2 syntax
Common gadgets of Shell (sort, uniq, tr, cut)
Shell正则表达式,三剑客之grep命令
箭头函数和普通函数的常见区别
LeetCode 1413.逐步求和得到正数的最小值
Recommend a free 50-hour AI computing platform
脱光衣服待着就能减肥,当真有这好事?
曼城推出可检测情绪的智能围巾,把球迷给整迷惑了
【面试高频题】可逐步优化的链表高频题
Blazor Server (9) from scratch -- modify Layout
"Digital Economy Panorama White Paper" Special Analysis of Banking Industry Intelligent Marketing Application Released