static int flvsrv_init_vid_h264(CODEC_VID_CTXT_T *pCtxtV, const SPSPPS_RAW_T *pSpspps) { CODEC_VID_CTXT_H264_T *pCtxtVH264 = &pCtxtV->codecCtxt.h264; H264_DECODER_CTXT_T h264Ctxt; BIT_STREAM_T h264bs; int rc; H264_INIT_BITPARSER(h264bs, pSpspps->sps, pSpspps->sps_len); memset(pCtxtVH264, 0, sizeof(CODEC_VID_CTXT_H264_T)); memset(&h264Ctxt, 0, sizeof(h264Ctxt)); if(h264_decode_NALHdr(&h264Ctxt, &h264bs, 0) <= H264_RESULT_ERR) { LOG(X_ERROR("Failed to parse rtmp video start h.264 SPS length: %d"), pSpspps->sps_len); return -1; } if((rc = avcc_create(pCtxtVH264->avccRaw, sizeof(pCtxtVH264->avccRaw), pSpspps, 4)) < 0) { LOG(X_ERROR("Failed to create video avcc start headers (sps:%d pps:%d)"), pSpspps->sps_len, pSpspps->pps_len); return -1; } pCtxtVH264->avccRawLen = rc; pCtxtV->ctxt.pstartHdrs = pCtxtVH264->avccRaw; pCtxtV->ctxt.startHdrsLen = pCtxtVH264->avccRawLen; h264_getCroppedDimensions(&h264Ctxt.sps[h264Ctxt.sps_idx], &pCtxtV->ctxt.width, &pCtxtV->ctxt.height, NULL, NULL); h264_getVUITiming(&h264Ctxt.sps[h264Ctxt.sps_idx], &pCtxtV->ctxt.clockHz, &pCtxtV->ctxt.frameDeltaHz); pCtxtVH264->profile = h264Ctxt.sps[h264Ctxt.sps_idx].profile_id; pCtxtVH264->level = h264Ctxt.sps[h264Ctxt.sps_idx].level_id; // // The avcc config is needed for dash mpd creation // if((rc = avcc_initCfg(pCtxtVH264->avccRaw, pCtxtVH264->avccRawLen, &pCtxtVH264->avcc)) < 0 || !pCtxtVH264->avcc.psps || !pCtxtVH264->avcc.ppps) { } return rc; }
int h264_getVUITimingFromSps(AVC_DECODER_CFG_BLOB_T *pSpsBlob, unsigned int *pClockHz, unsigned int *pFrameDeltaHz) { int rc = -1; H264_RESULT_T res; H264_DECODER_CTXT_T ctxt; BIT_STREAM_T bs; if(!pSpsBlob) { return -1; } memset(&ctxt, 0, sizeof(ctxt)); memset(&bs, 0, sizeof(bs)); bs.buf = pSpsBlob->data; bs.sz = pSpsBlob->len; if((res = h264_decode_NALHdr(&ctxt, &bs, 0)) >= H264_RESULT_DECODED && (rc = h264_getVUITiming(&ctxt.sps[ctxt.sps_idx], pClockHz, pFrameDeltaHz)) == 0) { } return rc; }