Пример #1
0
void *rtp_thread_func(void *arg) {
    socklen_t si_len = sizeof(rtp_client);
    char packet[MAX_PACKET];
    char *pktp;
    seq_t seqno;
    ssize_t plen;
    int sock = rtp_sockets[0], csock = rtp_sockets[1];
    int readsock;
    char type;

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(sock, &fds);
    FD_SET(csock, &fds);

    while (select(csock>sock ? csock+1 : sock+1, &fds, 0, 0, 0)!=-1) {
        if (FD_ISSET(sock, &fds)) {
            readsock = sock;
        } else {
            readsock = csock;
        }
        FD_SET(sock, &fds);
        FD_SET(csock, &fds);

        plen = recvfrom(readsock, packet, sizeof(packet), 0, (struct sockaddr*)&rtp_client, &si_len);
        if (plen < 0)
            continue;
        assert(plen<=MAX_PACKET);

        type = packet[1] & ~0x80;
        if (type == 0x60 || type == 0x56) {   // audio data / resend
            pktp = packet;
            if (type==0x56) {
                pktp += 4;
                plen -= 4;
            }
            seqno = ntohs(*(unsigned short *)(pktp+2));
            buffer_put_packet(seqno, pktp+12, plen-12);
        }
    }

    return 0;
}
Пример #2
0
static int st_joining(struct state *st) {
    struct pkt pkt;
    int ret;

    // Actually attempt to join the data
    if (st->buffer_offset >= 0) {
        struct pkt pkts[REQUIRED_MATCHES];
        struct pkt old_pkts[REQUIRED_MATCHES];
        int synced = 0;
        int disk_offset = 0;
        int buffer_start = st->buffer_offset;


        for (disk_offset=disk_offset;
             (disk_offset+REQUIRED_MATCHES) < SKIP_AMOUNT && !synced;
             disk_offset++) {

            fill_buffer(st, pkts, REQUIRED_MATCHES, packet_get_next_raw);

            for (st->search_limit = 0;
                 (st->search_limit + REQUIRED_MATCHES) < SKIP_AMOUNT && !synced;
                 st->search_limit++)
            {
                int i;
                int matches_found = 0;
                fill_buffer(st, old_pkts, REQUIRED_MATCHES, buffer_get_packet);

                // Check to see if our run matches up
                for (i=0; i<REQUIRED_MATCHES; i++) {
                    int dat = pkts[i].data.nand_cycle.data;
                    int old_dat = old_pkts[i].data.nand_cycle.data;
                    int ctrl = pkts[i].data.nand_cycle.control;
                    int old_ctrl = old_pkts[i].data.nand_cycle.control;

                    if (dat == old_dat && ctrl == old_ctrl)
                        matches_found++;
                }
                
                // If enough packets match, we're synced
                if (matches_found >= REQUIRED_MATCHES-1) {
                    st->last_sec_dif = st->sec_dif;
                    st->last_nsec_dif = st->nsec_dif;
                    st->sec_dif =
                        -(pkts[REQUIRED_MATCHES/2].header.sec-old_pkts[REQUIRED_MATCHES/2].header.sec);
                    st->nsec_dif =
                        -(pkts[REQUIRED_MATCHES/2].header.nsec-old_pkts[REQUIRED_MATCHES/2].header.nsec);
                    if (st->nsec_dif > 1000000000L) {
                        st->nsec_dif -= 1000000000L;
                        st->sec_dif++;
                    }
                    else if (st->nsec_dif < 0) {
                        st->nsec_dif += 1000000000L;
                        st->sec_dif--;
                    }
                    synced=1;
                    buffer_unget_packet(st, old_pkts);
                }
                else {
                    empty_buffer(st, old_pkts, REQUIRED_MATCHES, buffer_unget_packet);
                    buffer_get_packet(st, old_pkts);
                }
            }

            if (!synced) {
                empty_buffer(st, pkts, REQUIRED_MATCHES, packet_unget);
                empty_buffer(st, old_pkts, REQUIRED_MATCHES,
                        buffer_unget_packet);
                packet_get_next_raw(st, pkts);
            }
        }
        if (!synced)
            printf("Couldn't join\n");

        // Now we're synced, just ignore the rest of the matched-buffer
        // packets.  This is because if they're in the buffer, they've
        // already been written out.
        int tries = 0;
        while ((st->buffer_offset+st->search_limit)%SKIP_AMOUNT != buffer_start-1) {
            struct pkt old_pkt;
            int dat, old_dat, ctrl, old_ctrl;
            buffer_get_packet(st, &old_pkt);
            packet_get_next_raw(st, &pkt);

            dat = pkt.data.nand_cycle.data;
            old_dat = old_pkt.data.nand_cycle.data;
            ctrl = pkt.data.nand_cycle.control;
            old_ctrl = old_pkt.data.nand_cycle.control;
            
            tries++;
            if ((dat != old_dat) || (ctrl != old_ctrl)) {
                printf("Join anomaly after %d tries: %d/%d and %d/%d\n",
                        tries, old_dat, dat, old_ctrl, ctrl);
            }
        }
        st->buffer_offset = -1;
        st->search_limit = 0;
    }

    // Done now, copy data
    while ((ret = packet_get_next_raw(st, &pkt)) == 0) {
        if (!is_nand(st, &pkt)) {
            packet_unget(st, &pkt);
            jstate_set(st, ST_SEARCHING);
            break;
        }

        if (st->nsec_dif > 0) {
            pkt.header.nsec += st->nsec_dif;
            if (pkt.header.nsec > 1000000000L) {
                pkt.header.nsec -= 1000000000L;
                pkt.header.sec++;
            }
            pkt.header.sec += st->sec_dif;
        }
        else {
            pkt.header.nsec -= st->nsec_dif;
            if (pkt.header.nsec <= 0) {
                pkt.header.nsec += 1000000000L;
                pkt.header.sec--;
            }
            pkt.header.sec -= st->sec_dif;
        }
        packet_write(st, &pkt);
        buffer_put_packet(st, &pkt);
    }

    return ret;
}
Пример #3
0
static void *rtp_thread_func(void *arg) {
    socklen_t si_len = sizeof(rtp_client);
    char packet[MAX_PACKET];
    char *pktp;
    seq_t seqno;
    ssize_t plen;
    int sock = rtp_sockets[0], csock = rtp_sockets[1];
    int readsock;
    char type;

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(sock, &fds);
    FD_SET(csock, &fds);

    while (select(csock>sock ? csock+1 : sock+1, &fds, 0, 0, 0)!=-1) {
        if (FD_ISSET(sock, &fds)) {
            readsock = sock;
        } else {
            readsock = csock;
        }
        FD_SET(sock, &fds);
        FD_SET(csock, &fds);

        plen = recvfrom(readsock, packet, sizeof(packet), 0, (struct sockaddr*)&rtp_client, &si_len);
        if (plen < 0)
            continue;
#ifdef DEBUG 
        assert(plen<=MAX_PACKET);
#endif

        type = packet[1] & ~0x80;
        if (type == 0x60 || type == 0x56) {   // audio data / resend
            pktp = packet;
            if (type==0x56) {
                pktp += 4;
                plen -= 4;
            }
            seqno = ntohs(*(unsigned short *)(pktp+2));
            buffer_put_packet(seqno, pktp+12, plen-12);

            // adjust pointer and length
            pktp += 12;
            plen -= 12;
            // check if packet contains enough content to be reasonable
            if (plen >= 16) {
                buffer_put_packet(seqno, pktp, plen);
            } else {
                // resync?
                if (type == 0x56 && seqno == 0) {
                    fprintf(stderr, "Suspected resync request packet received. Initiating resync.\n");
                    pthread_mutex_lock(&ab_mutex);
                    ab_resync();
                    pthread_mutex_unlock(&ab_mutex);
                }
            }

        }
    }

    return 0;
}