Exemple #1
0
static int udp_read(URLContext *h, uint8_t *buf, int size)
{
    UDPContext *s = h->priv_data;
    int ret;
#if HAVE_PTHREAD_CANCEL
    int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;

    if (s->fifo) {
        pthread_mutex_lock(&s->mutex);
        do {
            avail = av_fifo_size(s->fifo);
            if (avail) { // >=size) {
                uint8_t tmp[4];

                av_fifo_generic_read(s->fifo, tmp, 4, NULL);
                avail= AV_RL32(tmp);
                if(avail > size) {
                    av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
                    avail= size;
                }

                av_fifo_generic_read(s->fifo, buf, avail, NULL);
                av_fifo_drain(s->fifo, AV_RL32(tmp) - avail);
                pthread_mutex_unlock(&s->mutex);
                return avail;
            } else if(s->circular_buffer_error) {
                int err = s->circular_buffer_error;
                pthread_mutex_unlock(&s->mutex);
                return err;
            } else if(nonblock) {
                pthread_mutex_unlock(&s->mutex);
                return AVERROR(EAGAIN);
            }
            else {
                /* FIXME: using the monotonic clock would be better,
                   but it does not exist on all supported platforms. */
                int64_t t = av_gettime() + 100000;
                struct timespec tv = { .tv_sec  =  t / 1000000,
                           .tv_nsec = (t % 1000000) * 1000
                };
                if (pthread_cond_timedwait(&s->cond, &s->mutex, &tv) < 0) {
                    pthread_mutex_unlock(&s->mutex);
                    return AVERROR(errno == ETIMEDOUT ? EAGAIN : errno);
                }
                nonblock = 1;
            }
        } while( 1);
    }
#endif

    if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
        ret = ff_network_wait_fd(s->udp_fd, 0);
        if (ret < 0)
            return ret;
    }
    ret = recv(s->udp_fd, buf, size, 0);

    return ret < 0 ? ff_neterrno() : ret;
}
Exemple #2
0
static int dv_assemble_frame(DVMuxContext *c, AVStream* st,
                             uint8_t* data, int data_size, uint8_t** frame)
{
    int i, reqasize;

    *frame = &c->frame_buf[0];
    reqasize = 4 * dv_audio_frame_size(c->sys, c->frames);

    switch (st->codec->codec_type) {
    case AVMEDIA_TYPE_VIDEO:
        /* FIXME: we have to have more sensible approach than this one */
        if (c->has_video)
            av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient audio data or severe sync problem.\n", c->frames);

        memcpy(*frame, data, c->sys->frame_size);
        c->has_video = 1;
        break;
    case AVMEDIA_TYPE_AUDIO:
        for (i = 0; i < c->n_ast && st != c->ast[i]; i++);

          /* FIXME: we have to have more sensible approach than this one */
        if (av_fifo_size(c->audio_data[i]) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE)
            av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames);
        av_fifo_generic_write(c->audio_data[i], data, data_size, NULL);

        /* Let us see if we've got enough audio for one DV frame. */
        c->has_audio |= ((reqasize <= av_fifo_size(c->audio_data[i])) << i);

        break;
    default:
        break;
    }

    /* Let us see if we have enough data to construct one DV frame. */
    if (c->has_video == 1 && c->has_audio + 1 == 1 << c->n_ast) {
        dv_inject_metadata(c, *frame);
        c->has_audio = 0;
        for (i=0; i < c->n_ast; i++) {
            dv_inject_audio(c, i, *frame);
            av_fifo_drain(c->audio_data[i], reqasize);
            c->has_audio |= ((reqasize <= av_fifo_size(c->audio_data[i])) << i);
        }

        c->has_video = 0;

        c->frames++;

        return c->sys->frame_size;
    }

    return 0;
}
Exemple #3
0
int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest)
{
    do {
        int len = FFMIN(f->end - f->rptr, buf_size);
        if(func) func(dest, f->rptr, len);
        else{
            memcpy(dest, f->rptr, len);
            dest = (uint8_t*)dest + len;
        }
        av_fifo_drain(f, len);
        buf_size -= len;
    } while (buf_size > 0);
    return 0;
}
Exemple #4
0
static int udp_read(URLContext *h, uint8_t *buf, int size)
{
    UDPContext *s = h->priv_data;
    int ret;
    int avail;

#if HAVE_PTHREADS
    if (s->fifo) {
        pthread_mutex_lock(&s->mutex);
        do {
            avail = av_fifo_size(s->fifo);
            if (avail) { // >=size) {
                uint8_t tmp[4];
                pthread_mutex_unlock(&s->mutex);

                av_fifo_generic_read(s->fifo, tmp, 4, NULL);
                avail= AV_RL32(tmp);
                if(avail > size){
                    av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
                    avail= size;
                }

                av_fifo_generic_read(s->fifo, buf, avail, NULL);
                av_fifo_drain(s->fifo, AV_RL32(tmp) - avail);
                return avail;
            } else if(s->circular_buffer_error){
                pthread_mutex_unlock(&s->mutex);
                return s->circular_buffer_error;
            } else if(h->flags & AVIO_FLAG_NONBLOCK) {
                pthread_mutex_unlock(&s->mutex);
                return AVERROR(EAGAIN);
            }
            else {
                pthread_cond_wait(&s->cond, &s->mutex);
            }
        } while( 1);
    }
#endif

    if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
        ret = ff_network_wait_fd(s->udp_fd, 0);
        if (ret < 0)
            return ret;
    }
    ret = recv(s->udp_fd, buf, size, 0);

    return ret < 0 ? ff_neterrno() : ret;
}
Exemple #5
0
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
{
    int i, size;

    if (nb_samples < 0)
        return AVERROR(EINVAL);
    nb_samples = FFMIN(nb_samples, af->nb_samples);

    if (nb_samples) {
        size = nb_samples * af->sample_size;
        for (i = 0; i < af->nb_buffers; i++)
            av_fifo_drain(af->buf[i], size);
        af->nb_samples -= nb_samples;
    }
    return 0;
}
Exemple #6
0
Fichier : fifo.c Projet : 1c0n/xbmc
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int))
{
// Read memory barrier needed for SMP here in theory
    do {
        int len = FFMIN(f->end - f->rptr, buf_size);
        if(func) func(dest, f->rptr, len);
        else{
            memcpy(dest, f->rptr, len);
            dest = (uint8_t*)dest + len;
        }
// memory barrier needed for SMP here in theory
        av_fifo_drain(f, len);
        buf_size -= len;
    } while (buf_size > 0);
    return 0;
}
/*  This function uses for 'smart' releasing of consumed data
    from the input bitstream fifo.
    Since the input fifo mapped to mfxBitstream which does not understand
    a wrapping of data over fifo end, we should also to relocate a possible
    data rest to fifo begin. If rest of data is absent then we just reset fifo's
    pointers to initial positions.
    NOTE the case when fifo does contain unconsumed data is rare and typical
    amount of such data is 1..4 bytes.
*/
static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
{
    int data_size;
    int data_rest = 0;

    av_fifo_drain(f, bytes_to_free);

    data_size = av_fifo_size(f);
    if (data_size > 0) {
        if (f->buffer!=f->rptr) {
            if ( (f->end - f->rptr) < data_size) {
                data_rest = data_size - (f->end - f->rptr);
                data_size-=data_rest;
                memmove(f->buffer+data_size, f->buffer, data_rest);
            }
            memmove(f->buffer, f->rptr, data_size);
            data_size+= data_rest;
        }
    }
    f->rptr = f->buffer;
    f->wptr = f->buffer + data_size;
    f->wndx = data_size;
    f->rndx = 0;
}
Exemple #8
0
static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
                      const uint8_t *buf, int buf_size)
{
    FLACParseContext *fpc = s->priv_data;
    FLACHeaderMarker *curr;
    int nb_headers;
    const uint8_t *read_end   = buf;
    const uint8_t *read_start = buf;

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
        FLACFrameInfo fi;
        if (frame_header_is_valid(avctx, buf, &fi))
            s->duration = fi.blocksize;
        *poutbuf      = buf;
        *poutbuf_size = buf_size;
        return buf_size;
    }

    fpc->avctx = avctx;
    if (fpc->best_header_valid)
        return get_best_header(fpc, poutbuf, poutbuf_size);

    /* If a best_header was found last call remove it with the buffer data. */
    if (fpc->best_header && fpc->best_header->best_child) {
        FLACHeaderMarker *temp;
        FLACHeaderMarker *best_child = fpc->best_header->best_child;

        /* Remove headers in list until the end of the best_header. */
        for (curr = fpc->headers; curr != best_child; curr = temp) {
            if (curr != fpc->best_header) {
                av_log(avctx, AV_LOG_DEBUG,
                       "dropping low score %i frame header from offset %i to %i\n",
                       curr->max_score, curr->offset, curr->next->offset);
            }
            temp = curr->next;
            av_freep(&curr->link_penalty);
            av_free(curr);
            fpc->nb_headers_buffered--;
        }
        /* Release returned data from ring buffer. */
        av_fifo_drain(fpc->fifo_buf, best_child->offset);

        /* Fix the offset for the headers remaining to match the new buffer. */
        for (curr = best_child->next; curr; curr = curr->next)
            curr->offset -= best_child->offset;

        fpc->nb_headers_buffered--;
        best_child->offset = 0;
        fpc->headers       = best_child;
        if (fpc->nb_headers_buffered >= FLAC_MIN_HEADERS) {
            fpc->best_header = best_child;
            return get_best_header(fpc, poutbuf, poutbuf_size);
        }
        fpc->best_header   = NULL;
    } else if (fpc->best_header) {
        /* No end frame no need to delete the buffer; probably eof */
        FLACHeaderMarker *temp;

        for (curr = fpc->headers; curr != fpc->best_header; curr = temp) {
            temp = curr->next;
            av_freep(&curr->link_penalty);
            av_free(curr);
        }
        fpc->headers = fpc->best_header->next;
        av_freep(&fpc->best_header->link_penalty);
        av_freep(&fpc->best_header);
    }

    /* Find and score new headers. */
    while ((buf && read_end < buf + buf_size &&
            fpc->nb_headers_buffered < FLAC_MIN_HEADERS)
           || (!buf && !fpc->end_padded)) {
        int start_offset;

        /* Pad the end once if EOF, to check the final region for headers. */
        if (!buf) {
            fpc->end_padded      = 1;
            buf_size = MAX_FRAME_HEADER_SIZE;
            read_end = read_start + MAX_FRAME_HEADER_SIZE;
        } else {
            /* The maximum read size is the upper-bound of what the parser
               needs to have the required number of frames buffered */
            int nb_desired = FLAC_MIN_HEADERS - fpc->nb_headers_buffered + 1;
            read_end       = read_end + FFMIN(buf + buf_size - read_end,
                                              nb_desired * FLAC_AVG_FRAME_SIZE);
        }

        if (!av_fifo_space(fpc->fifo_buf) &&
            av_fifo_size(fpc->fifo_buf) / FLAC_AVG_FRAME_SIZE >
            fpc->nb_headers_buffered * 10) {
            /* There is less than one valid flac header buffered for 10 headers
             * buffered. Therefore the fifo is most likely filled with invalid
             * data and the input is not a flac file. */
            goto handle_error;
        }

        /* Fill the buffer. */
        if (av_fifo_realloc2(fpc->fifo_buf,
                             (read_end - read_start) + av_fifo_size(fpc->fifo_buf)) < 0) {
            av_log(avctx, AV_LOG_ERROR,
                   "couldn't reallocate buffer of size %td\n",
                   (read_end - read_start) + av_fifo_size(fpc->fifo_buf));
            goto handle_error;
        }

        if (buf) {
            av_fifo_generic_write(fpc->fifo_buf, (void*) read_start,
                                  read_end - read_start, NULL);
        } else {
            int8_t pad[MAX_FRAME_HEADER_SIZE] = { 0 };
            av_fifo_generic_write(fpc->fifo_buf, pad, sizeof(pad), NULL);
        }

        /* Tag headers and update sequences. */
        start_offset = av_fifo_size(fpc->fifo_buf) -
                       ((read_end - read_start) + (MAX_FRAME_HEADER_SIZE - 1));
        start_offset = FFMAX(0, start_offset);
        nb_headers   = find_new_headers(fpc, start_offset);

        if (nb_headers < 0) {
            av_log(avctx, AV_LOG_ERROR,
                   "find_new_headers couldn't allocate FLAC header\n");
            goto handle_error;
        }

        fpc->nb_headers_buffered = nb_headers;
        /* Wait till FLAC_MIN_HEADERS to output a valid frame. */
        if (!fpc->end_padded && fpc->nb_headers_buffered < FLAC_MIN_HEADERS) {
            if (buf && read_end < buf + buf_size) {
                read_start = read_end;
                continue;
            } else {
                goto handle_error;
            }
        }

        /* If headers found, update the scores since we have longer chains. */
        if (fpc->end_padded || fpc->nb_headers_found)
            score_sequences(fpc);

        /* restore the state pre-padding */
        if (fpc->end_padded) {
            /* HACK: drain the tail of the fifo */
            fpc->fifo_buf->wptr -= MAX_FRAME_HEADER_SIZE;
            fpc->fifo_buf->wndx -= MAX_FRAME_HEADER_SIZE;
            if (fpc->fifo_buf->wptr < 0) {
                fpc->fifo_buf->wptr += fpc->fifo_buf->end -
                    fpc->fifo_buf->buffer;
            }
            buf_size = 0;
            read_start = read_end = NULL;
        }
    }

    curr = fpc->headers;
    for (curr = fpc->headers; curr; curr = curr->next)
        if (!fpc->best_header || curr->max_score > fpc->best_header->max_score)
            fpc->best_header = curr;

    if (fpc->best_header) {
        fpc->best_header_valid = 1;
        if (fpc->best_header->offset > 0) {
            /* Output a junk frame. */
            av_log(avctx, AV_LOG_DEBUG, "Junk frame till offset %i\n",
                   fpc->best_header->offset);

            /* Set duration to 0. It is unknown or invalid in a junk frame. */
            s->duration = 0;
            *poutbuf_size     = fpc->best_header->offset;
            *poutbuf          = flac_fifo_read_wrap(fpc, 0, *poutbuf_size,
                                                    &fpc->wrap_buf,
                                                    &fpc->wrap_buf_allocated_size);
            return buf_size ? (read_end - buf) : (fpc->best_header->offset -
                                           av_fifo_size(fpc->fifo_buf));
        }
        if (!buf_size)
            return get_best_header(fpc, poutbuf, poutbuf_size);
    }

handle_error:
    *poutbuf      = NULL;
    *poutbuf_size = 0;
    return read_end - buf;
}