Search code examples
h.264vlclive-streaminglive555

use live555 to stream H264 to VLC


I try to stream H264 to VLC via RTP without RTSP, that is to receive H.264 stream from IP camera, and send it to VLC on anther host. VLC opened URL “rtp://@:12345”. Notice that openRTSP doing the same thing but output data into file using H264VideoFileSink class, I replace that part of code:

 if (strcmp(subsession->mediumName(), "video") == 0) {
    if (strcmp(subsession->codecName(), "H264") == 0) {
      // For H.264 video stream, we use a special sink that adds 'start codes',
      // and (at the start) the SPS and PPS NAL units:
      //fileSink = H264VideoFileSink::createNew(*env, outFileName,
            //            subsession->fmtp_spropparametersets(),
            //            fileSinkBufferSize, oneFilePerFrame);

      char const* outputAddressStr = "192.168.1.123"; // this could also be unicast
      struct in_addr outputAddress;
      outputAddress.s_addr = our_inet_addr(outputAddressStr);

      const Port outputPort(12345);
      unsigned char const outputTTL = 255;

      Groupsock outputGroupsock(*env, outputAddress, outputPort, outputTTL);
      rtpSink = H264VideoRTPSink::createNew(*env, &outputGroupsock, 96);
   }
…

then,

    subsession->sink = rtpSink;
    subsession->sink->startPlaying(*(subsession->readSource()),
        subsessionAfterPlaying,
        subsession);

The result is that openRTSP is running but VLC received nothing. I used Wireshark to check, no packet sent to destination IP and port.

I also try testMP3Streamer, replace multicast address with the unicast address aboved. VLC could play it. Could anybody give me some suggestions?


Solution

  • There is severals errors in your code, first the Groupsock scope is too narrow, next an H264 Framer is needed to feed an H264VideoRTPSink, as you can see in H264VideoRTPSink.cpp :

    Boolean H264VideoRTPSink::sourceIsCompatibleWithUs(MediaSource& source) {
      // Our source must be an appropriate framer:
      return source.isH264VideoStreamFramer();
    }
    

    Then putting all together will give something like :

    char const* outputAddressStr = "192.168.1.123"; 
    struct in_addr outputAddress;
    outputAddress.s_addr = our_inet_addr(outputAddressStr);
    
    const Port outputPort(12345);
    unsigned char const outputTTL = 255;
    
    Groupsock* outputGroupsock = new Groupsock(*env, outputAddress, outputPort, outputTTL);
    rtpSink = H264VideoRTPSink::createNew(*env, outputGroupsock, 96);
    
    subsession->addFilter(H264VideoStreamDiscreteFramer::createNew(*env, subsession->readSource()));