I've just been experimenting with 1.8.0's vastly
improved lpcm capabilities, and seem to have found one
more problem:
Mplex's 24-bit lpcm PES packet payloads aren't aligned
to the nearest fully-resolved sample boundary, e.g. a
typical packet, (subtracting headers) works out to, in
the case of 24-bit stereo, a 2008 byte audio data
payload, or 167.333 12-byte LR sample blocks.
A disc dvdauthored using this output doesn't play, but
instead (going by the player's readout) skips forward
rapidly through the entire disc, as if rejecting each
LB and trying the next. PowerDVD, on the other hand,
plays either the vob file structure or the iso image
just fine.
If the payload is constrained to an exact multiple of
resolved sample blocks (limited to 167 in the example
above), the problem goes away and the disc plays.
Below is a patch to fix this (excuse the word-wrap,
courtesy of yahoo mail; I'll attach it separately as
well), by adding a 'whole_unit' variable to class
LPCMStream, which is calculated in Init() and
monitored in ReadPacketPayload().
Thanks for this truly excellent resource,
Bahman Negahban
btw, I've only been working with 24-bit, so the
formula I'm using, though safe for 16 bit too, may be
overkill if the 16 bit payload doesn't need to be
inter-channel aligned, and a few more bytes could be
squeezed out here, i.e. maybe [whole_unit = 2 *
(bits_per_sample == 24 ? 3 * channels : 1)]. Maybe
someone with a deeper understanding than mine could
venture an opinion...
---------------------------------------------------
*** audiostrm0.hpp Mon Mar 15 13:47:43 2004
--- audiostrm.hpp Tue Oct 11 13:45:11 2005
*************** private:
*** 172,177 ****
--- 172,178 ----
unsigned int samples_per_second;
unsigned int channels;
unsigned int bits_per_sample;
+ unsigned int whole_unit;
unsigned int bytes_per_frame;
unsigned int frame_index;
unsigned int dynamic_range_code;
--- lpcmstrm_in0.cpp 2005-05-30 14:20:09.000000000
-0400
+++ lpcmstrm_in.cpp 2005-10-11 13:44:50.138500000
-0400
@@ -103,6 +103,7 @@ void LPCMStream::Init ( const int
_strea
samples_per_second * channels *
bits_per_sample / 8
* ticks_per_frame_90kHz
/ 90000;
+ whole_unit = 2 * (bits_per_sample == 24 ? 3 : 1)
* channels;
frame_index = 0;
dynamic_range_code = 0x80;
@@ -212,8 +213,8 @@
LPCMStream::ReadPacketPayload(uint8_t *d
{
unsigned int header_size =
LPCMStream::StreamHeaderSize();
bitcount_t read_start = bs.GetBytePos();
- unsigned int bytes_read = bs.GetBytes(
dst+header_size,
-
to_read-header_size );
+ unsigned int bytes_read = bs.GetBytes( dst +
header_size,
+ (( to_read - header_size ) / whole_unit ) *
whole_unit );
bs.Flush( read_start );
clockticks decode_time;
__________________________________
Start your day with Yahoo! - Make it your home page!
http://www.yahoo.com/r/hs*** audiostrm0.hpp Mon Mar 15 13:47:43 2004
--- audiostrm.hpp Tue Oct 11 13:45:11 2005
*************** private:
*** 172,177 ****
--- 172,178 ----
unsigned int samples_per_second;
unsigned int channels;
unsigned int bits_per_sample;
+ unsigned int whole_unit;
unsigned int bytes_per_frame;
unsigned int frame_index;
unsigned int dynamic_range_code;
--- lpcmstrm_in0.cpp 2005-05-30 14:20:09.000000000 -0400
+++ lpcmstrm_in.cpp 2005-10-11 13:44:50.138500000 -0400
@@ -103,6 +103,7 @@ void LPCMStream::Init ( const int _strea
samples_per_second * channels * bits_per_sample / 8
* ticks_per_frame_90kHz
/ 90000;
+ whole_unit = 2 * (bits_per_sample == 24 ? 3 : 1) * channels;
frame_index = 0;
dynamic_range_code = 0x80;
@@ -212,8 +213,8 @@ LPCMStream::ReadPacketPayload(uint8_t *d
{
unsigned int header_size = LPCMStream::StreamHeaderSize();
bitcount_t read_start = bs.GetBytePos();
- unsigned int bytes_read = bs.GetBytes( dst+header_size,
- to_read-header_size );
+ unsigned int bytes_read = bs.GetBytes( dst + header_size,
+ (( to_read - header_size ) / whole_unit ) * whole_unit );
bs.Flush( read_start );
clockticks decode_time;