在任何地方都没有完整的例子。在live555文件夹中,有以下程序:testRTSPClient.cpp访问RTSP并接收原始RTP数据包但不对它们执行任何操作。它通过DummySink
类接收它们。
关于如何使用testRTSPClient.cpp
从h264接收NAL单元有example,但live555专门针对每个编解码器设置了自定义接收器类,因此使用它们要好得多。示例:H264or5VideoRTPSink.cpp。
因此,如果我将DummySink
的实例替换为H264or5VideoRTPSink
中testRTSPClient.cpp
的子类的实例,并使该子类接收我认为可能有效的帧。
如果我只是遵循DummySink
的实现,我只需要写下这样的内容:
class MyH264VideoRTPSink: public H264VideoRTPSink {
public:
static MyH264VideoRTPSink* createNew(UsageEnvironment& env,
MediaSubsession& subsession, // identifies the kind of data that's being received
char const* streamId = NULL); // identifies the stream itself (optional)
private:
MyH264VideoRTPSink(UsageEnvironment& env, MediaSubsession& subsession, char const* streamId);
// called only by "createNew()"
virtual ~MyH264VideoRTPSink();
static void afterGettingFrame(void* clientData, unsigned frameSize,
unsigned numTruncatedBytes,
struct timeval presentationTime,
unsigned durationInMicroseconds);
void afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
struct timeval presentationTime, unsigned durationInMicroseconds);
// redefined virtual functions:
virtual Boolean continuePlaying();
u_int8_t* fReceiveBuffer;
MediaSubsession& fSubsession;
char* fStreamId;
};
如果我们查看DummySink
,则表明afterGettingFrame
是接收帧的函数。但收到的框架在哪里?我该如何访问它?
void DummySink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
struct timeval presentationTime, unsigned /*durationInMicroseconds*/) {
// We've just received a frame of data. (Optionally) print out information about it:
更新
我创建了自己的H264接收器类:https://github.com/lucaszanella/jscam/blob/f6b38eea2934519bcccd76c8d3aee7f58793da00/src/jscam/android/app/src/main/cpp/MyH264VideoRTPSink.cpp但它与createNew
中的DummySink
不同{/ 1}}:
createNew(UsageEnvironment& env, Groupsock* RTPgs, unsigned char rtpPayloadFormat);
根本没有提及RTPgs
的意图,rtpPayloadFormat
。我甚至不知道我是否走在正确的轨道上......
答案 0 :(得分:2)
第一个混乱来自Source&接收器,FAQ简要描述了工作流程:
' source1中' - > '源2' (过滤器) - > ' source3' (过滤器) - > '信宿'
类H264VideoRTPSink
用于通过RTP发布数据,而不是使用数据。
对于RTSP客户端示例testRTSPClient.cpp,创建依赖于编解码器的源,处理调用MediaSession::createNew
的DESCRIBE应答。
Sink不依赖于编解码器,startPlaying
上的MediaSink
方法注册了当源接收数据时要调用的回调afterGettingFrame
。接下来,当执行此回调时,您应该调用continuePlaying
再次注册它以获取下一个传入数据。
在DummySink::afterGettingFrame
中,缓冲区包含从RTP缓冲区中提取的H264基本流帧。
要转储H264基本流帧,您可以查看h264bitstream