天天看點

nginx_rtmp中解析sps和pps

  • 摘要:一首先這裡要啰嗦一下,為什麼要提取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;

繼續閱讀