- 摘要:一首先這裡要啰嗦一下,為什麼要提取sps和ppssps主要包含了視訊的分辨率和profile類型資訊。pps是什麼暫時沒有關注。二在nginx-rtmp中,如何提取到sps和pps資訊呢?直接找到nginx_rtmp循環主幹。ngx_rtmp_live_av(ngx_rtmp_session_t*s,ngx_rtmp_header_t*h, ngx_chain_t*in)
-
一 首先這裡要啰嗦一下,為什麼要提取sps和pps
sps 主要包含了視訊的分辨率和profile類型資訊。pps是什麼暫時沒有關注。
二 在nginx-rtmp中,如何提取到sps和pps資訊呢?
直接找到nginx_rtmp循環主幹。
ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
ngx_chain_t *in)(1) 擷取到codec ctx
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
codec_ctx->aac_header;//音頻codec header
codec_ctx->avc_header;//視訊codec header
(2) 合并avc(h264)buf
ngx_chain_t *in = NULL;
for(in = avc_header;in;in = in->next)
{
memcpy(tmp_str.data + in_len,in->buf->pos,(int)(in->buf->last - in->buf->pos));
in_len += (int)(in->buf->last - in->buf->pos);
}
//buf 有4個指針,pos,last,start,end。end-start表示buf的容量,
last-pos表示buf資料量
(3) 解析sps和pps
從avc_header中提取到的buf資料符合rtmp message協定标準(即flv檔案格式标準)
下面附上解析代碼和注釋:int parse_offset = 0;
int frametype = avc_header->data[parse_offset]&;0xff>>4;//4 bit幀格式
int codec_id = avc_header->data[parse_offset]&;0x0f;//編碼器id 7 AVC
parse_offset ++;
int packet_type = avc_header->data[parse_offset]&;0xff;//資料包類型 0 sequence head(codec head) 1 nalu u
parse_offset ++;
parse_offset += 3;//3 位元組時間戳
parser_AVCDecoderHeader *sps_header = (parser_AVCDecoderHeader *)(avc_header->data + parse_offset);
//parser_AVCDecoderHeader_DUMP(sps_header);
parse_offset += sizeof(parser_AVCDecoderHeader);//sps 解碼頭資訊
int sps_len = ntohs(*(unsigned short *)((char *)avc_header->data + parse_offset));//sps長度
parse_offset += 2;
memcpy(sps->data,nalu_head,4);//在sps前面加上0x00000001
sps->len += 4;
memcpy(sps->data + sps->len,avc_header->data + parse_offset,sps_len);//把sps資料串到後面
sps->len += sps_len;
parse_offset += sps_len;int ppscount = ((char*)avc_header->data)[parse_offset];//pps 個數
parse_offset ++;
int pps_len = ntohs(*(unsigned short *)((char *)avc_header->data + parse_offset));//pps 長度
parse_offset += 2;
memcpy(pps->data,nalu_head,4);//在pps前面加上0x00000001
pps->len += 4;
memcpy(pps->data + pps->len,avc_header->data + parse_offset,pps_len);//把pps資料串到後面
pps->len += pps_len;