x264的编码示例

/**
 * @note x264的编码示例.
 * 使用x264的版本为libx264-115
 * 1. 示例是个死循环,会源源不断的编码,然后将数据写文件.
 * 2. 示例的行为是:编码1000帧后,取空编码缓冲区,然后循环执行这两步.

 * @author 

*gcc  -lx264

 **/
#include <cassert>
#include <iostream>
#include <string>
#include "stdint.h"
#include <string.h>
#include <stdio.h>
extern "C" {
#include "x264.h"
}
;
unsigned int g_uiPTSFactor = 0;
int iNal = 0;
x264_nal_t* pNals = NULL;
int encode(x264_t* p264, x264_picture_t* pIn, x264_picture_t* pOut);
int main(int argc, char** argv) {
int iResult = 0;
x264_t* pX264Handle = NULL;


x264_param_t* pX264Param = new x264_param_t;
assert(pX264Param);
//* 配置参数
//* 使用默认参数
x264_param_default(pX264Param);
//* cpuFlags
pX264Param->i_threads = X264_SYNC_LOOKAHEAD_AUTO; //* 取空缓冲区继续使用不死锁的保证.
//* video Properties
pX264Param->i_width = 320; //* 宽度.
pX264Param->i_height = 240; //* 高度
pX264Param->i_frame_total = 0; //* 编码总帧数.不知道用0.
pX264Param->i_keyint_max = 10;
//* bitstream parameters
pX264Param->i_bframe = 5;
pX264Param->b_open_gop = 0;
pX264Param->i_bframe_pyramid = 0;
pX264Param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;


//* 宽高比,有效果,但不是想要的.
//pX264Param->vui.i_sar_width = 1080;
//pX264Param->vui.i_sar_height = 720;


//* Log
pX264Param->i_log_level = X264_LOG_DEBUG;
//* Rate control Parameters
pX264Param->rc.i_bitrate = 1024 * 10; //* 码率(比特率,单位Kbps)
//* muxing parameters
pX264Param->i_fps_den = 1; //* 帧率分母
pX264Param->i_fps_num = 25; //* 帧率分子
pX264Param->i_timebase_den = pX264Param->i_fps_num;
pX264Param->i_timebase_num = pX264Param->i_fps_den;


//* 设置Profile.使用MainProfile
x264_param_apply_profile(pX264Param, x264_profile_names[1]);


//* 打开编码器句柄,通过x264_encoder_parameters得到设置给X264
//* 的参数.通过x264_encoder_reconfig更新X264的参数
pX264Handle = x264_encoder_open(pX264Param);
assert(pX264Handle);


//* 获取整个流的PPS和SPS,不需要可以不调用.
iResult = x264_encoder_headers(pX264Handle, &pNals, &iNal);
assert(iResult >= 0);
//* PPS SPS 总共只有36B,如何解析出来呢?
for (int i = 0; i < iNal; ++i) {
switch (pNals[i].i_type) {
case NAL_SPS:
break;
case NAL_PPS:
break;
default:
break;
}
}


//* 获取允许缓存的最大帧数.
int iMaxFrames = x264_encoder_maximum_delayed_frames(pX264Handle);


//* 编码需要的参数.
iNal = 0;
pNals = NULL;
x264_picture_t* pPicIn = new x264_picture_t;
x264_picture_t* pPicOut = new x264_picture_t;


x264_picture_init(pPicOut);
x264_picture_alloc(pPicIn, X264_CSP_I420, pX264Param->i_width,
pX264Param->i_height);
pPicIn->img.i_csp = X264_CSP_I420;
pPicIn->img.i_plane = 3;


//* 创建文件,用于存储编码数据
FILE* pFile = fopen("agnt.264", "wb");
assert(pFile);


//* 示例用编码数据.
int iDataLen = pX264Param->i_width * pX264Param->i_height;
uint8_t* data = new uint8_t[iDataLen];


unsigned int uiComponent = 0;
while (++uiComponent) {
//* 构建需要编码的源数据(YUV420色彩格式)
memset(data, uiComponent, iDataLen);
memcpy(pPicIn->img.plane[0], data, iDataLen);
memcpy(pPicIn->img.plane[1], data, iDataLen / 4);
memcpy(pPicIn->img.plane[2], data, iDataLen / 4);


if (uiComponent <= 1000) {
pPicIn->i_pts = uiComponent + g_uiPTSFactor * 1000;
encode(pX264Handle, pPicIn, pPicOut);
} else {
//* 将缓存的数据取出
int iResult = encode(pX264Handle, NULL, pPicOut);
if (0 == iResult) {
//break; //* 取空,跳出
uiComponent = 0;
++g_uiPTSFactor;


/* {{ 这个解决不了取空缓冲区,再压缩无B帧的问题
x264_encoder_reconfig(pX264Handle, pX264Param);
x264_encoder_intra_refresh(pX264Handle);
//* }} */
}
}


//* 将编码数据写入文件.
for (int i = 0; i < iNal; ++i) {
fwrite(pNals[i].p_payload, 1, pNals[i].i_payload, pFile);
}
}
//* 清除图像区域
x264_picture_clean(pPicIn);
x264_picture_clean(pPicOut);
//* 关闭编码器句柄
x264_encoder_close(pX264Handle);
pX264Handle = NULL;


delete pPicIn;
pPicIn = NULL;


delete pPicOut;
pPicOut = NULL;


delete pX264Param;
pX264Param = NULL;


delete[] data;
data = NULL;
return 0;
}


int encode(x264_t* pX264Handle, x264_picture_t* pPicIn,
x264_picture_t* pPicOut) {


int iResult = 0;
iResult = x264_encoder_encode(pX264Handle, &pNals, &iNal, pPicIn, pPicOut);
if (0 == iResult) {
std::cout << "编码成功,但被缓存了." << std::endl;
} else if (iResult < 0) {
std::cout << "编码出错" << std::endl;
} else if (iResult > 0) {
std::cout << "得到编码数据" << std::endl;
}


/* {{ 作用不明
unsigned char* pNal = NULL;
for (int i = 0;i < iNal; ++i)
{
int iData = 1024 * 32;
x264_nal_encode(pX264Handle, pNal,&pNals[i]);
}
//* }} */


//* 获取X264中缓冲帧数.
int iFrames = x264_encoder_delayed_frames(pX264Handle);
std::cout << "当前编码器中缓存数据:" << iFrames << "帧\n";
return iFrames;
}

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Base64编码是一种针对字节的编码,它将字节流转换为一种可以传输的字符串格式。例如,将字节流"Hello World"转换为Base64编码的字符串形式可以为"SGVsbG8gV29ybGQ="。 ### 回答2: Base64是一种将二进制数据编码为ASCII字符的编码方式。它通常用于在网络传输中将二进制数据以文本形式进行传输和存储。 在C语言中,我们可以使用标准库中的函数实现Base64编码示例。下面是一个使用C语言实现Base64编码的简单示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> const char base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char *base64_encode(const unsigned char *data, int size) { int i, j; int encode_size = 4 * ((size + 2) / 3); char *encoded_data = malloc(encode_size + 1); if (encoded_data == NULL) { return NULL; } for (i = 0, j = 0; i < size; i += 3, j += 4) { unsigned char a = i < size ? data[i] : 0; unsigned char b = i + 1 < size ? data[i + 1] : 0; unsigned char c = i + 2 < size ? data[i + 2] : 0; encoded_data[j] = base64_table[a >> 2]; encoded_data[j + 1] = base64_table[((a & 0x03) << 4) | (b >> 4)]; encoded_data[j + 2] = (i + 1 < size) ? base64_table[((b & 0x0f) << 2) | (c >> 6)] : '='; encoded_data[j + 3] = (i + 2 < size) ? base64_table[c & 0x3f] : '='; } encoded_data[encode_size] = '\0'; return encoded_data; } int main() { unsigned char data[] = "Hello, World!"; int size = strlen((char*)data); char *encoded_data = base64_encode(data, size); if (encoded_data == NULL) { printf("Base64 encoding failed. No memory available.\n"); return 1; } printf("Base64 encoded data: %s\n", encoded_data); free(encoded_data); return 0; } ``` 在上述代码中,我们定义了一个`base64_table`字符数组,用于映射二进制数据到Base64编码字符。然后,我们定义了一个`base64_encode()`函数,该函数接收需要编码的数据和数据尺寸作为输入,并返回编码后的数据。 在`main()`函数中,我们定义了一个示例数据`data`,并调用`base64_encode()`函数对其进行编码。然后,我们打印出编码后的数据。 请注意,上述代码只是一个简单的Base64编码示例,并不包括对边界情况的处理和错误检查。实际使用中,可能需要进行更多的错误处理和边界条件检查。 ### 回答3: Base64编码是一种将二进制数据转换为可打印字符的编码方式。它将3个字节的二进制数据编码为4个可打印字符,以实现数据在传输过程中的可读性和可靠性。 要实现Base64编码,我们需要按照以下步骤进行操作: 1. 准备Base64编码表:将A~Z、a~z、0~9这62个字符和"+"、"/"两个字符组成一个长度为64的字符数组。在实际编码中,有些情况下会使用"="字符来填充不足4字节的情况。 2. 将需要编码的数据分割成每3个字节一组。如果数据不足3个字节,需要进行填充至3个字节。 3. 将每组3个字节的二进制数据转换成4个Base64字符的编码。 4. 如果有填充字符,则将对应的填充字符添加到编码结果中。 下面是一个Base64编码示例: 假设我们需要编码的数据是"Hello, World!"。 1. 将字符串转换成对应的字节数组:[72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]。 2. 将字节数组分组:[72, 101, 108]、[108, 111, 44]、[32, 87, 111]、[114, 108, 100]、[33]。 3. 将每组3个字节的二进制数据转换成4个Base64字符的编码: 第一组:01101000 01100101 01101100 -> 011010 000110 010101 101100 -> i Wxu 第二组:01101100 01101111 00101100 -> 011011 000110 111100 101100 -> bGVv 第三组:00100000 01010111 01101111 -> 001000 000101 011110 110000 -> IAXj 第四组:01110010 01101100 01100100 -> 011100 100110 110100 010000 -> chrS 第五组:00100001 00000000 00000000 -> 001000 010000 000000 000000 -> IAAAAAAAAA 编码结果为:iWxubGVvIAXjchrSIAAAAAAAAA== 通过以上步骤,我们成功地将数据"Hello, World!"进行了Base64编码

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值