func (m *Muxer) WriteData(d *MuxerData) (int, error) {
	ctx, ok := m.esContexts[d.PID]
	if !ok {
		return 0, ErrPIDNotFound
	}

	bytesWritten := 0

	forceTables := d.AdaptationField != nil &&
		d.AdaptationField.RandomAccessIndicator &&
		d.PID == m.pmt.PCRPID

	n, err := m.retransmitTables(forceTables)
	if err != nil {
		return n, err
	}

	bytesWritten += n

	payloadStart := true
	writeAf := d.AdaptationField != nil
	payloadBytesWritten := 0
	for payloadBytesWritten < len(d.PES.Data) {
		pktLen := 1 + mpegTsPacketHeaderSize // sync byte + header
		pkt := Packet{
			Header: &PacketHeader{
				ContinuityCounter:         uint8(ctx.cc.get()),
				HasAdaptationField:        writeAf,
				HasPayload:                false,
				PayloadUnitStartIndicator: false,
				PID:                       d.PID,
			},
		}

		if writeAf {
			pkt.AdaptationField = d.AdaptationField
			// one byte for adaptation field length field
			pktLen += 1 + int(calcPacketAdaptationFieldLength(d.AdaptationField))
			writeAf = false
		}

		bytesAvailable := m.packetSize - pktLen
		if payloadStart {
			pesHeaderLengthCurrent := pesHeaderLength + int(calcPESOptionalHeaderLength(d.PES.Header.OptionalHeader))
			// d.AdaptationField with pes header are too big, we don't have space to write pes header
			if bytesAvailable < pesHeaderLengthCurrent {
				pkt.Header.HasAdaptationField = true
				if pkt.AdaptationField == nil {
					pkt.AdaptationField = newStuffingAdaptationField(bytesAvailable)
				} else {
					pkt.AdaptationField.StuffingLength = bytesAvailable
				}
			} else {
				pkt.Header.HasPayload = true
				pkt.Header.PayloadUnitStartIndicator = true
			}
		} else {
			pkt.Header.HasPayload = true
		}

		if pkt.Header.HasPayload {
			m.buf.Reset()
			if d.PES.Header.StreamID == 0 {
				d.PES.Header.StreamID = ctx.es.StreamType.ToPESStreamID()
			}

			ntot, npayload, err := writePESData(
				m.bufWriter,
				d.PES.Header,
				d.PES.Data[payloadBytesWritten:],
				payloadStart,
				bytesAvailable,
			)
			if err != nil {
				return bytesWritten, err
			}

			payloadBytesWritten += npayload

			pkt.Payload = m.buf.Bytes()

			bytesAvailable -= ntot
			// if we still have some space in packet, we should stuff it with adaptation field stuffing
			// we can't stuff packets with 0xff at the end of a packet since it's not uncommon for PES payloads to have length unspecified
			if bytesAvailable > 0 {
				pkt.Header.HasAdaptationField = true
				if pkt.AdaptationField == nil {
					pkt.AdaptationField = newStuffingAdaptationField(bytesAvailable)
				} else {
					pkt.AdaptationField.StuffingLength = bytesAvailable
				}
			}

			n, err = writePacket(m.bitsWriter, &pkt, m.packetSize)
			if err != nil {
				return bytesWritten, err
			}

			bytesWritten += n

			payloadStart = false
		}
	}

	if d.AdaptationField != nil {
		d.AdaptationField.StuffingLength = 0
	}

	return bytesWritten, nil
}
// WriteData writes MuxerData to TS stream
// Currently only PES packets are supported
// Be aware that after successful call WriteData will set d.AdaptationField.StuffingLength value to zero
WriteData writes MuxerData to TS stream
Currently only PES packets are supported
Be aware that after successful call WriteData will set d.AdaptationField.StuffingLength value to zero
// WriteData writes MuxerData to TS stream // Currently only PES packets are supported // Be aware that after successful call WriteData will set d . AdaptationField . StuffingLength value to zero
func (m *Muxer) WriteData(d *MuxerData) (int, error) {
	ctx, ok := m.esContexts[d.PID]
	if !ok {
		return 0, ErrPIDNotFound
	}
	bytesWritten := 0
	forceTables := d.AdaptationField != nil &&
		d.AdaptationField.RandomAccessIndicator &&
		d.PID == m.pmt.PCRPID
	n, err := m.retransmitTables(forceTables)
	if err != nil {
		return n, err
	}
	bytesWritten += n
	payloadStart := true
	writeAf := d.AdaptationField != nil
	payloadBytesWritten := 0
	for payloadBytesWritten < len(d.PES.Data) {
		pktLen := 1 + mpegTsPacketHeaderSize 
		pkt := Packet{
			Header: &PacketHeader{
				ContinuityCounter:         uint8(ctx.cc.get()),
				HasAdaptationField:        writeAf,
				HasPayload:                false,
				PayloadUnitStartIndicator: false,
				PID:                       d.PID,
			},
		}
		if writeAf {
			pkt.AdaptationField = d.AdaptationField
			pktLen += 1 + int(calcPacketAdaptationFieldLength(d.AdaptationField))
			writeAf = false
		}
		bytesAvailable := m.packetSize - pktLen
		if payloadStart {
			pesHeaderLengthCurrent := pesHeaderLength + int(calcPESOptionalHeaderLength(d.PES.Header.OptionalHeader))
			if bytesAvailable < pesHeaderLengthCurrent {
				pkt.Header.HasAdaptationField = true
				if pkt.AdaptationField == nil {
					pkt.AdaptationField = newStuffingAdaptationField(bytesAvailable)
				} else {
					pkt.AdaptationField.StuffingLength = bytesAvailable
				}
			} else {
				pkt.Header.HasPayload = true
				pkt.Header.PayloadUnitStartIndicator = true
			}
		} else {
			pkt.Header.HasPayload = true
		}
		if pkt.Header.HasPayload {
			m.buf.Reset()
			if d.PES.Header.StreamID == 0 {
				d.PES.Header.StreamID = ctx.es.StreamType.ToPESStreamID()
			}
			ntot, npayload, err := writePESData(
				m.bufWriter,
				d.PES.Header,
				d.PES.Data[payloadBytesWritten:],
				payloadStart,
				bytesAvailable,
			)
			if err != nil {
				return bytesWritten, err
			}
			payloadBytesWritten += npayload
			pkt.Payload = m.buf.Bytes()
			bytesAvailable -= ntot
			if bytesAvailable > 0 {
				pkt.Header.HasAdaptationField = true
				if pkt.AdaptationField == nil {
					pkt.AdaptationField = newStuffingAdaptationField(bytesAvailable)
				} else {
					pkt.AdaptationField.StuffingLength = bytesAvailable
				}
			}
			n, err = writePacket(m.bitsWriter, &pkt, m.packetSize)
			if err != nil {
				return bytesWritten, err
			}
			bytesWritten += n
			payloadStart = false
		}
	}
	if d.AdaptationField != nil {
		d.AdaptationField.StuffingLength = 0
	}
	return bytesWritten, nil
}
func ( m * Muxer ) WriteData ( d * MuxerData ) ( int , error ) { ctx , ok := m . esContexts [ d . PID ] if ! ok { return 0 , ErrPIDNotFound } bytesWritten := 0 forceTables := d . AdaptationField != nil && d . AdaptationField . RandomAccessIndicator && d . PID == m . pmt . PCRPID n , err := m . retransmitTables ( forceTables ) if err != nil { return n , err } bytesWritten += n payloadStart := true writeAf := d . AdaptationField != nil payloadBytesWritten := 0 for payloadBytesWritten < len ( d . PES . Data ) { pktLen := 1 + mpegTsPacketHeaderSize pkt := Packet { Header : & PacketHeader { ContinuityCounter : uint8 ( ctx . cc . get ( ) ) , HasAdaptationField : writeAf , HasPayload : false , PayloadUnitStartIndicator : false , PID : d . PID , } , } if writeAf { pkt . AdaptationField = d . AdaptationField pktLen += 1 + int ( calcPacketAdaptationFieldLength ( d . AdaptationField ) ) writeAf = false } bytesAvailable := m . packetSize - pktLen if payloadStart { pesHeaderLengthCurrent := pesHeaderLength + int ( calcPESOptionalHeaderLength ( d . PES . Header . OptionalHeader ) ) if bytesAvailable < pesHeaderLengthCurrent { pkt . Header . HasAdaptationField = true if pkt . AdaptationField == nil { pkt . AdaptationField = newStuffingAdaptationField ( bytesAvailable ) } else { pkt . AdaptationField . StuffingLength = bytesAvailable } } else { pkt . Header . HasPayload = true pkt . Header . PayloadUnitStartIndicator = true } } else { pkt . Header . HasPayload = true } if pkt . Header . HasPayload { m . buf . Reset ( ) if d . PES . Header . StreamID == 0 { d . PES . Header . StreamID = ctx . es . StreamType . ToPESStreamID ( ) } ntot , npayload , err := writePESData ( m . bufWriter , d . PES . Header , d . PES . Data [ payloadBytesWritten : ] , payloadStart , bytesAvailable , ) if err != nil { return bytesWritten , err } payloadBytesWritten += npayload pkt . Payload = m . buf . Bytes ( ) bytesAvailable -= ntot if bytesAvailable > 0 { pkt . Header . HasAdaptationField = true if pkt . AdaptationField == nil { pkt . AdaptationField = newStuffingAdaptationField ( bytesAvailable ) } else { pkt . AdaptationField . StuffingLength = bytesAvailable } } n , err = writePacket ( m . bitsWriter , & pkt , m . packetSize ) if err != nil { return bytesWritten , err } bytesWritten += n payloadStart = false } } if d . AdaptationField != nil { d . AdaptationField . StuffingLength = 0 } return bytesWritten , nil }
WriteData writes MuxerData to TS stream
Currently only PES packets are supported
Be aware that after successful call WriteData will set d.AdaptationField.StuffingLength value to zero
WriteData writes MuxerData to TS stream Currently only PES packets are supported Be aware that after successful call WriteData will set d . AdaptationField . StuffingLength value to zero
// sync byte + header // one byte for adaptation field length field // d.AdaptationField with pes header are too big, we don't have space to write pes header // if we still have some space in packet, we should stuff it with adaptation field stuffing // we can't stuff packets with 0xff at the end of a packet since it's not uncommon for PES payloads to have length unspecified