Hi All,

        I use the latest version   live.2019.02.03.tar.gz download from 
http://www.live555.com/liveMedia/public/, however H.264 bitstream is not 
playable but H.265 is ok.

ffplay warning:
> [rtsp @ 0x7f7fef834400] Multi-layer HEVC coding is not implemented. Update 
> your FFmpeg version to the newest one from Git. If the problem still occurs, 
> it means that your file has a feature which has not been implemented.

Actually I use the newest ffmpeg version on my macOS, and VLC also complain me 
that:


> live555 warning: unsupported NAL type for H265

I captured the respond message from RTSPServer with Wireshark. It seems live555 
regard the H.264 bitstream as H.265.


> Session Description Protocol
>       Session Description Protocol Version (v): 0
>       Owner/Creator, Session Id (o): - 1550460541446764 1 IN IP4 0.0.0.0
>       Session Name (s): Session streamed by "RTSPServer"
 >      Session Information (i): stream
 >     Time Description, active time (t): 0 0
 >      Session Attribute (a): tool:LIVE555 Streaming Media v2019.02.03
>       Session Attribute (a): type:broadcast
>       Session Attribute (a): control:*
>       Session Attribute (a): range:npt=0-
>       Session Attribute (a): x-qt-text-nam:Session streamed by "RTSPServer"
>       Session Attribute (a): x-qt-text-inf:stream
>       Media Description, name and address (m): video 0 RTP/AVP 96
>       Connection Information (c): IN IP4 0.0.0.0
>       Bandwidth Information (b): AS:4096
>       Media Attribute (a): rtpmap:96 H265/90000
>       Media Attribute (a): control:track1

From SDP information, we see “Media Attribute (a): rtpmap:96 H265/90000”, but 
payload type 96 was thought as H.265, not H.264. 
I pasted some code below, though it may be not my fault. 
Much appreciation if you give some advices or patch. 

## About my code

I subclass` OnDemandServerMediaSubsession`, and Implement `createNewRTPSink` 
and `createNewStreamSource`. Also I subclass `FramedSource ` and  implement 
`doGetNextFrame` to get the frame from the encoder by `std::queue`.

Some code:
```c++
void QueueFramedSource::doGetNextFrame() { // derive drom `FramedSource`
   auto streamPacket = streamQueue->dequeue();
   fFrameSize = 0;     // reset frame size
   fDurationInMicroseconds = 0; // set to zero for live source, non-zero for 
file source
   if (streamPacket == nullptr) {
       log_->warningf("[%s#%d]The frame queue is empty!", __func__, __LINE__);
       nextTask() = envir().taskScheduler().scheduleDelayedTask( 3000, 
reinterpret_cast<TaskFunc*>(FramedSource::afterGetting), this);
       return ;
   } else {
       log_->tracef("[%s#%d]seq:%u, pts:%llu, len:%llu", __func__, __LINE__, 
streamPacket->seq_, streamPacket->pts, streamPacket->len_);
   }

   if(streamPacket->len_ > fMaxSize) {
       fFrameSize = fMaxSize;
       fNumTruncatedBytes = streamPacket->len_ - fMaxSize;
       log_->infof("[%s#%d]packet length(%llu) exceed the fMaxSize(%u), 
fNumTruncatedBytes(%u)!!!", __func__, __LINE__, streamPacket->len_, fMaxSize, 
fNumTruncatedBytes);
   } else {
       fFrameSize = streamPacket->len_;
       fNumTruncatedBytes = 0;
   }
   fPresentationTime.tv_sec = streamPacket->pts / 1000000UL;   // update pts
   fPresentationTime.tv_usec = streamPacket->pts % 1000000UL;

   auto offset = start_code_offset(streamPacket->data_, fFrameSize);
   auto startcode_length = start_code_length(streamPacket->data_ + offset, 
fFrameSize - offset);
   auto total_offset = offset + startcode_length;
   fFrameSize -= total_offset;
   memcpy(fTo, streamPacket->data_ + total_offset, fFrameSize);
   delete [] streamPacket->data_;

   FramedSource::afterGetting(this); 
}


FramedSource *RtspServerMediaSubsession::createNewStreamSource(unsigned 
clientSessionId,  //derived from OnDemandServerMediaSubsession
                                                                        
unsigned &estBitrate) {
   estBitrate = 4096;   //VBR, max 4096 kbps
   QueueFramedSource *framedSource = QueueFramedSource::createNew(streamQueue, 
envir());
   if (framedSource == nullptr) {
       return nullptr;
   }

   H264or5VideoStreamDiscreteFramer *discreteFramer = nullptr;
   if (payload_type_ == PT_H264) {
       discreteFramer = H264VideoStreamDiscreteFramer::createNew(envir(), 
framedSource);
   } else if (payload_type_ == PT_H265) {
       discreteFramer = H265VideoStreamDiscreteFramer::createNew(envir(), 
framedSource);
   }

   return discreteFramer;
}
RTPSink *RtspServerMediaSubsession::createNewRTPSink(Groupsock *rtpGroupsock,  
//derived from OnDemandServerMediaSubsession
                                                              unsigned char 
rtpPayloadTypeIfDynamic,
                                                              FramedSource 
*inputSource) {
   H264or5VideoRTPSink *rtpSink = nullptr;
   OutPacketBuffer::increaseMaxSizeTo(max_size_);  /* packet-loss frequently */
   if (payload_type_ == PT_H264) {
       rtpSink = H264VideoRTPSink::createNew(envir(), rtpGroupsock, 
rtpPayloadTypeIfDynamic);
   } else if (payload_type_ == PT_H265) {
       rtpSink = H265VideoRTPSink::createNew(envir(), rtpGroupsock, 
rtpPayloadTypeIfDynamic);
   } else {
       rtpSink = nullptr;
   }

   if (nullptr != rtpSink) {
       rtpSink->setPacketSizes(preferredPacketSize, maxPacketSize);
   }
   return rtpSink;
}
```
_______________________________________________
live-devel mailing list
live-devel@lists.live555.com
http://lists.live555.com/mailman/listinfo/live-devel

Reply via email to