简体   繁体   English

当我有原始 H264 帧和时间戳时,如何创建视频 stream?

[英]How to create a video stream when I have raw H264 frames and timestamps?

I receive from a third party application, a stream of packests containing raw H264 frames and a timestamp.我从第三方应用程序收到一个包含原始 H264 帧和时间戳的 stream 数据包。 I want to take the raw frames and the timestamp and re-stream, so I can see the video in a player like VLC我想获取原始帧和时间戳并重新流式传输,这样我就可以在像 VLC 这样的播放器中看到视频

I tried to just take the raw H264 frames as they arrive and stream them over a TCP socket, and I'm actually able to see the video in VLC.我试图在原始 H264 帧到达时获取它们,并通过 TCP 套接字将它们转换为 stream,我实际上能够在 VLC 中看到视频。 But of course without timestamps, the video play at maximum speed and then it stop to wait other frames, and then it starts again at max speed.但是当然没有时间戳,视频以最大速度播放,然后停止等待其他帧,然后以最大速度再次开始播放。 I guess I need to put those raw frames in a container and mark each frame with the timestamp, but I don't know how.我想我需要将这些原始帧放在一个容器中并用时间戳标记每个帧,但我不知道如何做。 Any help appreceated (if in C# even better)感谢任何帮助(如果在 C# 中更好)

Thanks谢谢

(1) Option 1: Timer (1)选项 1:定时器

Simply use a timer to send your individual H264 frames.只需使用计时器发送您的个人 H264 帧。

timer_delay = (1000/FPS); //if FPS is 30, then sends a frame every 33 milliseconds.

A frame (NAL unit) has a start code of four bytes as 00 00 00 00 so grab all bytes from one sequence of and including the 00 00 00 00 up to the last byte before another sequence of 00 00 00 00 begins.一个帧(NAL 单元)有一个四字节的起始码,如00 00 00 00因此在另一个序列00 00 00 00开始之前,从一个序列(包括00 00 00 00到最后一个字节)抓取所有字节。 This should* be your frame data to send.这应该*是您要发送的帧数据。

note:笔记:
I say "should" because H264 sometimes slices the images, so if you send a frame and get only half a picture that means you must send two or three sequences of NAL units as one whole item ( eg: in one bytes array) to see a full image.我说“应该”是因为 H264 有时会对图像进行切片,所以如果您发送一帧并只得到半张图片,这意味着您必须将两到三个 NAL 单元序列作为一个整体发送(例如:在一个字节数组中)才能看到一个完整的图像。 You'll learn through active experimenting.您将通过积极的实验来学习。

(2) Option 2: Pipes (2)选项 2:管道
Try FFmpeg a free command line tool.试试FFmpeg一个免费的命令行工具。 Actually it's also the audio/video decoder for VLC.实际上它也是 VLC 的音频/视频解码器。 You can use C#'s Standard in/out to send the received bytes to FFmpeg (which as a Process is running with encoder settings eg: the output format and resolution, etc).您可以使用 C# 的标准输入/输出将接收到的字节发送到 FFmpeg(作为一个进程正在使用编码器设置运行,例如:输出格式和分辨率等)。

See this article as a starting point:请参阅这篇文章作为起点:
https://mathewsachin.github.io/blog/2017/07/28/ffmpeg-pipe-csharp.html https://mathewsachin.github.io/blog/2017/07/28/ffmpeg-pipe-csharp.html

Frames can be three or four byte delimiter (long or short) depending on encoder.帧可以是三个或四个字节的定界符(长或短),具体取决于编码器。 However, each sample (ie, collection on IDR and Non-IDR frames) have start sequence of 4 bytes 00 00 00 01. Refer to RFC documents for detail.然而,每个样本(即 IDR 和非 IDR 帧的集合)都有 4 个字节的起始序列 00 00 00 01。请参阅 RFC 文档了解详细信息。 You can collect frames in to a single sample and can send it over RTP/RTSP.您可以将帧收集到一个样本中,并可以通过 RTP/RTSP 发送它。 Gstreamer has good capability for RTP. Gstreamer 具有良好的 RTP 能力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM