Revision 03f8f397 libavformat/udp.c

View differences:

libavformat/udp.c
29 29
#include "avformat.h"
30 30
#include "avio_internal.h"
31 31
#include "libavutil/parseutils.h"
32
#include "libavutil/fifo.h"
32 33
#include <unistd.h>
33 34
#include "internal.h"
34 35
#include "network.h"
35 36
#include "os_support.h"
36 37
#include "url.h"
37 38
#include <pthread.h>
38
#include <semaphore.h>
39 39
#include <sys/resource.h>
40 40
#include <sys/time.h>
41 41

  
......
56 56
    int is_connected;
57 57

  
58 58
    /* Circular Buffer variables for use in UDP receive code */
59
    unsigned char *circular_buffer;
60
    int circular_buffer_head;
61 59
    int circular_buffer_size;
62
    int circular_buffer_tail;
63
    int circular_buffer_available;
60
    AVFifoBuffer *fifo;
64 61
    int circular_buffer_available_max;
65 62
    int circular_buffer_error;
66 63
    pthread_t circular_buffer_thread;
67
    sem_t circular_buffer_semaphore;
68 64
} UDPContext;
69 65

  
70 66
#define UDP_TX_BUF_SIZE 32768
......
345 341
            continue;
346 342

  
347 343
        /* How much do we have left to the end of the buffer */
348
        left = s->circular_buffer_size-s->circular_buffer_head;
349 344
        /* Whats the minimum we can read so that we dont comletely fill the buffer */
350
        sem_wait( &s->circular_buffer_semaphore);
351
        left = FFMIN( left, s->circular_buffer_size-s->circular_buffer_available);
352
        sem_post( &s->circular_buffer_semaphore );
345
        left = av_fifo_space(s->fifo);
346
        left = FFMIN(left, s->fifo->end - s->fifo->wptr);
347

  
353 348
        /* No Space left, error, what do we do now */
354 349
        if( !left) {
355 350
            av_log(h, AV_LOG_ERROR, "circular_buffer: OVERRUN\n");
356 351
            s->circular_buffer_error = EIO;
357 352
            return NULL;
358 353
        }
359
        len = recv(s->udp_fd, s->circular_buffer+s->circular_buffer_head, left, 0);
354

  
355
        len = recv(s->udp_fd, s->fifo->wptr, left, 0);
360 356
        if (len < 0) {
361 357
            if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
362 358
                s->circular_buffer_error = EIO;
363 359
                return NULL;
364 360
            }
365 361
        }
366
        s->circular_buffer_head += len;
367
        sem_wait( &s->circular_buffer_semaphore);
368
        s->circular_buffer_available += len;
369
        s->circular_buffer_available_max = FFMAX( s->circular_buffer_available_max, s->circular_buffer_available);
370
        sem_post( &s->circular_buffer_semaphore );
371
        if( s->circular_buffer_head>=s->circular_buffer_size)
372
            s->circular_buffer_head -= s->circular_buffer_size;
362
        s->fifo->wptr += len;
363
        if (s->fifo->wptr >= s->fifo->end)
364
            s->fifo->wptr = s->fifo->buffer;
365
        s->fifo->wndx += len;
373 366
    }
374 367

  
375 368
    return NULL;
......
516 509

  
517 510
    if (!is_output && s->circular_buffer_size) {
518 511
        /* start the task going */
519
        s->circular_buffer = av_malloc( s->circular_buffer_size);
520
        if (sem_init( &s->circular_buffer_semaphore, PTHREAD_PROCESS_PRIVATE, 1 )) {
521
            av_log(h, AV_LOG_ERROR, "sem_init failed\n");
522
            goto fail;
523
        }
512
        s->fifo = av_fifo_alloc(s->circular_buffer_size);
524 513
        if (pthread_create(&s->circular_buffer_thread, NULL, circular_buffer_task, h)) {
525 514
            av_log(h, AV_LOG_ERROR, "pthread_create failed\n");
526 515
            goto fail;
......
531 520
 fail:
532 521
    if (udp_fd >= 0)
533 522
        closesocket(udp_fd);
534
        if (s->circular_buffer) {
535
            sem_destroy( &s->circular_buffer_semaphore);
536
            av_free( s->circular_buffer);
537
        }
523
        av_fifo_free(s->fifo);
538 524
    av_free(s);
539 525
    return AVERROR(EIO);
540 526
}
......
551 537
    if (s->circular_buffer_thread) {
552 538

  
553 539
        do {
554
            sem_wait( &s->circular_buffer_semaphore );
555
            avail = s->circular_buffer_available;
556
            sem_post( &s->circular_buffer_semaphore );
540
            avail = av_fifo_size(s->fifo);
557 541
            if (avail) { // >=size) {
558 542

  
559 543
                // Maximum amount available
560 544
                size = FFMIN( avail, size);
561
                // Whats left till the end of the circular buffer
562
                left = s->circular_buffer_size-s->circular_buffer_tail;
563
                // How much do we need, all?
564
                left = FFMIN( left, size);
565
                // Get the first block
566
                memcpy( buf, s->circular_buffer+s->circular_buffer_tail, left);
567
                // Have we any more, this will be from the start of the buffer
568
                if (size-left)
569
                    memcpy( buf+left, s->circular_buffer, size-left);
570
                // Check for the tail wrapping around
571
                s->circular_buffer_tail += size;
572
                if( s->circular_buffer_tail>=s->circular_buffer_size)
573
                    s->circular_buffer_tail -= s->circular_buffer_size;
574
                // Update the available amount
575
                sem_wait( &s->circular_buffer_semaphore );
576
                s->circular_buffer_available -= size;
577
                sem_post( &s->circular_buffer_semaphore );
545
                av_fifo_generic_read(s->fifo, buf, size, NULL);
578 546
                return size;
579 547
            }
580 548
            else {
......
627 595
    if (s->is_multicast && (h->flags & AVIO_FLAG_READ))
628 596
        udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
629 597
    closesocket(s->udp_fd);
630
    if (s->circular_buffer) {
631
        sem_destroy( &s->circular_buffer_semaphore);
632
        av_free( s->circular_buffer);
633
        av_log( h, AV_LOG_INFO, "circular_buffer_info max:%d%%\r\n", (s->circular_buffer_available_max*100)/s->circular_buffer_size);
634
    }
598
    av_log( h, AV_LOG_INFO, "circular_buffer_info max:%d%%\r\n", (s->circular_buffer_available_max*100)/s->circular_buffer_size);
599
    av_fifo_free(s->fifo);
635 600
    av_free(s);
636 601
    return 0;
637 602
}

Also available in: Unified diff