看此文章之前,建议先看一看:https://blog.youkuaiyun.com/weixin_42462202/article/details/88182605
使用ffmpeg读取H264并不能直接得到NALU单元,必须从读取出来的AVPacket与AVFormatContext->streams[video_index]->codec->extradata提取出来。
输出H.264格式,我们需要将NALU提取出来,然后组织成下面的数据结构。
提取流程
1、打开MP4文件,循环读取
2、从AVPacket获取IDR(nalu type==5),从AVFormatContext->streams[video_index]->codec->extradata获取SPS与PPS。
3、添加start code,给SPS与PPS前加上00 00 00 01,IDR加上00 00 01
4、按照上图的数据结构写入文件中
5、继续提取NALU,添加start code(00 00 01),写入文件中
几个注意的点
1、SPS与PPS存在于AVFormatContext->streams[video_index]->codec->extradata
2、其他的NALU存在于读取出来的AVPacket中
3、AVPacket->data前四个字节表示当前NALU的大小,根据这一条件可以获取NALU
4、AVFormatContext->streams[video_index]->codec->extradata + 5,之后两个字节表示SPS的个数,
SPS的数据结束后的两个字节表示PPS的个数
源码
#include <stdio.h>
#include <libavutil/log.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
/* 获取SPS与PPS */
static int h264_extradata_to_annexb(const unsigned char *pCodecExtraData, const int codecExtraDataSize,
AVPacket *pOutExtradata, int padding)
{
const unsigned char *pExtraData = NULL; /* 前四个字节没用 */
int len = 0;
int spsUnitNum, ppsUnitNum;
int unitSize, totolSize = 0;
unsigned char startCode[] = {0, 0, 0, 1};
unsigned char *pOut = NULL;
int err;
pExtraData = pCodecExtraData+4;
len