在网上移植了第三方的代码,将mp4文件切片成TS + m3u8文件,在代码调试的过程中发现一个系统会挂掉的超级大BUG描述如下:
1.分配一大块内存空间,用于存储当前TS文件需要的的音视频帧数据以及描述信息,600K左右。
2.在写入video数据时没没有任何问题,但是在写入audio数据的时候却一进入就挂掉。
调试过程:
怀疑内存是不是被意外释放了,由于这套代码写的并不是很规范,变量、指针满天飞,代码的冗余度也很高,异常退出也不会将申内存释放干净,看的头都大,后来花了两天的时间去熟悉代码逻辑,修改代码,并找是否有指针指向了缓存区,然后被当做局部的缓存区释放了。后来发现并没有这样的现象,问题任然存在。
直到偶然间发现一个地方:
for(int i=0; i<n_tracks; i++)
{
/*----初始化 track_data[i] 的地址-------------------------------------------*/
if (i==0) //track_data[0]
{
output_buffer->track_data[i] = (track_data_t*)((char*)output_buffer + sizeof(media_data_t));
}
else //track_data[1]
{
output_buffer->track_data[i] = (track_data_t*)((char*)output_buffer->track_data[i-1] + sizeof(track_data_t) + (sizeof(int) * output_buffer->track_data[i-1]->n_frames) * 2 + sizeof(char) * output_buffer->track_data[i-1]->buffer_size );//*2是因为每个帧都有 size 和 offset都是四字节,两倍关系
}
。。。。。。。。。。。。省略。。。。。。。。。。。。。。。。。。。。。。
}
代码中的 track_data[i] 就是video / audio 缓存的起始位置,问题就出在初始化 track_data[1] 的时候,track_data[1] 后边的一系列偏移不管是多少,但是,这个偏移最后的地址是不是能落到 4 字节整数倍上呢????!!!!!极有可能不是落在 4 的整数倍上,试着在下边加上字节对齐的依据代码(为了不踩到前边的数据,还特意向后偏移了4 字节再进行4字节对齐):
#define ALIGNMENT_BYTES 4
for(int i=0; i<n_tracks; i++)
{
/*----初始化 track_data[i] 的地址-------------------------------------------*/
if (i==0) //track_data[0]
{
output_buffer->track_data[i] = (track_data_t*)((char*)output_buffer + sizeof(media_data_t));
}
else //track_data[1]
{
output_buffer->track_data[i] = (track_data_t*)((char*)output_buffer->track_data[i-1] + sizeof(track_data_t) + (sizeof(int) * output_buffer->track_data[i-1]->n_frames) * 2 + sizeof(char) * output_buffer->track_data[i-1]->buffer_size );//*2是因为每个帧都有 size 和 offset都是四字节,两倍关系
output_buffer->track_data[i] = (track_data_t*)(((unsigned int)output_buffer->track_data[i] + ALIGNMENT_BYTES)&(~0x3L)); //调整地址,进行4字节对齐
}
。。。。。。。。。。。。省略。。。。。。。。。。。。。。。。。。。。。。
}
最后,不再死机了,调试通过。。。。。果然是这。。。。