diff --git a/rtmp/rtmp.go b/rtmp/rtmp.go index 2c6300d5..ea5d05cb 100644 --- a/rtmp/rtmp.go +++ b/rtmp/rtmp.go @@ -130,7 +130,7 @@ var ( errTinyPacket = errors.New("rtmp: packet too small") errEncoding = errors.New("rtmp: encoding error") errDecoding = errors.New("rtmp: decoding error") - errCopying = errors.New("rtmp: copying error") + errUnimplemented = errors.New("rtmp: unimplemented feature") ) // setupURL parses the RTMP URL. @@ -861,76 +861,22 @@ func handshake(s *Session) error { // write prepares data to write then sends it. func (s *Session) write(buf []byte) error { + if buf[0] == RTMP_PACKET_TYPE_INFO || (buf[0] == 'F' && buf[1] == 'L' && buf[2] == 'V') { + return errUnimplemented + } + if len(buf) < minDataSize { + return errTinyPacket + } + pkt := packet{ - channel: RTMP_CHANNEL_SOURCE, - info: s.streamID, + packetType: buf[0], + bodySize: C_AMF_DecodeInt24(buf[1:4]), + timestamp: C_AMF_DecodeInt24(buf[4:7]) | uint32(buf[7])<<24, + channel: RTMP_CHANNEL_SOURCE, + info: s.streamID, } - var enc []byte - for len(buf) != 0 { - if pkt.bytesRead == 0 { - if len(buf) < minDataSize { - return errTinyPacket - } - - if buf[0] == 'F' && buf[1] == 'L' && buf[2] == 'V' { - buf = buf[13:] - } - - pkt.packetType = buf[0] - buf = buf[1:] - pkt.bodySize = C_AMF_DecodeInt24(buf[:3]) - buf = buf[3:] - pkt.timestamp = C_AMF_DecodeInt24(buf[:3]) - buf = buf[3:] - pkt.timestamp |= uint32(buf[0]) << 24 - buf = buf[4:] - - headerType := uint8(RTMP_PACKET_SIZE_MEDIUM) - switch pkt.packetType { - case RTMP_PACKET_TYPE_VIDEO, RTMP_PACKET_TYPE_AUDIO: - if pkt.timestamp == 0 { - headerType = RTMP_PACKET_SIZE_LARGE - } - case RTMP_PACKET_TYPE_INFO: - headerType = RTMP_PACKET_SIZE_LARGE - pkt.bodySize += 16 - } - - resizePacket(&pkt, pkt.bodySize, headerType) - - enc = pkt.body[:pkt.bodySize] - if pkt.packetType == RTMP_PACKET_TYPE_INFO { - enc = C_AMF_EncodeString(enc, setDataFrame) - if enc == nil { - return errEncoding - } - pkt.bytesRead = uint32(len(pkt.body) - len(enc)) - } - - } else { - enc = pkt.body[:pkt.bodySize][pkt.bytesRead:] - } - num := int(pkt.bodySize - pkt.bytesRead) - if num > len(buf) { - num = len(buf) - } - - copy(enc[:num], buf[:num]) - pkt.bytesRead += uint32(num) - buf = buf[num:] - if pkt.bytesRead == pkt.bodySize { - err := sendPacket(s, &pkt, false) - pkt.body = nil - pkt.bytesRead = 0 - if err != nil { - return err - } - if len(buf) < 4 { - return nil - } - buf = buf[4:] - } - } - return nil + resizePacket(&pkt, pkt.bodySize, RTMP_PACKET_SIZE_AUTO) + copy(pkt.body, buf[minDataSize:minDataSize+pkt.bodySize]) + return sendPacket(s, &pkt, false) }