Example #1
0
void ElementaryStream::Muxed (unsigned int bytes_muxed)
{
	clockticks   decode_time;
  
	if (bytes_muxed == 0 || MuxCompleted() )
		return;


	/* Work through what's left of the current AU and the following AU's
	   updating the info until we reach a point where an AU had to be
	   split between packets.
	   NOTE: It *is* possible for this loop to iterate. 

	   The DTS/PTS field for the packet in this case would have been
	   given the that for the first AU to start in the packet.
	   Whether Joe-Blow's hardware VCD player handles this properly is
	   another matter of course!
	*/

	decode_time = RequiredDTS();
	while (au_unsent < bytes_muxed)
	{	  
        AUMuxed(true);          // Update stream specific tracking 
                                // of AUs muxed...
		bufmodel.Queued(au_unsent, decode_time);
		bytes_muxed -= au_unsent;
        new_au_next_sec = NextAU();
        if( !new_au_next_sec )
			return;
		decode_time = RequiredDTS();
	};

	// We've now reached a point where the current AU overran or
	// fitted exactly.  We need to distinguish the latter case
	// so we can record whether the next packet starts with an
	// existing AU or not - info we need to decide what PTS/DTS
	// info to write at the start of the next packet.
	
	if (au_unsent > bytes_muxed)
	{
        AUMuxed(false);
		bufmodel.Queued( bytes_muxed, decode_time);
		au_unsent -= bytes_muxed;
		new_au_next_sec = false;
	} 
	else //  if (au_unsent == bytes_muxed)
	{
        AUMuxed(false);
		bufmodel.Queued(bytes_muxed, decode_time);
		new_au_next_sec = NextAU();
	}	   

}
unsigned int 
LPCMStream::ReadPacketPayload(uint8_t *dst, unsigned int to_read)
{
    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 );
    bs.Flush( read_start );
    
	clockticks   decode_time;
    bool starting_frame_found = false;
    uint8_t starting_frame_index = 0;

    int starting_frame_offset = 
        (new_au_next_sec || au_unsent > bytes_read )
        ? 0 
        : au_unsent;

    unsigned int frames = 0;
    unsigned int bytes_muxed = bytes_read;
  
	if (bytes_muxed == 0 || MuxCompleted() )
    {
		goto completion;
    }


	/* Work through what's left of the current frames and the
	   following frames's updating the info until we reach a point where
	   an frame had to be split between packets. 

	   The DTS/PTS field for the packet in this case would have been
	   given the that for the first AU to start in the packet.

	*/

	decode_time = RequiredDTS();
	while (au_unsent < bytes_muxed)
	{	  
        assert( bytes_muxed > 1 );
		bufmodel.Queued(au_unsent, decode_time);
		bytes_muxed -= au_unsent;
        if( new_au_next_sec )
        {
            ++frames;
            if( ! starting_frame_found )
            {
                starting_frame_index = static_cast<uint8_t>(au->dorder % 20);
                starting_frame_found = true;
            }
        }
		if( !NextAU() )
        {
            goto completion;
        }
		new_au_next_sec = true;
		decode_time = RequiredDTS();
	};

	// We've now reached a point where the current AU overran or
	// fitted exactly.  We need to distinguish the latter case so we
	// can record whether the next packet starts with the tail end of
	// // an already started frame or a new one. We need this info to
	// decide what PTS/DTS info to write at the start of the next
	// packet.
	
	if (au_unsent > bytes_muxed)
	{
        if( new_au_next_sec )
            ++frames;
		bufmodel.Queued( bytes_muxed, decode_time);
		au_unsent -= bytes_muxed;
		new_au_next_sec = false;
	} 
	else //  if (au_unsent == bytes_muxed)
	{
		bufmodel.Queued(bytes_muxed, decode_time);
        if( new_au_next_sec )
            ++frames;
        new_au_next_sec = NextAU();
	}	   
completion:
    // Generate the LPCM header...
    // Note the index counts from the low byte of the offset so
    // the smallest value is 1!
    dst[0] = LPCM_SUB_STR_0 + stream_num;
    dst[1] = frames;
    dst[2] = (starting_frame_offset+4)>>8;
    dst[3] = (starting_frame_offset+4)&0xff;
    unsigned int bps_code;
    switch( bits_per_sample )
    {
    case 16 : bps_code = 0; break;
    case 20 : bps_code = 1; break;
    case 24 : bps_code = 2; break;
    default : bps_code = 3; break;
    }
    dst[4] = starting_frame_index;
    unsigned int bsf_code = (samples_per_second == 48000) ? 0 : 1;
    unsigned int channels_code = channels - 1;
    dst[5] = (bps_code << 6) | (bsf_code << 4) | channels_code;
    dst[6] = dynamic_range_code;
	return bytes_read+header_size;
}