x264编码实现用yuyv转为h264

x264是常见的编码库,下面是利用x264将yuyv编码为h264
x264.h

#ifndef _H264ENCODER_H_
#define _H264ENCODER_H_

#include <stdint.h>
#include <stdio.h>

#include "x264.h"

typedef struct {
	x264_param_t *param;
	x264_t *handle;
	x264_picture_t *picture;	//说明一个视频序列中每帧特点
	x264_nal_t *nal;
} Encoder;

//初始化编码器,并返回一个编码器对象
void h264_compress_init(Encoder * en, int width, int height);

//编码一帧
int h264_compress_frame(Encoder * en, int type, uint8_t * in, uint8_t * out);

//释放内存
void h264_compress_uninit(Encoder * en);

#endif

h264encoder.c

static int i_pts = 0;
void h264_compress_init(Encoder * en, int width, int height)
{
en->param = (x264_param_t *) malloc(sizeof(x264_param_t));
en->picture = (x264_picture_t *) malloc(sizeof(x264_picture_t));
x264_param_default(en->param); //set default param
//x264_param_apply_preset(en->param,“slower”);
//en->param->rc.i_rc_method = X264_RC_CQP;//设置为恒定码率
//en->param->i_log_level = X264_LOG_NONE;
//en->param->i_threads = X264_SYNC_LOOKAHEAD_AUTO;//取空缓存区使用不死锁保证
//en->param->i_frame_total = 0;
//en->param->i_keyint_max = 10;
//en->param->i_bframe = 5; //两个参考帧之间b帧的数目
//en->param->b_open_gop = 0;
//en->param->i_bframe_pyramid = 0;
//en->param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
//en->param->rc.i_bitrate = 1024 * 10;//rate 为10 kbps
en->param->i_width = width; //set frame width
en->param->i_height = height; //set frame height
en->param->rc.i_lookahead = 0; //表示i帧向前缓冲区
en->param->i_fps_num = 25; //帧率分子
en->param->i_fps_den = 1; //帧率分母
en->param->i_csp = X264_CSP_I422;
x264_param_apply_profile(en->param, “high422”); //使用baseline

if ((en->handle = x264_encoder_open(en->param)) == 0) {
	printf("x264_encoder_open error!\n");
	return;
}
/* Create a new pic */
x264_picture_alloc(en->picture, X264_CSP_I422, en->param->i_width,
				   en->param->i_height);
en->picture->img.i_csp = X264_CSP_I422;
en->picture->img.i_plane = 3;

return;

}

int h264_compress_frame(Encoder * en, int type, uint8_t * in, uint8_t * out)
{
x264_picture_t pic_out;
int nNal = -1;
int result = 0;
int i = 0;
uint8_t *p_out = out;

char *y = en->picture->img.plane[0];
char *u = en->picture->img.plane[1];
char *v = en->picture->img.plane[2];

int is_y = 1, is_u = 1;
int y_index = 0, u_index = 0, v_index = 0;
int yuv422_length = 2 * en->param->i_width * en->param->i_height;

//序列为YU YV YU YV,一个yuv422帧的长度 width * height * 2 个字节
for (i = 0; i < yuv422_length; ++i) {
	if (is_y) {
		*(y + y_index) = *(in + i);
		++y_index;
		is_y = 0;
	} else {
		if (is_u) {
			*(u + u_index) = *(in + i);
			++u_index;
			is_u = 0;
		} else {
			*(v + v_index) = *(in + i);
			++v_index;
			is_u = 1;
		}
		is_y = 1;
	}
}

switch (type) {
case 0:
	en->picture->i_type = X264_TYPE_P;
	break;
case 1:
	en->picture->i_type = X264_TYPE_IDR;
	break;
case 2:
	en->picture->i_type = X264_TYPE_I;
	break;
default:
	en->picture->i_type = X264_TYPE_AUTO;
	break;
}

      en->picture->i_pts=pts++;
//printf("en->handle->param.i_csp:%08x\n", en->handle->param.i_csp);
if (x264_encoder_encode(en->handle, &(en->nal), &nNal, en->picture,
						&pic_out) < 0) {
	printf("x264_encoder_encode error,type:%08x!\n",
		   en->picture->img.i_csp);
	return -1;
}
    
for (i = 0; i < nNal; i++) {
	memcpy(p_out, en->nal[i].p_payload, en->nal[i].i_payload);
	p_out += en->nal[i].i_payload;
	result += en->nal[i].i_payload;
}

return result;

}

void h264_compress_uninit(Encoder * en)
{
if (en->picture) {
x264_picture_clean(en->picture);
free(en->picture);
en->picture = 0;
}
if (en->param) {
free(en->param);
en->param = 0;
}
if (en->handle) {
x264_encoder_close(en->handle);
}
free(en);

return;

}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这是一个比较复杂的程序,需要用到 x264 库和一些图像处理技术。以下是一个简单的示例程序,只实现了将 YUYV 数据转换成 H.264 编码的功能,您可以参考一下: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <x264.h> /* 定义输入图像的宽度和高度 */ #define WIDTH 640 #define HEIGHT 480 /* 定义编码输出的比特率和帧率 */ #define BITRATE 500000 #define FRAMERATE 25 int main(int argc, char **argv) { x264_param_t param; x264_t *encoder; x264_picture_t picture_in, picture_out; x264_nal_t *nal; int i, j, ret, frame_size, nal_count = 0; uint8_t *buf, *yuyv; /* 初始化 x264 库 */ x264_param_default_preset(&param, "ultrafast", "zerolatency"); param.i_threads = 1; param.i_width = WIDTH; param.i_height = HEIGHT; param.i_fps_num = FRAMERATE; param.i_fps_den = 1; param.i_keyint_max = FRAMERATE; param.i_rc_method = X264_RC_CRF; param.f_rf_constant = 25; param.i_bframe = 0; x264_param_apply_profile(&param, "baseline"); encoder = x264_encoder_open(&param); /* 计算每帧数据的大小 */ frame_size = WIDTH * HEIGHT * 2; /* 分配 YUYV 数据缓冲区和编码输出缓冲区 */ yuyv = (uint8_t *) malloc(frame_size); buf = (uint8_t *) malloc(frame_size); /* 循环读取 YUYV 数据并进行编码 */ while (1) { /* 读取 YUYV 数据 */ if (fread(yuyv, 1, frame_size, stdin) < frame_size) break; /* 将 YUYV 数据转换成 YUV420P 格式 */ for (i = 0; i < HEIGHT; i++) { for (j = 0; j < WIDTH; j++) { int index = i * WIDTH * 2 + j * 2; int y = yuyv[index]; int u = yuyv[index + 1] - 128; int v = yuyv[index + 3] - 128; picture_in.img.plane[0][i * WIDTH + j] = y; picture_in.img.plane[1][i / 2 * WIDTH / 2 + j / 2] = u; picture_in.img.plane[2][i / 2 * WIDTH / 2 + j / 2] = v; } } /* 设置输入图像的参数 */ picture_in.i_type = X264_TYPE_AUTO; picture_in.i_qpplus1 = 0; picture_in.i_pts = nal_count * 1000 / FRAMERATE; picture_in.img.i_csp = X264_CSP_I420; picture_in.img.i_plane = 3; picture_in.img.i_stride[0] = WIDTH; picture_in.img.i_stride[1] = WIDTH / 2; picture_in.img.i_stride[2] = WIDTH / 2; /* 编码输入图像 */ ret = x264_encoder_encode(encoder, &nal, &nal_count, &picture_in, &picture_out); if (ret < 0) { fprintf(stderr, "x264_encoder_encode error\n"); break; } /* 输出编码数据 */ for (i = 0; i < nal_count; i++) { fwrite(nal[i].p_payload, 1, nal[i].i_payload, stdout); } } /* 清理资源并退出程序 */ x264_encoder_close(encoder); free(yuyv); free(buf); return 0; } ``` 这个程序使用 x264实现了将 YUYV 格式的视频数据编码成 H.264 格式。它从标准输入中读取 YUYV 格式的视频数据,并将编码输出写入标准输出。该程序只是一个简单的示例,实际应用中还需要考虑错误处理、压缩效率等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌上花开缓缓归以

你的鼓励将是我创作的最大动力,

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值