ffmpeg的yuv压缩h264测试代码

#include <stdio.h>
#include <conio.h>  
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#pragma   warning(disable: 4996)

extern "C" {
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
};

typedef struct{
	AVCodec			*codec;
	AVFrame			*frame;
	AVCodecContext	*c;
	AVPacket		pkt;
} CodecCtx;

typedef struct{
	FILE *pFin;
	FILE *pFout;
	char *pNameIn;
	char *pNameOut;
	uint16_t nImageWidth;
	uint16_t nImageHeight;
	uint16_t nFrameRate;
	uint64_t nBitRate;

	uint16_t nGOPSize;
	uint16_t nMaxBFrames;
	uint16_t nTotalFrames;
} IOParam;

void errReport(char *info, int val) {
	fprintf(stderr, "ERR: %s code=%d\n", info, val);
	getch();
	exit(0);
}

int Open_file(IOParam &io_param) {
	io_param.pFin = fopen(io_param.pNameIn, "rb");
	if (!(io_param.pFin))	return -1;

	io_param.pFout = fopen(io_param.pNameOut, "wb");
	if (!(io_param.pFin))	return -2;
	return 0;
}

void Close_file(IOParam &io_param) {
	fclose(io_param.pFin);
	fclose(io_param.pFout);
}

void setContext(CodecCtx &ctx, IOParam io_param) {

	ctx.c->bit_rate = io_param.nBitRate;
	ctx.c->width = io_param.nImageWidth;
	ctx.c->height = io_param.nImageHeight;

	AVRational rational = { 1,25 };
	ctx.c->time_base = rational;

	ctx.c->gop_size = io_param.nGOPSize;
	ctx.c->max_b_frames = io_param.nMaxBFrames;
	ctx.c->pix_fmt = AV_PIX_FMT_YUV420P;
	av_opt_set(ctx.c->priv_data, "preset", "slow", 0);
}

int Open_encoder(CodecCtx &ctx, IOParam io_param) {

	avcodec_register_all();
	ctx.codec = avcodec_find_encoder(AV_CODEC_ID_H264);
	if (!ctx.codec)	return -1;

	ctx.c = avcodec_alloc_context3(ctx.codec);
	if (!ctx.c) return -2;

	setContext(ctx, io_param);
	if (avcodec_open2(ctx.c, ctx.codec, NULL) < 0)
		return -3;

	ctx.frame = av_frame_alloc();
	if (!ctx.frame)	return -4;

	ctx.frame->format = ctx.c->pix_fmt;
	ctx.frame->width = ctx.c->width;
	ctx.frame->height = ctx.c->height;

	if (av_image_alloc(ctx.frame->data, ctx.frame->linesize, ctx.c->width, ctx.c->height, ctx.c->pix_fmt, 32) < 0)
		return -5;
	return 0;
}

void Close_encoder(CodecCtx &ctx){
	avcodec_close(ctx.c);
	av_free(ctx.c);
	av_freep(&(ctx.frame->data[0]));
	av_frame_free(&(ctx.frame));
}

int Read_yuv_data(CodecCtx &ctx, IOParam &io_param, int color_plane) {
	int frame_height = color_plane == 0 ? ctx.frame->height : ctx.frame->height / 2;
	int frame_width = color_plane == 0 ? ctx.frame->width : ctx.frame->width / 2;
	int frame_size = frame_width * frame_height;
	int frame_stride = ctx.frame->linesize[color_plane];

	if (frame_width == frame_stride)
		//宽度和跨度相等,像素信息连续存放
		fread_s(ctx.frame->data[color_plane], frame_size, 1, frame_size, io_param.pFin);
	else {
		//宽度小于跨度,像素信息保存空间之间存在间隔
		for (int row_idx = 0; row_idx < frame_height; row_idx++)
			fread_s(ctx.frame->data[color_plane] + row_idx * frame_stride, frame_width, 1, frame_width, io_param.pFin);
	}
	return frame_size;
}

int main() {
	printf("ffmpeg test\n");
	IOParam io_param;
	io_param.nFrameRate = 25;
	io_param.nGOPSize = 10;
	io_param.nMaxBFrames = 1;
	io_param.pNameIn = "walk.yuv";
	io_param.pNameOut = "walk.h264";
	io_param.nImageWidth = 176;
	io_param.nImageHeight = 144;
	io_param.nBitRate = 120000;
	io_param.nTotalFrames = 100;

	CodecCtx ctx = { NULL, NULL, NULL };
	int frameIdx, packetIdx = 0, ret, got_output;

	if ((ret = Open_file(io_param)) < 0)
		errReport("Open_file", ret);

	if ((ret = Open_encoder(ctx, io_param)) < 0)
		errReport("Open_encoder", ret);

	printf("start...\n");
	for (frameIdx = 0; frameIdx < io_param.nTotalFrames; frameIdx++) {
		av_init_packet(&(ctx.pkt));
		ctx.pkt.data = NULL;
		ctx.pkt.size = 0;

		Read_yuv_data(ctx, io_param, 0);		//Y
		Read_yuv_data(ctx, io_param, 1);		//U
		Read_yuv_data(ctx, io_param, 2);		//V

		ctx.frame->pts = frameIdx;
		ret = avcodec_encode_video2(ctx.c, &(ctx.pkt), ctx.frame, &got_output);
		if (ret < 0)	errReport("1: avcodec_encode_video2", ret);

		printf("frame idx: %d, pts: %d ", frameIdx, ctx.frame->pts);
		if(got_output) {
			printf("#Packet idx=%3d size=%5d pts=%d", packetIdx++, ctx.pkt.size, ctx.pkt.pts);
			fwrite(ctx.pkt.data, 1, ctx.pkt.size, io_param.pFout);
			av_packet_unref(&(ctx.pkt));
		}	
		printf("\n");
	} 
	while(1) {
		ret = avcodec_encode_video2(ctx.c, &(ctx.pkt), NULL, &got_output);
		if (ret < 0)	errReport("2: avcodec_encode_video2", ret);
		if (got_output) {
			printf("Cached frames: Packet idx=%3d size=%5d pts=%d\n", packetIdx++, ctx.pkt.size, ctx.pkt.pts);
			fwrite(ctx.pkt.data, 1, ctx.pkt.size, io_param.pFout);
			av_packet_unref(&(ctx.pkt));
		}
		else 
			break;
	} 
	printf("avcodec_encode --- ok\n");
	Close_file(io_param);
	Close_encoder(ctx);
	getch();
	return 0;
}

结果:

ffmpeg test
[libx264 @ 00517a00] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX XOP
FMA4 FMA3 LZCNT BMI1
[libx264 @ 00517a00] profile High, level 1.1
start...
frame idx: 0, pts: 0
frame idx: 1, pts: 1
frame idx: 2, pts: 2
frame idx: 3, pts: 3
frame idx: 4, pts: 4
frame idx: 5, pts: 5
frame idx: 6, pts: 6
frame idx: 7, pts: 7
frame idx: 8, pts: 8
frame idx: 9, pts: 9
frame idx: 10, pts: 10
frame idx: 11, pts: 11
frame idx: 12, pts: 12
frame idx: 13, pts: 13
frame idx: 14, pts: 14
frame idx: 15, pts: 15
frame idx: 16, pts: 16
frame idx: 17, pts: 17
frame idx: 18, pts: 18 #Packet idx=  0 size= 2756 pts=0
frame idx: 19, pts: 19 #Packet idx=  1 size=  631 pts=2
frame idx: 20, pts: 20 #Packet idx=  2 size=  275 pts=1
frame idx: 21, pts: 21 #Packet idx=  3 size=  607 pts=3
frame idx: 22, pts: 22 #Packet idx=  4 size=  305 pts=5
frame idx: 23, pts: 23 #Packet idx=  5 size=  159 pts=4
frame idx: 24, pts: 24 #Packet idx=  6 size=  351 pts=7
frame idx: 25, pts: 25 #Packet idx=  7 size=  120 pts=6
frame idx: 26, pts: 26 #Packet idx=  8 size=  404 pts=9
frame idx: 27, pts: 27 #Packet idx=  9 size=   92 pts=8
frame idx: 28, pts: 28 #Packet idx= 10 size= 2116 pts=10
frame idx: 29, pts: 29 #Packet idx= 11 size=  288 pts=12
frame idx: 30, pts: 30 #Packet idx= 12 size=  119 pts=11
frame idx: 31, pts: 31 #Packet idx= 13 size=  425 pts=14
frame idx: 32, pts: 32 #Packet idx= 14 size=  103 pts=13
frame idx: 33, pts: 33 #Packet idx= 15 size=  403 pts=16
frame idx: 34, pts: 34 #Packet idx= 16 size=  157 pts=15
frame idx: 35, pts: 35 #Packet idx= 17 size=  748 pts=18
frame idx: 36, pts: 36 #Packet idx= 18 size=  171 pts=17
frame idx: 37, pts: 37 #Packet idx= 19 size=  225 pts=19
frame idx: 38, pts: 38 #Packet idx= 20 size= 2297 pts=20
frame idx: 39, pts: 39 #Packet idx= 21 size=  389 pts=22
frame idx: 40, pts: 40 #Packet idx= 22 size=  145 pts=21
frame idx: 41, pts: 41 #Packet idx= 23 size=  575 pts=24
frame idx: 42, pts: 42 #Packet idx= 24 size=  142 pts=23
frame idx: 43, pts: 43 #Packet idx= 25 size=  574 pts=26
frame idx: 44, pts: 44 #Packet idx= 26 size=  178 pts=25
frame idx: 45, pts: 45 #Packet idx= 27 size=  656 pts=28
frame idx: 46, pts: 46 #Packet idx= 28 size=  175 pts=27
frame idx: 47, pts: 47 #Packet idx= 29 size=  219 pts=29
frame idx: 48, pts: 48 #Packet idx= 30 size= 2230 pts=30
frame idx: 49, pts: 49 #Packet idx= 31 size=  530 pts=32
frame idx: 50, pts: 50 #Packet idx= 32 size=  229 pts=31
frame idx: 51, pts: 51 #Packet idx= 33 size=  765 pts=34
frame idx: 52, pts: 52 #Packet idx= 34 size=  204 pts=33
frame idx: 53, pts: 53 #Packet idx= 35 size=  492 pts=36
frame idx: 54, pts: 54 #Packet idx= 36 size=  173 pts=35
frame idx: 55, pts: 55 #Packet idx= 37 size=  419 pts=37
frame idx: 56, pts: 56 #Packet idx= 38 size=  539 pts=39
frame idx: 57, pts: 57 #Packet idx= 39 size=  116 pts=38
frame idx: 58, pts: 58 #Packet idx= 40 size= 2276 pts=40
frame idx: 59, pts: 59 #Packet idx= 41 size=  346 pts=42
frame idx: 60, pts: 60 #Packet idx= 42 size=  168 pts=41
frame idx: 61, pts: 61 #Packet idx= 43 size=  789 pts=44
frame idx: 62, pts: 62 #Packet idx= 44 size=  233 pts=43
frame idx: 63, pts: 63 #Packet idx= 45 size=  823 pts=46
frame idx: 64, pts: 64 #Packet idx= 46 size=  201 pts=45
frame idx: 65, pts: 65 #Packet idx= 47 size=  754 pts=48
frame idx: 66, pts: 66 #Packet idx= 48 size=  215 pts=47
frame idx: 67, pts: 67 #Packet idx= 49 size=  484 pts=49
frame idx: 68, pts: 68 #Packet idx= 50 size= 2395 pts=50
frame idx: 69, pts: 69 #Packet idx= 51 size=  357 pts=51
frame idx: 70, pts: 70 #Packet idx= 52 size=  630 pts=53
frame idx: 71, pts: 71 #Packet idx= 53 size=  213 pts=52
frame idx: 72, pts: 72 #Packet idx= 54 size=  640 pts=55
frame idx: 73, pts: 73 #Packet idx= 55 size=  174 pts=54
frame idx: 74, pts: 74 #Packet idx= 56 size=  423 pts=56
frame idx: 75, pts: 75 #Packet idx= 57 size=  608 pts=58
frame idx: 76, pts: 76 #Packet idx= 58 size=  143 pts=57
frame idx: 77, pts: 77 #Packet idx= 59 size=  306 pts=59
frame idx: 78, pts: 78 #Packet idx= 60 size= 2291 pts=60
frame idx: 79, pts: 79 #Packet idx= 61 size=  594 pts=62
frame idx: 80, pts: 80 #Packet idx= 62 size=  163 pts=61
frame idx: 81, pts: 81 #Packet idx= 63 size=  610 pts=64
frame idx: 82, pts: 82 #Packet idx= 64 size=  164 pts=63
frame idx: 83, pts: 83 #Packet idx= 65 size=  603 pts=66
frame idx: 84, pts: 84 #Packet idx= 66 size=  134 pts=65
frame idx: 85, pts: 85 #Packet idx= 67 size=  596 pts=68
frame idx: 86, pts: 86 #Packet idx= 68 size=  111 pts=67
frame idx: 87, pts: 87 #Packet idx= 69 size=  187 pts=69
frame idx: 88, pts: 88 #Packet idx= 70 size= 2511 pts=70
frame idx: 89, pts: 89 #Packet idx= 71 size=  256 pts=71
frame idx: 90, pts: 90 #Packet idx= 72 size=  564 pts=73
frame idx: 91, pts: 91 #Packet idx= 73 size=  182 pts=72
frame idx: 92, pts: 92 #Packet idx= 74 size=  718 pts=75
frame idx: 93, pts: 93 #Packet idx= 75 size=  209 pts=74
frame idx: 94, pts: 94 #Packet idx= 76 size=  795 pts=77
frame idx: 95, pts: 95 #Packet idx= 77 size=  189 pts=76
frame idx: 96, pts: 96 #Packet idx= 78 size=  733 pts=79
frame idx: 97, pts: 97 #Packet idx= 79 size=  152 pts=78
frame idx: 98, pts: 98 #Packet idx= 80 size= 2972 pts=80
frame idx: 99, pts: 99 #Packet idx= 81 size=  336 pts=82
Cached frames: Packet idx= 82 size=  138 pts=81
Cached frames: Packet idx= 83 size=  466 pts=84
Cached frames: Packet idx= 84 size=  114 pts=83
Cached frames: Packet idx= 85 size=  301 pts=85
Cached frames: Packet idx= 86 size=  541 pts=87
Cached frames: Packet idx= 87 size=  144 pts=86
Cached frames: Packet idx= 88 size=  583 pts=89
Cached frames: Packet idx= 89 size=  131 pts=88
Cached frames: Packet idx= 90 size= 2637 pts=90
Cached frames: Packet idx= 91 size=  444 pts=92
Cached frames: Packet idx= 92 size=  179 pts=91
Cached frames: Packet idx= 93 size=  461 pts=94
Cached frames: Packet idx= 94 size=  137 pts=93
Cached frames: Packet idx= 95 size=  418 pts=95
Cached frames: Packet idx= 96 size=  533 pts=97
Cached frames: Packet idx= 97 size=  209 pts=96
Cached frames: Packet idx= 98 size=  325 pts=99
Cached frames: Packet idx= 99 size=  182 pts=98
avcodec_encode --- ok
[libx264 @ 00517a00] frame I:10    Avg QP:33.45  size:  2448
[libx264 @ 00517a00] frame P:51    Avg QP:36.12  size:   505
[libx264 @ 00517a00] frame B:39    Avg QP:39.58  size:   165
[libx264 @ 00517a00] consecutive B-frames: 22.0% 78.0%
[libx264 @ 00517a00] mb I  I16..4:  5.2% 62.5% 32.3%
[libx264 @ 00517a00] mb P  I16..4:  0.3%  1.4%  0.7%  P16..4: 45.2% 22.6% 10.0%
 0.0%  0.0%    skip:19.9%
[libx264 @ 00517a00] mb B  I16..4:  0.1%  0.0%  0.0%  B16..8: 51.9%  7.5%  1.0%
 direct: 1.3%  skip:38.3%  L0:40.7% L1:53.9% BI: 5.4%
[libx264 @ 00517a00] final ratefactor: 29.59
[libx264 @ 00517a00] 8x8 transform intra:62.2% inter:66.8%
[libx264 @ 00517a00] direct mvs  spatial:94.9% temporal:5.1%
[libx264 @ 00517a00] coded y,uvDC,uvAC intra: 83.5% 68.3% 34.9% inter: 17.0% 11.
2% 0.5%
[libx264 @ 00517a00] i16 v,h,dc,p: 29% 24%  9% 38%
[libx264 @ 00517a00] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 18%  8%  5%  7% 13% 14% 11%
11% 13%
[libx264 @ 00517a00] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 16%  8%  5%  8% 13% 14% 11%
11% 13%
[libx264 @ 00517a00] i8c dc,h,v,p: 39% 28% 22% 11%
[libx264 @ 00517a00] Weighted P-Frames: Y:64.7% UV:15.7%
[libx264 @ 00517a00] ref P L0: 72.8% 14.9%  9.3%  2.0%  0.7%  0.2%  0.1%
[libx264 @ 00517a00] ref B L0: 95.5%  3.5%  0.9%  0.1%
[libx264 @ 00517a00] kb/s:113.39


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值