【T264 简介】
T264 简介
H.264 是 MPEG-4 标准所定义的最新格式,同时也是技术含量最高、代表最新技术水平的视频编码格式之一,有的也称(AVC)。而 T264 是 H264 的一个开源实现,其他的开源实现还有 x264(只有编码部分)和 ffmpeg等。T264 为国内开发团队开发,它解决了在尽可能低的存储空间内,获得好的图像质量,这样也减少了图像在网络传输中所占用的带宽。
H.264 是 MPEG-4 标准所定义的最新格式,同时也是技术含量最高、代表最新技术水平的视频编码格式之一,有的也称(AVC)。而 T264 是 H264 的一个开源实现,其他的开源实现还有 x264(只有编码部分)和 ffmpeg等。T264 为国内开发团队开发,它解决了在尽可能低的存储空间内,获得好的图像质量,这样也减少了图像在网络传输中所占用的带宽。
T264性能测评
T264是国内的开源项目,T264 decoder的程序做过汇编优化,速度还可以,但只能解 T264 本身的码流。开发团队对 T264 decoder v0.14 做了修改,只车 baseline 的解码。与本身不带解码器的 x264 相比,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.
4. #include <netinet/in.h>
5.
6.
7. #include "<DIR>/avc/common/T264.h"
8.
9. T264_param_t
14.
15. T264_t
16.
17. T264_frame_t
20.
21. decoder_state_t
#include <netinet/in.h>
#include "<DIR>/avc/common/T264.h"
T264_param_t
T264_t
T264_frame_t
decoder_state_t
T264 基本函数接口
o T264_t *T264_open(¶m) 根据param 参数配置,打开并初始化一个编码器实例,返回编码器实例指针,可以当成句柄理解。
o uint8_t *T264_malloc(size, CACHE_SIZE),分配内存,大小为 size,返回内存区指针。
1.
9. T264_t *T264_open(T264_param_t *para);
10.
11.
21.
void T264_close(T264_t* t);
22.
23.
31. int32_t T264_encode(T264_t* t, uint8_t* src, uint8_t* dst, int32_t dst_size);
32.
33.
38. T264_t *T264dec_open();
39.
40.
44.
void T264dec_close(T264_t *t);
45.
46.
53.
void T264dec_buffer(T264_t *t, uint8_t *buf, int32_t len);
54.
55.
60. decoder_state_t T264dec_parse(T264_t *t);
61.
62.
67. T264_frame_t *T264dec_flush_frame(T264_t *t);
T264_t *T264_open(T264_param_t *para);
void T264_close(T264_t* t);
int32_t T264_encode(T264_t* t, uint8_t* src, uint8_t* dst, int32_t dst_size);
T264_t *T264dec_open();
void T264dec_close(T264_t *t);
void T264dec_buffer(T264_t *t, uint8_t *buf, int32_t len);
decoder_state_t T264dec_parse(T264_t *t);
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. 创建一个 T264_param_t
2. 设置 T264_param_t 中的相关参数
3. 打开编码器
4. 分配 buffer 内存空间
5. 读一帧视频
6. 用 T264_encode 编码一帧视频,结果存放在一个 buffer 里面
7. 处理结果,可以是写入文件,或者发送到网络
8. 编码结束后释放 buffer 并关闭编码器
1.
void encode()
2. {
3.
4. T264_param_t param;
5. T264_t* t;
6. uint8_t* buf, *dst;
7. int32_t size;
8.
9.
10. init_param(¶m, paramfile);
12. param.direct_flag = 1;
13.
14.
15. t = T264_open(¶m);
16.
17.
18.
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.
25.
if(read(buf, size, ...) == 0)
26.
break; // No more frame now
27.
28.
29. len = T264_encode(t, buf, dst, size);
30.
31.
32. process(dst, size);
33. }
34.
35.
36. T264_free(buf);
37. T264_free(dst);
38. T264_close(t);
39. }
void encode()
{
}
解码过程
1. 打开解码器
2. 获取解码器当前状态
3. 如果需要更多数据,则读更多数据并给传进解码器
4. 如果当前有一帧视频解压好,则处理这帧视频
5. 如果... 一般就是上面两种状态,其他的还有待深入理解,一般用不上
6. 处理完成之后就关闭解码器
注意:这里在最开始的时候,解码器状态是需要更多数据的,这时,应该传数据给它,并且必须是一个关键帧!因为解码器需要关键帧做参考,也就是说,在编码的时候,每个一定数目的视频帧就会有一帧比较大的关键帧,其他非关键帧参考关键帧的内容。如果最开始的时候传给解码器的视频帧不是关键帧,可预料的:应该是解不起来的,没有关键帧可以参考!而且解码器还会异常退出!
1. 打开解码器
2. 获取解码器当前状态
3. 如果需要更多数据,则读更多数据并给传进解码器
4. 如果当前有一帧视频解压好,则处理这帧视频
5. 如果... 一般就是上面两种状态,其他的还有待深入理解,一般用不上
6. 处理完成之后就关闭解码器
注意:这里在最开始的时候,解码器状态是需要更多数据的,这时,应该传数据给它,并且必须是一个关键帧!因为解码器需要关键帧做参考,也就是说,在编码的时候,每个一定数目的视频帧就会有一帧比较大的关键帧,其他非关键帧参考关键帧的内容。如果最开始的时候传给解码器的视频帧不是关键帧,可预料的:应该是解不起来的,没有关键帧可以参考!而且解码器还会异常退出!
1.
void decode()
2. {
3.
size_t size;
4. uint8_t buffer[BUFFER_SIZE + 4];
5.
6.
7. T264_t* t = T264dec_open();
8.
while (run)
9. {
10.
11. decoder_state_t state = T264dec_parse(t);
12.
switch(state)
13. {
14.
15.
case DEC_STATE_BUFFER:
16.
17. size = read(buffer, 1, BUFFER_SIZE, somewhere);
18.
19. T264dec_buffer(t, buffer, size);
20.
21.
case DEC_STATE_PIC:
22.
23.
break;
24.
25.
case DEC_STATE_SEQ:
26.
break;
27.
28.
29.
case DEC_STATE_SLICE:
30.
31. frame = T264dec_flush_frame(t);
32.
33.
36.
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.
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.
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.
64.
65.
break;
66.
67.
case DEC_STATE_CUSTOM_SET:
68.
break;
69.
default:
70.
break;
71. }
72. }
73.
74.
75. T264dec_close(t);
76. }
void decode()
{
}
更详细的接口和编解码流程请参考 t264 源码中 T264.c 文件,这是个例子程序,相当于一个 API 说明文档,当然没有文档那么好懂,注释不多,所以多看几遍咯!
上述为本人看代码 T264.c 的一点理解,不尽准确,仅供参考。
本文来源:http://blog.sina.com.cn/s/blog_9126694b01015bhw.html