diff --git a/recording-daemon/packet.c b/recording-daemon/packet.c index 1d1b4eba3..af5f54fd4 100644 --- a/recording-daemon/packet.c +++ b/recording-daemon/packet.c @@ -94,79 +94,94 @@ static int ssrc_tree_search(const void *testseq_p, const void *ts_p) { } -// ssrc is locked and must be unlocked when returning -// XXX split up function -static void ssrc_run(ssrc_t *ssrc) { - while (1) { - // see if we have a packet with the correct seq nr in the queue - packet_t *packet = g_tree_lookup(ssrc->packets, GINT_TO_POINTER(ssrc->seq)); - if (G_UNLIKELY(!packet)) { - // why not? do we have anything? (we should) - int nnodes = g_tree_nnodes(ssrc->packets); - if (G_UNLIKELY(nnodes == 0)) - break; - if (G_LIKELY(nnodes < 10)) // XXX arbitrary value - break; // need to wait for more - - // packet was probably lost. search for the next highest seq - struct tree_searcher ts = { .find_seq = ssrc->seq + 1, .found_seq = -1 }; - packet = g_tree_search(ssrc->packets, ssrc_tree_search, &ts); - if (packet) // bullseye - goto have_packet; - if (G_UNLIKELY(ts.found_seq == -1)) { - // didn't find anything. seq must have wrapped around. retry - // starting from zero - ts.find_seq = 0; - packet = g_tree_search(ssrc->packets, ssrc_tree_search, &ts); - if (packet) - goto have_packet; - if (G_UNLIKELY(ts.found_seq == -1)) - abort(); - } +// ssrc is locked +static packet_t *ssrc_next_packet(ssrc_t *ssrc) { + // see if we have a packet with the correct seq nr in the queue + packet_t *packet = g_tree_lookup(ssrc->packets, GINT_TO_POINTER(ssrc->seq)); + if (G_LIKELY(packet != NULL)) + return packet; + + // why not? do we have anything? (we should) + int nnodes = g_tree_nnodes(ssrc->packets); + if (G_UNLIKELY(nnodes == 0)) + return NULL; + if (G_LIKELY(nnodes < 10)) // XXX arbitrary value + return NULL; // need to wait for more + + // packet was probably lost. search for the next highest seq + struct tree_searcher ts = { .find_seq = ssrc->seq + 1, .found_seq = -1 }; + packet = g_tree_search(ssrc->packets, ssrc_tree_search, &ts); + if (packet) // bullseye + return packet; + if (G_UNLIKELY(ts.found_seq == -1)) { + // didn't find anything. seq must have wrapped around. retry + // starting from zero + ts.find_seq = 0; + packet = g_tree_search(ssrc->packets, ssrc_tree_search, &ts); + if (packet) + return packet; + if (G_UNLIKELY(ts.found_seq == -1)) + abort(); + } - // pull out the packet we found - packet = g_tree_lookup(ssrc->packets, GINT_TO_POINTER(ts.found_seq)); - if (G_UNLIKELY(packet == NULL)) - abort(); - } + // pull out the packet we found + packet = g_tree_lookup(ssrc->packets, GINT_TO_POINTER(ts.found_seq)); + if (G_UNLIKELY(packet == NULL)) + abort(); -have_packet:; - dbg("processing packet seq %i", packet->seq); - g_tree_steal(ssrc->packets, GINT_TO_POINTER(packet->seq)); + return packet; +} - // determine payload type and run decoder - unsigned int payload_type = packet->rtp->m_pt & 0x7f; - // check if we have a decoder for this payload type yet - if (G_UNLIKELY(!ssrc->decoders[payload_type])) { - metafile_t *mf = ssrc->metafile; - pthread_mutex_lock(&mf->payloads_lock); - char *payload_str = mf->payload_types[payload_type]; - pthread_mutex_unlock(&mf->payloads_lock); - - if (!payload_str) { - const struct rtp_payload_type *rpt = rtp_get_rfc_payload_type(payload_type); - if (!rpt) { - ilog(LOG_WARN, "Unknown RTP payload type %u", payload_type); - goto next_packet; - } - payload_str = rpt->encoding_with_params.s; + +// ssrc is locked +static void packet_decode(ssrc_t *ssrc, packet_t *packet) { + // determine payload type and run decoder + unsigned int payload_type = packet->rtp->m_pt & 0x7f; + // check if we have a decoder for this payload type yet + if (G_UNLIKELY(!ssrc->decoders[payload_type])) { + metafile_t *mf = ssrc->metafile; + pthread_mutex_lock(&mf->payloads_lock); + char *payload_str = mf->payload_types[payload_type]; + pthread_mutex_unlock(&mf->payloads_lock); + + if (!payload_str) { + const struct rtp_payload_type *rpt = rtp_get_rfc_payload_type(payload_type); + if (!rpt) { + ilog(LOG_WARN, "Unknown RTP payload type %u", payload_type); + return; } + payload_str = rpt->encoding_with_params.s; + } - dbg("payload type for %u is %s", payload_type, payload_str); + dbg("payload type for %u is %s", payload_type, payload_str); - ssrc->decoders[payload_type] = decoder_new(payload_str); - if (!ssrc->decoders[payload_type]) { - ilog(LOG_WARN, "Cannot decode RTP payload type %u (%s)", - payload_type, payload_str); - goto next_packet; - } + ssrc->decoders[payload_type] = decoder_new(payload_str); + if (!ssrc->decoders[payload_type]) { + ilog(LOG_WARN, "Cannot decode RTP payload type %u (%s)", + payload_type, payload_str); + return; } + } + + if (decoder_input(ssrc->decoders[payload_type], &packet->payload, ntohl(packet->rtp->timestamp), + ssrc->output)) + ilog(LOG_ERR, "Failed to decode media packet"); +} + + +// ssrc is locked and must be unlocked when returning +static void ssrc_run(ssrc_t *ssrc) { + while (1) { + // see if we have a packet with the correct seq nr in the queue + packet_t *packet = ssrc_next_packet(ssrc); + if (G_UNLIKELY(packet == NULL)) + break; + + dbg("processing packet seq %i", packet->seq); + g_tree_steal(ssrc->packets, GINT_TO_POINTER(packet->seq)); - if (decoder_input(ssrc->decoders[payload_type], &packet->payload, ntohl(packet->rtp->timestamp), - ssrc->output)) - ilog(LOG_ERR, "Failed to decode media packet"); + packet_decode(ssrc, packet); -next_packet: ssrc->seq = (packet->seq + 1) & 0xffff; packet_free(packet); dbg("packets left in queue: %i", g_tree_nnodes(ssrc->packets));