在x264.dsw工程中,找了一下,找到点相关的东西。
另外,x264.exe在编码文件时,只有一个地方进行文件的写入,就是
int write_nalu_bsf( hnd_t handle, uint8_t *p_nalu, int i_size )
{
if (fwrite(p_nalu, i_size, 1, (FILE *)handle) > 0)
{
return i_size;
}
return -1;
}
如果把函数里的代码注释掉,会发现,虽然在不停的编码,但最终文件大小始终为0,从这一点可以证明只有此处进行文件的写入操作。
那么,序列参数集是哪里来的呢,又找到一部分东西,在encoder.c文件的函数:
int x264_encoder_encode( x264_t *h,/* 指定编码器 */
x264_nal_t **pp_nal, /* x264_nal_t * */
int *pi_nal,
/* int */
x264_picture_t *pic_in,
x264_picture_t *pic_out )
中,有如下代码:
/* Write SPS and PPS 写序列参数集、图像参数集以及SEI版本信息,并不是写入文件,而是写入输出缓冲区 最后通过p_write_nalu中的fwrite写入到文件*/
if( i_nal_type == NAL_SLICE_IDR && h->param.b_repeat_headers )
{
printf("encoder.c : Write SPS and PPS");
system("pause");//暂停,任意键继续
if( h->fenc->i_frame == 0 )
{
/* identify ourself */
x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
x264_sei_version_write( h, &h->out.bs );
x264_nal_end( h );
}
/* generate sequence parameters */
x264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST );
x264_sps_write( &h->out.bs, h->sps );
x264_nal_end( h );
/* generate picture parameters */
x264_nal_start( h, NAL_PPS, NAL_PRIORITY_HIGHEST );
x264_pps_write( &h->out.bs, h->pps );
x264_nal_end( h );
}
/* Write frame 写入帧,并不是写入文件,而是写入输出缓冲区*/
i_frame_size = x264_slices_write( h );
在图一中,看到有一个网址http://www.videolan.org,在源码中搜索这个网址,找到唯一的一处,也就是如下的函数:
void x264_sei_version_write( x264_t *h, bs_t *s )
{
int i;
// random ID number generated according to ISO-11578
const uint8_t uuid[16] = {
0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7,
0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef
};
char version[1200];
int length;
char *opts = x264_param2string( &h->param, 0 );
sprintf( version, "x264 - core %d%s - H.264/MPEG-4 AVC codec - "
"
Copyleft 2005 - http://www.videolan.org/x264.html - options: %s",
X264_BUILD, X264_VERSION, opts );
x264_free( opts );
length = strlen(version)+1+16;
bs_write( s, 8, 0x5 ); // payload_type = user_data_unregistered
// payload_size
for( i = 0; i <= length-255; i += 255 )
bs_write( s, 8, 255 );
bs_write( s, 8, length-i );
for( i = 0; i < 16; i++ )
bs_write( s, 8, uuid[i] );
for( i = 0; i < length-16; i++ )
bs_write( s, 8, version[i] );
bs_rbsp_trailing( s );
}
猜想:
如果是实时的话,可以模仿下面的这两句代码发送序列参数集和图像参数集:
x264_sps_write( &h->out.bs, h->sps );
x264_pps_write( &h->out.bs, h->pps );
实际就是要发送h->sps和h->pps
因为我编码的文件是可以播放的,所以实际已经产生了sps和pps,直接发送就行了。