当前位置:   article > 正文

FFmpeg在win10上编译安装(配置libx264)_windows上安装libx264

windows上安装libx264


背景

使用带h264的ffmpeg才是我们的最终目的!

一、先把x264搞定(包含环境)

https://blog.csdn.net/qq_37249793/article/details/115272864

二、Windows配置步骤

1.下载FFmpeg

官网(http://www.ffmpeg.org/)下载源码

2.配置环境

  1. 重命名C:/msys64/usr/bin/link.exe 为C:/msys64/usr/bin/link.bak, 避免和MSVC 的link.exe抵触
  2. 下载yasm(http://yasm.tortall.net/Download.html)改名为yasm.exe放在/usr/bin/中
  3. 把msys目录下的msys2_shell.cmd的rem set MSYS2_PATH_TYPE=inherit去掉rem可以继承vs的编译环境
  4. 打开[适用于 VS 2017 的 x64 本机工具命令提示],输入msys2_shell.cmd -mingw64
  5. 检查环境是否搭建好:which cl link yasm cpp
  6. 把编译好的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"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

最下面两行是x264对应目录
7. 输入命令sh build.sh,如果保WARNING: using libx264 without pkg-config可以不用管
8. 接下来就是编译了:

make
make install
  • 1
  • 2
  1. 生成后,基本同上一篇部署,如果缺东西的话,另外把所有的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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/282395
推荐阅读
相关标签
  

闽ICP备14008679号

        
cppcmd=keepalive&