vc_compress(...) 压缩, 如果成功, 得到串流
static int encode_nals (Ctx *c, x264_nal_t *nals, int nal_cnt)
{
char *pout = (char*)c->output;
c->output_datasize = 0;
for (int i = 0; i < nal_cnt; i++) {
if (c->output_datasize + nals[i].i_payload > c->output_bufsize) {
// 扩展
c->output_bufsize = (c->output_datasize+nals[i].i_payload+4095)/4096*4096;
c->output = realloc(c->output, c->output_bufsize);
}
memcpy(pout+c->output_datasize, nals[i].p_payload, nals[i].i_payload);
c->output_datasize += nals[i].i_payload;
}
return c->output_datasize;
}
int vc_compress (void *ctx, unsigned char *data[4], int stride[4], const void **out, int *len)
{
Ctx *c = (Ctx*)ctx;
// 设置 picture 数据
for (int i = 0; i < 4; i++) {
c->picture.img.plane[i] = data[i];
c->picture.img.i_stride[i] = stride[i];
}
// encode
x264_nal_t *nals;
int nal_cnt;
x264_picture_t pic_out;
c->picture.i_pts = c->get_pts(c);
#ifdef DEBUG_MORE
static int64_t _last_pts = c->picture.i_pts;
fprintf(stderr, "DBG: pts delta = %lld/n", c->picture.i_pts - _last_pts);
_last_pts = c->picture.i_pts;
#endif //
x264_picture_t *pic = &c->picture;
do {
// 这里努力消耗掉 delayed frames ???
// 实际使用 zerolatency preset 时, 效果足够好了
int rc = x264_encoder_encode(c->x264, &nals, &nal_cnt, pic, &pic_out);
if (rc < 0) return -1;
encode_nals(c, nals, nal_cnt);
} while (0);
*out = c->output;
*len = c->output_datasize;
if (nal_cnt > 0) {
c->info_valid = 1;
c->info_key_frame = pic_out.b_keyframe;
c->info_pts = pic_out.i_pts;
c->info_dts = pic_out.i_dts;
}
else {
fprintf(stderr, ".");
return 0; // 继续
}
#ifdef DEBUG_MORE
static size_t _seq = 0;
fprintf(stderr, "#%lu: [%c] frame type=%d, size=%d/n", _seq,
pic_out.b_keyframe ? '*' : '.',
pic_out.i_type, c->output_datasize);
_seq++;
#endif // debug
return 1;
}
附上源码:
main.cpp 主流程
capture.cpp, capture.h 获取 v4l2 的图像帧
vcompress.cpp vcompress.h 实现 x264 的压缩
vshow.cpp vsho.h 用 X11 显示实时图像
**************************************************************
下载在Linux公社的1号FTP服务器里,下载地址:
FTP地址:ftp://www.linuxidc.com
用户名:
密码:
在 2013年LinuxIDC.com\4月\基于V4L2的Webcam应用过程详解【附源码】
**************************************************************