diff --git a/src/outputs/raop.c b/src/outputs/raop.c index 3eebf9d9..25e5400d 100644 --- a/src/outputs/raop.c +++ b/src/outputs/raop.c @@ -91,6 +91,8 @@ // alignment, which improves performance of some encoders #define RAOP_SAMPLES_PER_PACKET 352 +#define RAOP_RTP_PAYLOADTYPE 0x60 + // How many RTP packets keep in a buffer for retransmission #define RAOP_PACKET_BUFFER_SIZE 1000 @@ -2859,7 +2861,7 @@ packets_send(struct raop_master_session *rms) struct raop_session *rs; int ret; - pkt = rtp_packet_next(rms->rtp_session, ALAC_HEADER_LEN + rms->rawbuf_size, rms->samples_per_packet, 0x60); + pkt = rtp_packet_next(rms->rtp_session, ALAC_HEADER_LEN + rms->rawbuf_size, rms->samples_per_packet, RAOP_RTP_PAYLOADTYPE, 0); ret = packet_prepare(pkt, rms->rawbuf, rms->rawbuf_size, rms->encrypt); if (ret < 0) diff --git a/src/outputs/rtp_common.c b/src/outputs/rtp_common.c index bdbb00a7..8f961812 100644 --- a/src/outputs/rtp_common.c +++ b/src/outputs/rtp_common.c @@ -92,14 +92,15 @@ rtp_session_new(struct media_quality *quality, int pktbuf_size, int sync_each_ns gcry_randomize(&session->pos, sizeof(session->pos), GCRY_STRONG_RANDOM); gcry_randomize(&session->seqnum, sizeof(session->seqnum), GCRY_STRONG_RANDOM); - session->quality = *quality; + if (quality) + session->quality = *quality; session->pktbuf_size = pktbuf_size; CHECK_NULL(L_PLAYER, session->pktbuf = calloc(session->pktbuf_size, sizeof(struct rtp_packet))); if (sync_each_nsamples > 0) session->sync_each_nsamples = sync_each_nsamples; - else if (sync_each_nsamples == 0) + else if (sync_each_nsamples == 0 && quality) session->sync_each_nsamples = quality->sample_rate; return session; @@ -128,7 +129,7 @@ rtp_session_flush(struct rtp_session *session) // We don't want the caller to malloc payload for every packet, so instead we // will get him a packet from the ring buffer, thus in most cases reusing memory struct rtp_packet * -rtp_packet_next(struct rtp_session *session, size_t payload_len, int samples, char type) +rtp_packet_next(struct rtp_session *session, size_t payload_len, int samples, char payload_type, char marker_bit) { struct rtp_packet *pkt; uint16_t seq; @@ -168,7 +169,7 @@ rtp_packet_next(struct rtp_session *session, size_t payload_len, int samples, ch // | synchronization source (SSRC) identifier | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ pkt->header[0] = 0x80; // Version = 2, P, X and CC are 0 - pkt->header[1] = type; // RTP payload type + pkt->header[1] = (marker_bit << 7) | payload_type; // M and payload type seq = htobe16(session->seqnum); memcpy(pkt->header + 2, &seq, 2); diff --git a/src/outputs/rtp_common.h b/src/outputs/rtp_common.h index 172fcc46..233c6c58 100644 --- a/src/outputs/rtp_common.h +++ b/src/outputs/rtp_common.h @@ -62,12 +62,36 @@ rtp_session_free(struct rtp_session *session); void rtp_session_flush(struct rtp_session *session); -struct rtp_packet * -rtp_packet_next(struct rtp_session *session, size_t payload_len, int samples, char type); +/* Gets the next packet from the packet buffer, pkt->payload will be allocated + * to a size of payload_len (or larger). + * + * @in session RTP session + * @in payload_len Length of payload the packet needs to hold + * @in samples Number of samples in packet + * @in payload_type RTP payload type + * @in marker_bit Marker bit, see RFC3551 + * @return Pointer to the next packet in the packet buffer + */ +struct rtp_packet * +rtp_packet_next(struct rtp_session *session, size_t payload_len, int samples, char payload_type, char marker_bit); + +/* Call this after finalizing a packet, i.e. writing the payload and possibly + * sending. Registers the packet as final, i.e. it can now be retrieved with + * rtp_packet_get() for retransmission, if required. Also advances RTP position + * (seqnum and RTP time). + * + * @in session RTP session + * @in pkt RTP packet to commit + */ void rtp_packet_commit(struct rtp_session *session, struct rtp_packet *pkt); +/* Get a previously committed packet from the packet buffer + * + * @in session RTP session + * @in seqnum Packet sequence number + */ struct rtp_packet * rtp_packet_get(struct rtp_session *session, uint16_t seqnum);