Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Video 使用mp4v2将h264写入mp4容器的正确方法是什么?_Video_Mp4_H.264_Rtp - Fatal编程技术网

Video 使用mp4v2将h264写入mp4容器的正确方法是什么?

Video 使用mp4v2将h264写入mp4容器的正确方法是什么?,video,mp4,h.264,rtp,Video,Mp4,H.264,Rtp,我在将RTP数据包中的h264帧写入MP4文件时遇到问题。使用(例如)命令avplay/ffplay播放视频,但我发现以下错误: 当然,看起来有些帧丢失了   我写数据包的方式如下所示: 为此等待NAL类型为8(=SPS)和7(=PPS)的数据包 时间将传入的数据包保留在列表中 如果NAL type为28,则表示帧被分割-查找开始 位和结束位,然后创建适当的NAL单元和棒 碎片在一起 如果我们已找到PPS和SPS表,则创建MP4文件: char*application_name=“isom”;

我在将RTP数据包中的h264帧写入MP4文件时遇到问题。使用(例如)命令avplay/ffplay播放视频,但我发现以下错误:

当然,看起来有些帧丢失了   我写数据包的方式如下所示:

  • 为此等待NAL类型为8(=SPS)和7(=PPS)的数据包 时间将传入的数据包保留在列表中
  • 如果NAL type为28,则表示帧被分割-查找开始 位和结束位,然后创建适当的NAL单元和棒 碎片在一起
  • 如果我们已找到PPS和SPS表,则创建MP4文件:

    char*application_name=“isom”; _mp4file=mp4createx(名称,0,1,1,应用程序名称,1)

    然后创建VideoTrack:

     _video = MP4AddH264VideoTrack(_mp4file, _videoTimeScale, _videoTimeScale / _videoSampleDuration, _videoWidth, _videoHeight,
                                                _sps->getData()[1], //sps[1] AVCProfileIndication
                                                _sps->getData()[2], //sps[2] profile_compat
                                                _sps->getData()[3], //sps[3] AVCLevelIndication
    3); // 4 (minusOne) bytes length before each NAL unit 
    
    设置一些东西:

    MP4SetVideoProfileLevel(_mp4file, 0x7F);
    MP4AddH264SequenceParameterSet(_mp4file, _video, _sps->getData(), _sps->getSize());
    MP4AddH264PictureParameterSet(_mp4file, _video, _pps->getData(), _pps->getSize());
    
  • 将等待帧从列表刷新到文件,并在开头添加以大端为单位的帧大小:

    MP4WriteSample(_mp4file, _video, waitingFrame->getDataWithNalSize(), waitingFrame->getSize(), MP4_INVALID_DURATION, 0, 1);
  • 读取RTP数据包并将其在循环中写入文件:
    MP4WriteSample(_mp4file, _video, _videoFrame->getDataWithNalSize(), _videoFrame->getSize(), MP4_INVALID_DURATION, 0, 1);
  • RTP有效载荷由以下类型的NAL组成:
    -PPS(8)
    -SPS(7)
    -分帧(28),粘贴后我得到IDR(5)和非IDR(1)视频帧
    -SEI(6)
    -澳元(9)

    奇怪的是,如果我不使用MP4WriteSample函数在文件的开头写入PPS和SPS,我会收到以下错误(来自avplay):

    但如果我这样做,就不会有错误。 所以真正的问题是地震。如果我在RTP流中写入它们(使用MP4WriteSample),我会得到“无帧”错误。但是,如果我在文件的开头只写一个SEI“frame”(使用MP4WriteSample),就会出现这种错误:

    [h264 @ 0x7f1e48007d40] error while decoding MB 50 0, bytestream (-48)
    [h264 @ 0x7f1e48007d40] concealing 1499 DC, 1499 AC, 1499 MV errors
    [h264 @ 0x7f1e48008200] error while decoding MB 44 0, bytestream (-25)
    [h264 @ 0x7f1e48008200] concealing 1500 DC, 1500 AC, 1500 MV errors
    [h264 @ 0x7f1e48006d40] top block unavailable for requested intra4x4 mode -1 at 52 0
    
    然后图片被扭曲了(但是我没有“无帧”错误)

    所以我的问题是,什么是将SEI(可能还有AUD?)NAL写入mp4容器的正确方法?


    在我的项目中,我必须使用mp4v2库或任何其他具有免费使用许可证的库(这就是我不能使用libav的原因)

    您从RTP数据包收到的NAL以起始代码00 00 01开始,但NALs mp4v2需要以4字节的NAL长度开始。

    我正在做类似的事情。根据我的经验,H264流类似于SPS、PPS、I-FRAME、S-FRAME、S-FRAME等帧。因此,如果不是从SPS开始,这意味着它很可能位于S帧的某个位置。S帧的解码将取决于播放器,因为它不是一个完整的帧(较小的尺寸)。有些玩家可能会说这是错误,然后停止玩。一些玩家会尽最大努力玩S-FRME(在这里和那里有一些奇怪的阴影)。
    [h264 @ 0x7faebc006d40] non-existing PPS 0 referenced
    [h264 @ 0x7faebc006d40] decode_slice_header error
    [h264 @ 0x7faebc008200] no frame!
    
    [h264 @ 0x7f1e48007d40] error while decoding MB 50 0, bytestream (-48)
    [h264 @ 0x7f1e48007d40] concealing 1499 DC, 1499 AC, 1499 MV errors
    [h264 @ 0x7f1e48008200] error while decoding MB 44 0, bytestream (-25)
    [h264 @ 0x7f1e48008200] concealing 1500 DC, 1500 AC, 1500 MV errors
    [h264 @ 0x7f1e48006d40] top block unavailable for requested intra4x4 mode -1 at 52 0