Ticket #4155: underflow_overflow_fix.diff

File underflow_overflow_fix.diff, 3.7 KB (added by rycius, 10 years ago)
  • libavformat/udp.c

    diff --git a/libavformat/udp.c b/libavformat/udp.c
    index 3835f98..a5a30bf 100644
    a b static void *circular_buffer_task_tx( void *_URLContext)  
    575575
    576576    for(;;) {
    577577        int len;
     578        int buffer_needs;
    578579        const uint8_t *p;
    579580        uint8_t tmp[4];
    580581        int64_t timestamp;
    581582
    582583        len=av_fifo_size(s->fifo);
    583584
    584         while (len<4) {
     585        if (len < 4 && !s->close_req){
     586            buffer_needs = s->circular_buffer_size / 2;
     587            av_log(h, AV_LOG_WARNING, "Fifo empty, prefill up to atleast half of buffer:%i\n", buffer_needs);
     588        } else {
     589            buffer_needs = 4;
     590        }
     591
     592        while (len < buffer_needs) {
    585593            if (s->close_req)
    586594                goto end;
    587595            if (pthread_cond_wait(&s->cond, &s->mutex) < 0) {
    static void *circular_buffer_task_tx( void *_URLContext)  
    589597            }
    590598            len=av_fifo_size(s->fifo);
    591599        }
     600       
     601        if (buffer_needs > 4) {
     602            target_timestamp = av_gettime_relative();
     603            start_timestamp = av_gettime_relative();
     604        }
    592605
    593606        av_fifo_generic_read(s->fifo, tmp, 4, NULL);
    594607        len=AV_RL32(tmp);
    595 
    596608        av_assert0(len >= 0);
    597609        av_assert0(len <= sizeof(s->tmp));
    598 
    599610        av_fifo_generic_read(s->fifo, s->tmp, len, NULL);
    600611
    601612        pthread_mutex_unlock(&s->mutex);
    static int udp_write(URLContext *h, const uint8_t *buf, int size)  
    10971108
    10981109        if(av_fifo_space(s->fifo) < size + 4) {
    10991110            /* What about a partial packet tx ? */
    1100             pthread_mutex_unlock(&s->mutex);
    1101             return AVERROR(ENOMEM);
     1111            /* No Space left */
     1112            pthread_mutex_unlock(&s->mutex);
     1113            if (s->overrun_nonfatal) {
     1114                av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
     1115                        "Surviving due to overrun_nonfatal option\n");
     1116                        return 0;
     1117            } else {
     1118                return AVERROR(ENOMEM);
     1119            }
    11021120        }
    11031121        AV_WL32(tmp, size);
    11041122        av_fifo_generic_write(s->fifo, tmp, 4, NULL); /* size of packet */
  • libavformat/udp.c

    diff --git a/libavformat/udp.c b/libavformat/udp.c
    index 3835f98..38b7a2e 100644
    a b static void *circular_buffer_task_tx( void *_URLContext)  
    581581
    582582        len=av_fifo_size(s->fifo);
    583583
    584         while (len<4) {
    585             if (s->close_req)
    586                 goto end;
    587             if (pthread_cond_wait(&s->cond, &s->mutex) < 0) {
    588                 goto end;
    589             }
    590             len=av_fifo_size(s->fifo);
     584        if ( len < 4 ) {
     585            while (len < s->circular_buffer_size / 2) {
     586                if (s->close_req)
     587                    goto end;
     588                if (pthread_cond_wait(&s->cond, &s->mutex) < 0) {
     589                    goto end;
     590                }
     591                len=av_fifo_size(s->fifo);
     592            }
     593            target_timestamp = av_gettime_relative();
     594            start_timestamp = av_gettime_relative();
    591595        }
    592 
     596       
    593597        av_fifo_generic_read(s->fifo, tmp, 4, NULL);
    594598        len=AV_RL32(tmp);
    595 
    596599        av_assert0(len >= 0);
    597600        av_assert0(len <= sizeof(s->tmp));
    598 
    599601        av_fifo_generic_read(s->fifo, s->tmp, len, NULL);
    600602
    601603        pthread_mutex_unlock(&s->mutex);
    static int udp_write(URLContext *h, const uint8_t *buf, int size)  
    10971099
    10981100        if(av_fifo_space(s->fifo) < size + 4) {
    10991101            /* What about a partial packet tx ? */
    1100             pthread_mutex_unlock(&s->mutex);
    1101             return AVERROR(ENOMEM);
     1102            /* No Space left */
     1103            pthread_mutex_unlock(&s->mutex);
     1104            if (s->overrun_nonfatal) {
     1105                av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
     1106                        "Surviving due to overrun_nonfatal option\n");
     1107                        return 0;
     1108            } else {
     1109                return AVERROR(ENOMEM);
     1110            }
    11021111        }
    11031112        AV_WL32(tmp, size);
    11041113        av_fifo_generic_write(s->fifo, tmp, 4, NULL); /* size of packet */