2017-11-20 27 views
1

HiSilicon의 Hi35xx 카메라 프로세서를 사용하고 있습니다. 그것은 비디오 파이프 라인이 측면에 볼트로 고정 된 Arm9입니다. 파이프 라인의 한쪽 끝은 CMOS 센서입니다. 다른 끝에는 H264 인코더가 있습니다. 나는 파이프 라인을 켜면 인코더는 다음과 같이 H264 NAL 패킷을 출력합니다FFMPEG를 사용하여 H264에서 HLS 클립 만들기

frame0: <SPS>,<PPS>,<SEI>,<key frame> 
frame1: <delta frame> 
frame2: <delta frame> 
... 
frameN: <delta frame> 
frameN+1: <SPS>,<PPS>,<SEI><key frame> 
frameN+2: <delta frame> 
frameN+3: <delta frame> 
... 
etc. 

나는 다음 (선명도에 대한 의사 코드)을 수행하여 HLS 클립으로 그 선회하고있다 :

av_register_all(); 
avformat_network_init(); 

avformat_alloc_output_context2(&ctx_out, NULL, "hls", "./foo.m3u8"); 

strm_out = avformat_new_stream(ctx_out, NULL); 

codec_out = strm_out->codecpar; 
codec_out->codec_id = AV_CODEC_ID_H264; 
codec_out->codec_type = AVMEDIA_TYPE_VIDEO; 
codec_out->width = encoder_width; 
codec_out->height = encoder_height; 
codec_out->bit_rate = encoder_bitrate; 
codec_out->codec_tag = 0; 

avformat_write_header(ctx_out, NULL); 

while(get_packet_from_pipeline_encoder(&encoder_packet)) { 
    AVPacket pkt; 
    av_init_packet(&pkt); 
    pkt.stream_index = 0; 

    pkt.dts = AV_NOPTS_VALUE; 
    pkt.pts = AV_NOPTS_VALUE; 
    pkt.duration = (1000000/FRAMERATE); // frame rate in microseconds 

    pkt.data = encoder_packet.data; 
    pkt.size = encoder_packet.size; 

    if (is_keyframe(&encoder_packet)) { 
    pkt.flags |= AV_PKT_FLAG_KEY; 
    } 

    av_write_frame(ctx_out, &pkt); 
} 

av_write_trailer(ctx_out); 
avformat_free_context(ctx_out); 

이 보인다을 결과 HLS 프레임 속도가 옳지 않다는 것 외에는 잘 작동합니다. 물론, 이것은 pts/dts 항목을 올바르게 설정하지 않았기 때문에 발생하며 ffmpeg를 사용하면이를 알 수 있습니다. 그래서 저는 두 가지의 의구심을 가지고 있습니다 :

  1. 나는이 권리에 대해 갈 것입니까?
  2. pts/dts 항목을 올바르게 설정하려면 어떻게해야합니까?

인코더가 패킷을 제공하고이를 프레임으로 제출합니다. 그 <SPS>, <PPS> and <SEI> 패킷은 실제로 대역 외 데이터이며 타임 스탬프가 없습니다. 어떻게 정확하게 제출할 수 있습니까?

답변

0

내 결론은 내가 잘못된 방향으로 가고 있다는 것입니다. 근본적인 문제는 입력 컨텍스트가 없기 때문에 SPS, PPS 및 SEI 패킷을 가져와 h264 파서를 사용하여 아무 것도 할 수없는 h264 파서가 없다는 것입니다. 나는 NAL이 0 인 선두 문자가 h264 패킷 인 'mpegts'파일에 길이 단어 (일부 비트 스트림 필터가이를 수행함)로 바꾸기 때문에 필자의 루프가 작동하고있는 것으로 생각된다. 그러나 그것은 프레임으로 제출해야하기 때문에 타임 스탬프를 올바르게 얻을 수있는 기회가별로 없다는 것을 의미합니다. 디코더가 없어 'extradata/sidedata'로 제출할 수 없습니다.

이 문제는 내 인코더의 출력에 대한 사용자 지정 IO 컨텍스트를 작성한 다음 일반 입력 컨텍스트를 수행하여 해결됩니다. 이 접근 방식으로 몇 가지 실험을 해본 결과 제대로 작동하는 것 같습니다.