Right now H264or5VideoStreamParser can return 0 from parse() without
requesting more data from input source which leads to frame
delivery process becomes stalled (as 
MPEGVideoStreamFramer::continueReadProcessing()
does not call afterGetting() in this case either).
This can happen for several reasons:
  1. Simply if input stream contains 2 or more consecutive start codes (AFAIK 
this
should never happen in valid byte stream, but parser should not break if
it happens).
  2. As a result of following sequence of events:
    a. Parser reads all bytes prior to next start code, then gets
interrupted because there is no more data available.
    b. stopGettingFrames() gets called on framer and next frame is requested
via getNextFrame(). This discards parsed data from previous frame and
parser now assumes that it is reading new frame and thus already read
start code.
    c. Parser receives next bytes from input source which are the start
code.

This patch moves start code parsing (and discarding) to the beginning of
parsing current frame. Additionaly multiple start codes in row are
treated like one.
---
 liveMedia/H264or5VideoStreamFramer.cpp | 36 ++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)



-- 
Stas Tsymbalov
TrueConf LLC
http://trueconf.com/
diff --git a/liveMedia/H264or5VideoStreamFramer.cpp b/liveMedia/H264or5VideoStreamFramer.cpp
index 8bae69f..5234dcd 100644
--- a/liveMedia/H264or5VideoStreamFramer.cpp
+++ b/liveMedia/H264or5VideoStreamFramer.cpp
@@ -951,9 +951,6 @@ unsigned H264or5VideoStreamParser::parse() {
       while ((first4Bytes = test4Bytes()) != 0x00000001) {
 	get1Byte(); setParseState(); // ensures that we progress over bad data
       }
-      skipBytes(4); // skip this initial code
-      
-      setParseState();
       fHaveSeenFirstStartCode = True; // from now on
     }
     
@@ -998,9 +995,20 @@ unsigned H264or5VideoStreamParser::parse() {
       return 0;
     } else {
       u_int32_t next4Bytes = test4Bytes();
-      if (!fHaveSeenFirstByteOfNALUnit) {
-	fFirstByteOfNALUnit = next4Bytes>>24;
-	fHaveSeenFirstByteOfNALUnit = True;
+      if (curFrameSize() == 0) {
+	// Skip start code(s) at the beginning of a frame
+	while (next4Bytes == 0x00000001 || (next4Bytes&0xFFFFFF00) == 0x00000100) {
+	  if (next4Bytes == 0x00000001)
+	    skipBytes(4);
+	  else
+	    skipBytes(3);
+	  setParseState();
+	  next4Bytes = test4Bytes();
+	}
+	if (!fHaveSeenFirstByteOfNALUnit) {
+	  fFirstByteOfNALUnit = next4Bytes>>24;
+	  fHaveSeenFirstByteOfNALUnit = True;
+	}
       }
       while (next4Bytes != 0x00000001 && (next4Bytes&0xFFFFFF00) != 0x00000100) {
 	// We save at least some of "next4Bytes".
@@ -1017,12 +1025,6 @@ unsigned H264or5VideoStreamParser::parse() {
 	next4Bytes = test4Bytes();
       }
       // Assert: next4Bytes starts with 0x00000001 or 0x000001, and we've saved all previous bytes (forming a complete NAL unit).
-      // Skip over these remaining bytes, up until the start of the next NAL unit:
-      if (next4Bytes == 0x00000001) {
-	skipBytes(4);
-      } else {
-	skipBytes(3);
-      }
     }
 
     fHaveSeenFirstByteOfNALUnit = False; // for the next NAL unit that we'll parse
@@ -1112,8 +1114,18 @@ unsigned H264or5VideoStreamParser::parse() {
     } else {
       // We need to check the *next* NAL unit to figure out whether
       // the current NAL unit ends an 'access unit':
+      StreamParser::saveParserState();
+      u_int32_t next4Bytes = test4Bytes();
+      while (next4Bytes == 0x00000001 || (next4Bytes&0xFFFFFF00) == 0x00000100) {
+	if (next4Bytes == 0x00000001)
+	  skipBytes(4);
+	else
+	  skipBytes(3);
+	next4Bytes = test4Bytes();
+      }
       u_int8_t firstBytesOfNextNALUnit[3];
       testBytes(firstBytesOfNextNALUnit, 3);
+      StreamParser::restoreSavedParserState();
 
       u_int8_t const& next_nal_unit_type = fHNumber == 264
 	? (firstBytesOfNextNALUnit[0]&0x1F) : ((firstBytesOfNextNALUnit[0]&0x7E)>>1);

_______________________________________________
live-devel mailing list
[email protected]
http://lists.live555.com/mailman/listinfo/live-devel

Reply via email to