mplex NAV pack generation

Brent Baccala <[email protected]> Wed, 13 Jun 2007 00:27:00 -0400 (EDT)
Newsgroups gmane.comp.video.mjpeg.devel
Message-ID <[email protected]>
Hi -

I've had a problem with mplex not putting NAV packs into a DVD stream
that starts with a video still frame and then has lots of audio.  This
appears to be legitimate in terms of the DVD standard; the demo disk
from DVD Unlimited contains some VOB files constructed in this way.
But you still need NAV packs every half second or so, and mplex only
inserts them at GOPs.

So, I've patched mplex to "preemptively" insert NAV packs into its
output stream if a full second has gone by without one, and am
attaching the diffs.  Two of them, actually.  The first one fixes what
I think was a definite bug (using the PES header extension on a
private stream 2 packet) that got obscured because dvdauthor would
overwrite the packets with its own data.  The second diff contains my
actual change to mplex's NAV pack insertion routine.

I'm thinking that this code really needs to look forward a bit into
the stream to see if a GOP is about to begin, but my code doesn't do
that.

The usual disclaimers apply: I don't work much on your code, so I'm
jumping into a program I barely understand to try and patch it.  And I
don't have much experience with the patch - I've been using it for
about a day and it seems to work :-)

But I wanted to get this in quickly so you guys can give me any
feedback you might have before I spend a lot more time on this.



 					-bwb

 					Brent Baccala
 					[email protected]

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

_______________________________________________
Mjpeg-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mjpeg-developer
navpack.patch1 (text/plain, 1.3 KB)
diff -ru mjpegtools-1.9.0rc2.dist/mplex/multiplexor.cpp mjpegtools-1.9.0rc2/mplex/multiplexor.cpp
--- mjpegtools-1.9.0rc2.dist/mplex/multiplexor.cpp	2007-03-04 07:31:11.000000000 -0500
+++ mjpegtools-1.9.0rc2/mplex/multiplexor.cpp	2007-06-04 15:11:46.844878928 -0400
@@ -1604,6 +1604,7 @@
                                    index );
     tozero = sector_buf+2048-index;
     memset( index, 0, tozero );
+    index[0] = 0x01;   // substream 1 (DSI)
     index += tozero;
     PS_Stream::BufferPacketSize( packet_size_field, index );
 
diff -ru mjpegtools-1.9.0rc2.dist/mplex/systems.cpp mjpegtools-1.9.0rc2/mplex/systems.cpp
--- mjpegtools-1.9.0rc2.dist/mplex/systems.cpp	2007-03-04 07:31:11.000000000 -0500
+++ mjpegtools-1.9.0rc2/mplex/systems.cpp	2007-06-04 15:11:26.510970152 -0400
@@ -328,7 +328,7 @@
 			break;
 		}
 	}
-	else if( type != PADDING_STR )
+	else if( type != PADDING_STR && type != PRIVATE_STR_2 )
 	{
 	  	/* MPEG-2 packet syntax header flags. */
         /* These *DO NOT* appear in padding packets 			*/
@@ -376,7 +376,7 @@
             *(index++)=static_cast<uint8_t>(STUFFING_BYTE);
 	}
 
-    if( mpeg_version == 2 && type != PADDING_STR )
+    if( mpeg_version == 2 && type != PADDING_STR && type != PRIVATE_STR_2)
     {
         *pes_header_len_field = 
             static_cast<uint8_t>(index-(pes_header_len_field+1));
navpack.patch2 (text/plain, 2.5 KB)
diff -ru mjpegtools-1.9.0rc2.diff1/mplex/multiplexor.cpp mjpegtools-1.9.0rc2/mplex/multiplexor.cpp
--- mjpegtools-1.9.0rc2.diff1/mplex/multiplexor.cpp	2007-06-04 15:13:44.335017712 -0400
+++ mjpegtools-1.9.0rc2/mplex/multiplexor.cpp	2007-06-04 15:13:50.348103584 -0400
@@ -1277,6 +1277,25 @@
 
 		if( despatch )
 		{
+            // If we're not forcing video at the beginning of a
+            // stream, and the output format requires DVD NAV packs,
+            // and it's been at least a full second since the last
+            // one, output one.  Normally NAV packs are output by
+            // DVDVideoStream as GOPs are seen in the stream, but this
+            // handles the case where we've got a video still frame
+            // followed by a lot of audio.  According to mpucoder, DVD
+            // GOP / NAV packs can be up to 36 frames at NTSC's rate
+            // of 29.97 fps, or up to 30 frames at PAL's 24 fps.  So 1
+            // second should be OK.  TODO: scan ahead to see if we're
+            // about to hit another GOP and won't require a NAV pack.
+
+            if (!video_first && (mux_format == MPEG_FORMAT_DVD_NAV)
+                && (earliest > last_DVDPriv2_timestamp + 300*90000)) {
+                mjpeg_debug("Preemptive DVD Priv 2 packet triggered at %lld", earliest);
+                OutputDVDPriv2 ();
+                last_DVDPriv2_timestamp = earliest;
+            }
+
 			despatch->BufferAndOutputSector();
 			video_first = false;
 			if( current_SCR >=  earliest && underrun_ignore == 0)
diff -ru mjpegtools-1.9.0rc2.diff1/mplex/multiplexor.hpp mjpegtools-1.9.0rc2/mplex/multiplexor.hpp
--- mjpegtools-1.9.0rc2.diff1/mplex/multiplexor.hpp	2007-06-04 15:13:44.335017712 -0400
+++ mjpegtools-1.9.0rc2/mplex/multiplexor.hpp	2007-06-04 15:13:50.350103280 -0400
@@ -39,6 +39,7 @@
 	/* Special "unusual" sector types needed for particular formats 
 	 */
 	  
+	clockticks last_DVDPriv2_timestamp;
 	void OutputDVDPriv2 ();
 
 	/* Syntax control parameters, public becaus they're partly referenced
diff -ru mjpegtools-1.9.0rc2.diff1/mplex/videostrm_out.cpp mjpegtools-1.9.0rc2/mplex/videostrm_out.cpp
--- mjpegtools-1.9.0rc2.diff1/mplex/videostrm_out.cpp	2007-06-04 15:13:44.322019688 -0400
+++ mjpegtools-1.9.0rc2/mplex/videostrm_out.cpp	2007-06-04 15:13:50.353102824 -0400
@@ -365,6 +365,7 @@
 void DVDVideoStream::OutputGOPControlSector()
 {
     muxinto.OutputDVDPriv2 ();
+    muxinto.last_DVDPriv2_timestamp = RequiredDTS();
 }