`
java-mans
  • 浏览: 11414108 次
文章分类
社区版块
存档分类
最新评论

T264接口说明

 
阅读更多
T264 简介
H.264 是 MPEG-4 标准所定义的最新格式,同时也是技术含量最高、代表最新技术水平的视频编码格式之一,有的也称(AVC)。而 T264 是 H264 的一个开源实现,其他的开源实现还有 x264(只有编码部分)和 ffmpeg等。T264 为国内开发团队开发,它解决了在尽可能低的存储空间内,获得好的图像质量,这样也减少了图像在网络传输中所占用的带宽。
T264性能测评
T264是国内的开源项目,T264 decoder的程序做过汇编优化,速度还可以,但只能解 T264 本身的码流。开发团队对 T264 decoder v0.14 做了修改,只车 baseline 的解码。与本身不带解码器的 x264 相比,T264 更有可有行。
T264 基本数据结构
o T264_param_t 代表编码器所采用的参数,比如图片帧宽度高度、要用怎么样的压缩率等等。
o T264_t 表示编码器和解码器的一个实例。
o T264_frame_t 解码器解码出每一帧视频后都会储存到这个数据结构里。
o decoder_state_t 解码器状态。
o 每个数据结构里面的成员这里不详细说,之后遇到会有解释。
1. /* In Linux, you Should include this
2. * head file, or the compilor will report
3. * errors! I don't know why yet. */
4. #include <netinet/in.h>
5.
6. /* Head file for T264 */
7. #include "<DIR>/avc/common/T264.h"
8.
9. T264_param_t /* Store the parameters for encoder, sorts like
10.* how wide and how high a frame is, what quality
11.* do you expect, and how fast the encoder should be.
12.* You have to make a tradeoff between speed and quality,
13.* and maybe storage size. */
14.
15.T264_t /* An instance for encoder or decoder */
16.
17.T264_frame_t /* When decoder product a frame, store in this struct.
18.* Members of Y[0], U, V point to the components of YUV
19.* respectly. */
20.
21.decoder_state_t /* Represent the state of a decoder, maybe one of the
22.* following values:
23.* DEC_STATE_BUFFER: need more date
24.DEC_STATE_OK:
25.DEC_STATE_SEQ:
26.DEC_STATE_PIC:
27.DEC_STATE_SLICE: a frame have be deoded
28.DEC_STATE_CUSTOM_SET: the end or restart
29.DEC_STATE_UNKOWN: unknown
30.*/
/* In Linux, you Should include this
* head file, or the compilor will report
* errors! I don't know why yet. */
#include <netinet/in.h>
/* Head file for T264 */
#include "<DIR>/avc/common/T264.h"
T264_param_t /* Store the parameters for encoder, sorts like
* how wide and how high a frame is, what quality
* do you expect, and how fast the encoder should be.
* You have to make a tradeoff between speed and quality,
* and maybe storage size. */
T264_t /* An instance for encoder or decoder */
T264_frame_t /* When decoder product a frame, store in this struct.
* Members of Y[0], U, V point to the components of YUV
* respectly. */
decoder_state_t /* Represent the state of a decoder, maybe one of the
* following values:
* DEC_STATE_BUFFER: need more date
DEC_STATE_OK:
DEC_STATE_SEQ:
DEC_STATE_PIC:
DEC_STATE_SLICE: a frame have be deoded
DEC_STATE_CUSTOM_SET: the end or restart
DEC_STATE_UNKOWN: unknown
*/
T264 基本函数接口
o T264_t *T264_open(&param) 根据param 参数配置,打开并初始化一个编码器实例,返回编码器实例指针,可以当成句柄理解。
o uint8_t *T264_malloc(size, CACHE_SIZE),分配内存,大小为 size,返回内存区指针。
1. /**
2. * This function is used to open and initialize an
3. * encoder with parameter para. Return a pointer
4. * to the encoder instance, like a handle.
5. * @para: pointer to T264_param_t, represent parameters.
6. * @T264_t: return pointer to T264_t, an instance of
7. * encoder, will be used late, like a handle.
8. */
9. T264_t *T264_open(T264_param_t *para);
10.
11./**
12.* This function explicitly close an encoder, release
13.* system resouces.
14.* @t: pointer to the encoder you want to close.
15.* Note: I suggest here we should use T264_t **t as parameter,
16.* since the developers can set the pointer to NULL for the user
17.* programmer. Otherwise, the programmer should do it all by themself.
18.* To release something, don't forget to set the corresponding pointer
19.* to NULL, avoiding potential errors.
20.*/
21.void T264_close(T264_t* t);
22.
23./**
24.* This function encoder a frame.
25.* @t: pointer to encoder you have just open.
26.* @src: the frame you want to encode.
27.* @dst: The result will be put in this buffer.
28.* @dst_size: size of the dst buffer.
29.* @return: the length of frame after encoded.
30.*/
31.int32_t T264_encode(T264_t* t, uint8_t* src, uint8_t* dst, int32_t dst_size);
32.
33./**
34.* Open and initialize a decoder for use.
35.* @return: pointer to the decoder created.
36.* This pointer will be use late.
37.*/
38.T264_t *T264dec_open();
39.
40./**
41.* Close a decoder and release corresponding resources.
42.* @t: pointer to the decoder you want to close.
43.*/
44.void T264dec_close(T264_t *t);
45.
46./**
47.* Give the data to the decoder to decode, when the decoder
48.* need more data.
49.* @t: pointer to the decoder.
50.* @buf: pointer to the data you want to send to the decoder.
51.* @len: length of data store in buf.
52.*/
53.void T264dec_buffer(T264_t *t, uint8_t *buf, int32_t len);
54.
55./**
56.* Return the state of the decoder.
57.* @t: pointer to a decoder, which decoder you want to know.
58.* @return: the state of the decoder pointed by t.
59.*/
60.decoder_state_t T264dec_parse(T264_t *t);
61.
62./**
63.* Get a decoded frame when the decoder is ready to give.
64.* @t: pointer to the decoder.
65.* @return: pointer to the frame produced by the decoder.
66.*/
67.T264_frame_t *T264dec_flush_frame(T264_t *t);
/**
* This function is used to open and initialize an
* encoder with parameter para. Return a pointer
* to the encoder instance, like a handle.
* @para: pointer to T264_param_t, represent parameters.
* @T264_t: return pointer to T264_t, an instance of
* encoder, will be used late, like a handle.
*/
T264_t *T264_open(T264_param_t *para);
/**
* This function explicitly close an encoder, release
* system resouces.
* @t: pointer to the encoder you want to close.
* Note: I suggest here we should use T264_t **t as parameter,
* since the developers can set the pointer to NULL for the user
* programmer. Otherwise, the programmer should do it all by themself.
* To release something, don't forget to set the corresponding pointer
* to NULL, avoiding potential errors.
*/
void T264_close(T264_t* t);
/**
* This function encoder a frame.
* @t: pointer to encoder you have just open.
* @src: the frame you want to encode.
* @dst: The result will be put in this buffer.
* @dst_size: size of the dst buffer.
* @return: the length of frame after encoded.
*/
int32_t T264_encode(T264_t* t, uint8_t* src, uint8_t* dst, int32_t dst_size);
/**
* Open and initialize a decoder for use.
* @return: pointer to the decoder created.
* This pointer will be use late.
*/
T264_t *T264dec_open();
/**
* Close a decoder and release corresponding resources.
* @t: pointer to the decoder you want to close.
*/
void T264dec_close(T264_t *t);
/**
* Give the data to the decoder to decode, when the decoder
* need more data.
* @t: pointer to the decoder.
* @buf: pointer to the data you want to send to the decoder.
* @len: length of data store in buf.
*/
void T264dec_buffer(T264_t *t, uint8_t *buf, int32_t len);
/**
* Return the state of the decoder.
* @t: pointer to a decoder, which decoder you want to know.
* @return: the state of the decoder pointed by t.
*/
decoder_state_t T264dec_parse(T264_t *t);
/**
* Get a decoded frame when the decoder is ready to give.
* @t: pointer to the decoder.
* @return: pointer to the frame produced by the decoder.
*/
T264_frame_t *T264dec_flush_frame(T264_t *t);
编码过程
1. 创建一个 T264_param_t
2. 设置 T264_param_t 中的相关参数
3. 打开编码器
4. 分配 buffer 内存空间
5. 读一帧视频
6. 用 T264_encode 编码一帧视频,结果存放在一个 buffer 里面
7. 处理结果,可以是写入文件,或者发送到网络
8. 编码结束后释放 buffer 并关闭编码器
1. void encode()
2. {
3. /* No.1 Create param */
4. T264_param_t param;
5. T264_t* t;
6. uint8_t* buf, *dst;
7. int32_t size;
8.
9. /* No.2 Init param */
10.init_param(&param, paramfile); /* This function is in T264.c, reading info
11.* from a configure file and set the param. */
12.param.direct_flag = 1;
13.
14./* No.3 Open encoder */
15.t = T264_open(&param);
16.
17./* No.4 alloc memory for buffers */
18./* Since input data is YUV420, so size is: */
19.size = param.height * param.width + (param.height * param.width >> 1);
20.buf = T264_malloc(size, CACHE_SIZE);
21.dst = T264_malloc(size, CACHE_SIZE);
22.
23.while(1) {
24./* No.5 Read a frame */
25.if(read(buf, size, ...) == 0)
26.break; // No more frame now
27.
28./* No.6 Encode! Result store in dst, return result length */
29.len = T264_encode(t, buf, dst, size);
30.
31./* No.7 Process the encoded frame */
32.process(dst, size); /* write to a file, or send to the network, or... */
33.}
34.
35./* No.8 release buffers and close encoder */
36.T264_free(buf);
37.T264_free(dst);
38.T264_close(t);
39.}
void encode()
{
/* No.1 Create param */
T264_param_t param;
T264_t* t;
uint8_t* buf, *dst;
int32_t size;
/* No.2 Init param */
init_param(&param, paramfile); /* This function is in T264.c, reading info
* from a configure file and set the param. */
param.direct_flag = 1;
/* No.3 Open encoder */
t = T264_open(&param);
/* No.4 alloc memory for buffers */
/* Since input data is YUV420, so size is: */
size = param.height * param.width + (param.height * param.width >> 1);
buf = T264_malloc(size, CACHE_SIZE);
dst = T264_malloc(size, CACHE_SIZE);
while(1) {
/* No.5 Read a frame */
if(read(buf, size, ...) == 0)
break; // No more frame now
/* No.6 Encode! Result store in dst, return result length */
len = T264_encode(t, buf, dst, size);
/* No.7 Process the encoded frame */
process(dst, size); /* write to a file, or send to the network, or... */
}
/* No.8 release buffers and close encoder */
T264_free(buf);
T264_free(dst);
T264_close(t);
}
解码过程
1. 打开解码器
2. 获取解码器当前状态
3. 如果需要更多数据,则读更多数据并给传进解码器
4. 如果当前有一帧视频解压好,则处理这帧视频
5. 如果... 一般就是上面两种状态,其他的还有待深入理解,一般用不上
6. 处理完成之后就关闭解码器
注意:这里在最开始的时候,解码器状态是需要更多数据的,这时,应该传数据给它,并且必须是一个关键帧!因为解码器需要关键帧做参考,也就是说,在编码的时候,每个一定数目的视频帧就会有一帧比较大的关键帧,其他非关键帧参考关键帧的内容。如果最开始的时候传给解码器的视频帧不是关键帧,可预料的:应该是解不起来的,没有关键帧可以参考!而且解码器还会异常退出!
1. void decode()
2. {
3. size_t size;
4. uint8_t buffer[BUFFER_SIZE + 4];
5.
6. /* No.1 Open decoder */
7. T264_t* t = T264dec_open();
8. while (run)
9. {
10./* No.2 Query state of the decoder */
11.decoder_state_t state = T264dec_parse(t);
12.switch(state)
13.{
14./* No.3 The decoder needy more data */
15.case DEC_STATE_BUFFER:
16./* Read more data */
17.size = read(buffer, 1, BUFFER_SIZE, somewhere);
18./* Deliver to the decoder */
19.T264dec_buffer(t, buffer, size);
20.
21.case DEC_STATE_PIC:
22./* write one pic */
23.break;
24.
25.case DEC_STATE_SEQ:
26.break;
27.
28./* No.4 If another frame has been decoded */
29.case DEC_STATE_SLICE:
30./* Get the frame */
31.frame = T264dec_flush_frame(t);
32.
33./* The frame is of YUV420, we process
34.* the YUV components respectly.
35.*/
36./* Y */
37.temp = buffer;
38.p = frame->Y[0];
39.for(i = 0 ; i < t->height ; i ++)
40.{
41.memcpy(temp, p, t->width);
42.temp += t->width;
43.p += t->edged_stride;
44.}
45.
46./* U */
47.p = frame->U;
48.for(i = 0 ; i < t->height >> 1 ; i ++)
49.{
50.memcpy(temp, p, t->width >> 1);
51.temp += t->width >> 1;
52.p += t->edged_stride_uv;
53.}
54.
55./* V */
56.p = frame->V;
57.for(i = 0 ; i < t->height >> 1 ; i ++)
58.{
59.memcpy(temp, p, t->width >> 1);
60.temp += t->width >> 1;
61.p += t->edged_stride_uv;
62.}
63./* Now the frame is put in buffer, of YUV420 */
64./* Then you can process this frame: maybe just display */
65.break;
66.
67.case DEC_STATE_CUSTOM_SET:
68.break;
69.default:
70.break;
71.}
72.}
73.
74./* No.6 Close the decoder */
75.T264dec_close(t);
76.}
void decode()
{
size_t size;
uint8_t buffer[BUFFER_SIZE + 4];
/* No.1 Open decoder */
T264_t* t = T264dec_open();
while (run)
{
/* No.2 Query state of the decoder */
decoder_state_t state = T264dec_parse(t);
switch(state)
{
/* No.3 The decoder needy more data */
case DEC_STATE_BUFFER:
/* Read more data */
size = read(buffer, 1, BUFFER_SIZE, somewhere);
/* Deliver to the decoder */
T264dec_buffer(t, buffer, size);
case DEC_STATE_PIC:
/* write one pic */
break;
case DEC_STATE_SEQ:
break;
/* No.4 If another frame has been decoded */
case DEC_STATE_SLICE:
/* Get the frame */
frame = T264dec_flush_frame(t);
/* The frame is of YUV420, we process
* the YUV components respectly.
*/
/* Y */
temp = buffer;
p = frame->Y[0];
for(i = 0 ; i < t->height ; i ++)
{
memcpy(temp, p, t->width);
temp += t->width;
p += t->edged_stride;
}
/* U */
p = frame->U;
for(i = 0 ; i < t->height >> 1 ; i ++)
{
memcpy(temp, p, t->width >> 1);
temp += t->width >> 1;
p += t->edged_stride_uv;
}
/* V */
p = frame->V;
for(i = 0 ; i < t->height >> 1 ; i ++)
{
memcpy(temp, p, t->width >> 1);
temp += t->width >> 1;
p += t->edged_stride_uv;
}
/* Now the frame is put in buffer, of YUV420 */
/* Then you can process this frame: maybe just display */
break;
case DEC_STATE_CUSTOM_SET:
break;
default:
break;
}
}
/* No.6 Close the decoder */
T264dec_close(t);
}
更详细的接口和编解码流程请参考 t264 源码中 T264.c 文件,这是个例子程序,相当于一个 API 说明文档,当然没有文档那么好懂,注释不多,所以多看几遍咯!
上述为本人看代码 T264.c 的一点理解,不尽准确,仅供参考。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics