bool VideoStream::SeqEndRunOut() { unsigned int payload = au_unsent; unsigned int ahead = 0; AUnit *next_au = au; if( next_au == 0 ) return false; for(;;) { if( next_au->end_seq || payload >= muxinto.sector_size) break; ++ahead; next_au = Lookahead(ahead); if( next_au == 0 ) break; payload += next_au->PayloadSize(); } // We don't need to start run-out if the next sector cannot contain // next sequence or there is no next sequence (no AU after the one with // the sequence end marker return next_au != 0 && next_au->end_seq && payload < muxinto.sector_size && Lookahead(ahead+1) != 0; }
const AUnit *VideoStream::NextIFrame() { unsigned int ahead = 0; AUnit *au_ahead = Lookahead(ahead); while( au_ahead != 0 && au_ahead->type != IFRAME && ahead < MAX_GOP_LENGTH ) { ++ahead; au_ahead = Lookahead(ahead); } return au_ahead; }
bool VCDStillsStream::LastSectorLastAU() { return ( Lookahead() == 0 && au_unsent <= muxinto.PacketPayload( *this, buffers_in_header, false, false ) ); }
inline int NextAUType() { AUnit *p_au = Lookahead(); if( p_au != 0 ) return p_au->type; else return NOFRAME; }
CfgValue* CfgValue::ParseValue (InputBuffer& buf) { CfgValue *v = 0; if (buf.SkipWhitespace ()) { buf.Expecting ("Value"); return 0; } for (unsigned int a=0;a<classes.size();a++) { if (classes[a]->Identify (buf)) { v = classes[a]->Create (); if (!v->Parse (buf)) { delete v; return 0; } return v; } } // parse standard value types: char r = Lookahead (buf); if(buf.CompareIdent ("file")) { // load a nested config file return LoadNestedFile (buf); } else if(isalpha (*buf)) { v = new CfgLiteral; ((CfgLiteral*)v)->ident = true; } else if(isdigit (r) || *buf == '.' || *buf == '-') v = new CfgNumeric; else if(*buf == '"') v = new CfgLiteral; else if(*buf == '{') v = new CfgList; if (v && !v->Parse (buf)) { delete v; return 0; } return v; }
unsigned int VideoStream::ExcludeNextIFramePayload() { unsigned int payload = au_unsent; unsigned int ahead = 0; AUnit *au_ahead; for(;;) { au_ahead = Lookahead(ahead); if( au_ahead == 0 || payload >= muxinto.sector_size || au_ahead->type == IFRAME ) break; payload += au_ahead->PayloadSize(); ++ahead; } assert( eoscan || au_ahead != 0 ); return payload; }
void AudioStream::OutputSector ( ) { clockticks PTS; unsigned int max_packet_data; unsigned int actual_payload; unsigned int old_au_then_new_payload; PTS = RequiredDTS(); old_au_then_new_payload = muxinto.PacketPayload( *this, buffers_in_header, false, false ); bool last_packet = Lookahead() == 0; // Ensure we have access units data buffered to allow a sector to be // written. max_packet_data = 0; if( (muxinto.running_out && NextRequiredPTS() > muxinto.runout_PTS) || last_packet) { /* We're now in the last AU of a segment. So we don't want to go beyond it's end when writing sectors. Hence we limit packet payload size to (remaining) AU length. */ max_packet_data = au_unsent+StreamHeaderSize(); } /* CASE: packet starts with new access unit */ if (new_au_next_sec) { actual_payload = muxinto.WritePacket ( max_packet_data, *this, buffers_in_header, PTS, 0, TIMESTAMPBITS_PTS); } /* CASE: packet starts with old access unit, no new one */ /* starts in this very same packet */ else if (!(new_au_next_sec) && (au_unsent >= old_au_then_new_payload)) { actual_payload = muxinto.WritePacket ( max_packet_data, *this, buffers_in_header, 0, 0, TIMESTAMPBITS_NO ); } /* CASE: packet starts with old access unit, a new one */ /* starts in this very same packet */ else /* !(new_au_next_sec) && (au_unsent < old_au_then_new_payload)) */ { /* is there another access unit anyway ? */ if( !last_packet ) { PTS = NextRequiredDTS(); actual_payload = muxinto.WritePacket ( max_packet_data, *this, buffers_in_header, PTS, 0, TIMESTAMPBITS_PTS ); } else { actual_payload = muxinto.WritePacket ( max_packet_data, *this, buffers_in_header, 0, 0, TIMESTAMPBITS_NO ); }; } ++nsec; buffers_in_header = always_buffers_in_header; }
void VideoStream::OutputSector ( ) { unsigned int max_packet_payload; unsigned int actual_payload; unsigned int old_au_then_new_payload; clockticks DTS,PTS; int autype; max_packet_payload = 0; /* 0 = Fill sector */ /* I-frame aligning. For the last AU of segment or for formats with ACCESS-POINT sectors where I-frame (and preceding headers) are sector aligned. We need to look ahead to see how much we may put into the current packet without without touching the next I-frame (which is supposed to be placed at the start of its own sector). N.b.runout_PTS is the PTS of the after which the next I frame marks the start of the next sequence. */ if( muxinto.sector_align_iframeAUs || muxinto.running_out ) { max_packet_payload = ExcludeNextIFramePayload(); } /* Figure out the threshold payload size below which we can fit more than one AU into a packet N.b. because fitting more than one in imposses an overhead of additional header fields so there is a dead spot where we *have* to stuff the packet rather than start fitting in an extra AU. Slightly over-conservative in the case of the last packet... */ old_au_then_new_payload = muxinto.PacketPayload( *this, buffers_in_header, true, true); /* CASE: Packet starts with new access unit */ if (new_au_next_sec ) { autype = AUType(); // Some types of output format (e.g. DVD) require special // control sectors before the sector starting a new GOP // N.b. this implies muxinto.sector_align_iframeAUs // if( gop_control_packet && autype == IFRAME ) { OutputGOPControlSector(); } // // If we demand every AU should have its own timestamp // We can't start two in the same sector... // if( dtspts_for_all_au && max_packet_payload == 0 ) max_packet_payload = au_unsent; PTS = RequiredPTS(); DTS = RequiredDTS(); actual_payload = muxinto.WritePacket ( max_packet_payload, *this, NewAUBuffers(autype), PTS, DTS, NewAUTimestamps(autype) ); muxinto.IndexLastPacket(*this, autype ); } /* CASE: Packet begins with old access unit, no new one */ /* can begin in the very same packet */ else if ( au_unsent >= old_au_then_new_payload || (max_packet_payload != 0 && au_unsent >= max_packet_payload) ) { actual_payload = muxinto.WritePacket( au_unsent, *this, false, 0, 0, TIMESTAMPBITS_NO ); // No new frame starts so no indexing... } /* CASE: Packet begins with old access unit, a new one */ /* could begin in the very same packet */ else /* if ( !new_au_next_sec && (au_unsent < old_au_then_new_payload)) */ { /* Is there a new access unit ? */ if( Lookahead() != 0 ) { autype = NextAUType(); if( dtspts_for_all_au && max_packet_payload == 0 ) max_packet_payload = au_unsent + Lookahead()->length; PTS = NextRequiredPTS(); DTS = NextRequiredDTS(); actual_payload = muxinto.WritePacket ( max_packet_payload, *this, NewAUBuffers(autype), PTS, DTS, NewAUTimestamps(autype) ); muxinto.IndexLastPacket(*this, autype ); } else { actual_payload = muxinto.WritePacket ( au_unsent, *this, false, 0, 0, TIMESTAMPBITS_NO); } } ++nsec; buffers_in_header = always_buffers_in_header; }
void CxdsBuffer::SkipWhite(void) { while(isspace(Lookahead(0))) (void)ReadByte(); }