Пример #1
0
int FFMpegFifo::getSpace()
{
	//SDL_LockMutex(mutex);
	int ret = av_fifo_space(fifo);
	//SDL_UnlockMutex(mutex);
	return ret;
}
Пример #2
0
Файл: fifo.c Проект: 1c0n/xbmc
int main(void)
{
    /* create a FIFO buffer */
    AVFifoBuffer *fifo = av_fifo_alloc(13 * sizeof(int));
    int i, j, n;

    /* fill data */
    for (i = 0; av_fifo_space(fifo) >= sizeof(int); i++)
        av_fifo_generic_write(fifo, &i, sizeof(int), NULL);

    /* peek at FIFO */
    n = av_fifo_size(fifo)/sizeof(int);
    for (i = -n+1; i < n; i++) {
        int *v = (int *)av_fifo_peek2(fifo, i*sizeof(int));
        printf("%d: %d\n", i, *v);
    }
    printf("\n");

    /* read data */
    for (i = 0; av_fifo_size(fifo) >= sizeof(int); i++) {
        av_fifo_generic_read(fifo, &j, sizeof(int), NULL);
        printf("%d ", j);
    }
    printf("\n");

    av_fifo_free(fifo);

    return 0;
}
Пример #3
0
static int end_frame(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    BufferSinkContext *buf = inlink->dst->priv;

    av_assert1(inlink->cur_buf);
    if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) {
        /* realloc fifo size */
        if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) {
            av_log(ctx, AV_LOG_ERROR,
                   "Cannot buffer more frames. Consume some available frames "
                   "before adding new ones.\n");
            return AVERROR(ENOMEM);
        }
    }

    /* cache frame */
    av_fifo_generic_write(buf->fifo,
                          &inlink->cur_buf, sizeof(AVFilterBufferRef *), NULL);
    inlink->cur_buf = NULL;
    if (buf->warning_limit &&
        av_fifo_size(buf->fifo) / sizeof(AVFilterBufferRef *) >= buf->warning_limit) {
        av_log(ctx, AV_LOG_WARNING,
               "%d buffers queued in %s, something may be wrong.\n",
               buf->warning_limit,
               (char *)av_x_if_null(ctx->name, ctx->filter->name));
        buf->warning_limit *= 10;
    }
    return 0;
}
Пример #4
0
static void *circular_buffer_task( void *_URLContext)
{
    URLContext *h = _URLContext;
    UDPContext *s = h->priv_data;
    fd_set rfds;
    struct timeval tv;

    for(;;) {
        int left;
        int ret;
        int len;

        if (url_interrupt_cb()) {
            s->circular_buffer_error = EINTR;
            return NULL;
        }

        FD_ZERO(&rfds);
        FD_SET(s->udp_fd, &rfds);
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv);
        if (ret < 0) {
            if (ff_neterrno() == AVERROR(EINTR))
                continue;
            s->circular_buffer_error = EIO;
            return NULL;
        }

        if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds)))
            continue;

        /* How much do we have left to the end of the buffer */
        /* Whats the minimum we can read so that we dont comletely fill the buffer */
        left = av_fifo_space(s->fifo);
        left = FFMIN(left, s->fifo->end - s->fifo->wptr);

        /* No Space left, error, what do we do now */
        if( !left) {
            av_log(h, AV_LOG_ERROR, "circular_buffer: OVERRUN\n");
            s->circular_buffer_error = EIO;
            return NULL;
        }

        len = recv(s->udp_fd, s->fifo->wptr, left, 0);
        if (len < 0) {
            if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
                s->circular_buffer_error = EIO;
                return NULL;
            }
        }
        s->fifo->wptr += len;
        if (s->fifo->wptr >= s->fifo->end)
            s->fifo->wptr = s->fifo->buffer;
        s->fifo->wndx += len;
    }

    return NULL;
}
Пример #5
0
static int get_space(struct ao *ao)
{
    struct priv *priv = ao->priv;
    SDL_LockMutex(priv->buffer_mutex);
    int space = av_fifo_space(priv->buffer);
    SDL_UnlockMutex(priv->buffer_mutex);
    return space;
}
Пример #6
0
static void *circular_buffer_task( void *_URLContext)
{
    URLContext *h = _URLContext;
    UDPContext *s = h->priv_data;
    int old_cancelstate;

    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
    pthread_mutex_lock(&s->mutex);
    if (ff_socket_nonblock(s->udp_fd, 0) < 0) {
        av_log(h, AV_LOG_ERROR, "Failed to set blocking mode");
        s->circular_buffer_error = AVERROR(EIO);
        goto end;
    }
    while(1) {
        int len;

        pthread_mutex_unlock(&s->mutex);
        /* Blocking operations are always cancellation points;
           see "General Information" / "Thread Cancelation Overview"
           in Single Unix. */
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate);
        len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0);
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
        pthread_mutex_lock(&s->mutex);
        if (len < 0) {
            if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
                s->circular_buffer_error = ff_neterrno();
                goto end;
            }
            continue;
        }
        AV_WL32(s->tmp, len);

        if(av_fifo_space(s->fifo) < len + 4) {
            /* No Space left */
            if (s->overrun_nonfatal) {
                av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
                        "Surviving due to overrun_nonfatal option\n");
                continue;
            } else {
                av_log(h, AV_LOG_ERROR, "Circular buffer overrun. "
                        "To avoid, increase fifo_size URL option. "
                        "To survive in such case, use overrun_nonfatal option\n");
                s->circular_buffer_error = AVERROR(EIO);
                goto end;
            }
        }
        av_fifo_generic_write(s->fifo, s->tmp, len+4, NULL);
        pthread_cond_signal(&s->cond);
    }

end:
    pthread_cond_signal(&s->cond);
    pthread_mutex_unlock(&s->mutex);
    return NULL;
}
Пример #7
0
int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx,
                                               AVFrame *frame)
{
    BufferSourceContext *s = ctx->priv;
    AVFrame *copy;
    int refcounted, ret;

    if (!frame) {
        s->eof = 1;
        return 0;
    } else if (s->eof)
        return AVERROR(EINVAL);

    refcounted = !!frame->buf[0];

    switch (ctx->outputs[0]->type) {
    case AVMEDIA_TYPE_VIDEO:
        CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height,
                                 frame->format);
        break;
    case AVMEDIA_TYPE_AUDIO:
        CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout,
                                 frame->format);
        break;
    default:
        return AVERROR(EINVAL);
    }

    if (!av_fifo_space(s->fifo) &&
        (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) +
                                         sizeof(copy))) < 0)
        return ret;

    if (!(copy = av_frame_alloc()))
        return AVERROR(ENOMEM);

    if (refcounted) {
        av_frame_move_ref(copy, frame);
    } else {
        ret = av_frame_ref(copy, frame);
        if (ret < 0) {
            av_frame_free(&copy);
            return ret;
        }
    }

    if ((ret = av_fifo_generic_write(s->fifo, &copy, sizeof(copy), NULL)) < 0) {
        if (refcounted)
            av_frame_move_ref(frame, copy);
        av_frame_free(&copy);
        return ret;
    }

    return 0;
}
Пример #8
0
static void resume(struct ao *ao)
{
    struct priv *priv = ao->priv;
    SDL_LockMutex(priv->buffer_mutex);
    int free = av_fifo_space(priv->buffer);
    SDL_UnlockMutex(priv->buffer_mutex);
    if (free)
        priv->unpause = 1;
    else
        do_resume(ao);
}
Пример #9
0
static void write_buf(AVFilterContext *ctx, AVFilterBufferRef *buf)
{
    BufferSinkContext *sink = ctx->priv;

    if (av_fifo_space(sink->fifo) < sizeof(AVFilterBufferRef *) &&
        (av_fifo_realloc2(sink->fifo, av_fifo_size(sink->fifo) * 2) < 0)) {
            av_log(ctx, AV_LOG_ERROR, "Error reallocating the FIFO.\n");
            return;
    }

    av_fifo_generic_write(sink->fifo, &buf, sizeof(buf), NULL);
}
Пример #10
0
static int process_callback(jack_nframes_t nframes, void *arg)
{
    /* Warning: this function runs in realtime. One mustn't allocate memory here
     * or do any other thing that could block. */

    int i, j;
    JackData *self = arg;
    float * buffer;
    jack_nframes_t latency, cycle_delay;
    AVPacket pkt;
    float *pkt_data;
    double cycle_time;

    if (!self->client)
        return 0;

    /* The approximate delay since the hardware interrupt as a number of frames */
    cycle_delay = jack_frames_since_cycle_start(self->client);

    /* Retrieve filtered cycle time */
    cycle_time = ff_timefilter_update(self->timefilter,
                                      av_gettime() / 1000000.0 - (double) cycle_delay / self->sample_rate,
                                      self->buffer_size);

    /* Check if an empty packet is available, and if there's enough space to send it back once filled */
    if ((av_fifo_size(self->new_pkts) < sizeof(pkt)) || (av_fifo_space(self->filled_pkts) < sizeof(pkt))) {
        self->pkt_xrun = 1;
        return 0;
    }

    /* Retrieve empty (but allocated) packet */
    av_fifo_generic_read(self->new_pkts, &pkt, sizeof(pkt), NULL);

    pkt_data  = (float *) pkt.data;
    latency   = 0;

    /* Copy and interleave audio data from the JACK buffer into the packet */
    for (i = 0; i < self->nports; i++) {
        latency += jack_port_get_total_latency(self->client, self->ports[i]);
        buffer = jack_port_get_buffer(self->ports[i], self->buffer_size);
        for (j = 0; j < self->buffer_size; j++)
            pkt_data[j * self->nports + i] = buffer[j];
    }

    /* Timestamp the packet with the cycle start time minus the average latency */
    pkt.pts = (cycle_time - (double) latency / (self->nports * self->sample_rate)) * 1000000.0;

    /* Send the now filled packet back, and increase packet counter */
    av_fifo_generic_write(self->filled_pkts, &pkt, sizeof(pkt), NULL);
    sem_post(&self->packet_count);

    return 0;
}
Пример #11
0
static int write_to_fifo(AVFifoBuffer *fifo, AVFrame *buf)
{
    int ret;

    if (!av_fifo_space(fifo) &&
        (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) {
        av_frame_free(&buf);
        return ret;
    }

    av_fifo_generic_write(fifo, &buf, sizeof(buf), NULL);
    return 0;
}
Пример #12
0
int FFMpegFifo::read(unsigned char* dst,int readSize)
{
	//SDL_LockMutex(mutex);
	if (av_fifo_size(fifo) < readSize)
	{
		waitReadBytes = readSize;
		//SDL_CondWait(condRead,mutex);
	}
	int ret = av_fifo_generic_read(fifo,dst,readSize,NULL);
	if (av_fifo_space(fifo) >= waitWriteBytes)
		//SDL_CondSignal(condWrite);
	//SDL_UnlockMutex(mutex);
	return readSize;
}
Пример #13
0
static void end_frame(AVFilterLink *link)
{
    AVFilterContext   *ctx = link->dst;
    BufferSinkContext *sink = ctx->priv;

    if (av_fifo_space(sink->fifo) < sizeof(AVFilterBufferRef *) &&
        (av_fifo_realloc2(sink->fifo, av_fifo_size(sink->fifo) * 2) < 0)) {
            av_log(ctx, AV_LOG_ERROR, "Error reallocating the FIFO.\n");
            return;
    }

    av_fifo_generic_write(sink->fifo, &link->cur_buf, sizeof(link->cur_buf), NULL);
    link->cur_buf = NULL;
}
Пример #14
0
static int av_thread_message_queue_send_locked(AVThreadMessageQueue *mq,
                                               void *msg,
                                               unsigned flags)
{
    while (!mq->err_send && av_fifo_space(mq->fifo) < mq->elsize) {
        if ((flags & AV_THREAD_MESSAGE_NONBLOCK))
            return AVERROR(EAGAIN);
        pthread_cond_wait(&mq->cond, &mq->lock);
    }
    if (mq->err_send)
        return mq->err_send;
    av_fifo_generic_write(mq->fifo, msg, mq->elsize, NULL);
    pthread_cond_signal(&mq->cond);
    return 0;
}
Пример #15
0
static int play(struct ao *ao, void *data, int len, int flags)
{
    struct priv *priv = ao->priv;
    SDL_LockMutex(priv->buffer_mutex);
    int free = av_fifo_space(priv->buffer);
    if (len > free) len = free;
    av_fifo_generic_write(priv->buffer, data, len, NULL);
    SDL_CondSignal(priv->underrun_cond);
    SDL_UnlockMutex(priv->buffer_mutex);
    if (priv->unpause) {
        priv->unpause = 0;
        do_resume(ao);
    }
    return len;
}
Пример #16
0
int FFMpegFifo::write(unsigned char* src,int writeSize)
{
	//SDL_LockMutex(mutex);
	if (av_fifo_space(fifo) < writeSize)
	{
		waitWriteBytes = writeSize;
		//SDL_CondWait(condWrite,mutex);
	}
	int ret = av_fifo_generic_write(fifo,src,writeSize,NULL);
	/*
	if (av_fifo_size(fifo) >= waitReadBytes)
		SDL_CondSignal(condRead);
	*/
	//SDL_UnlockMutex(mutex);
	return ret;
}
Пример #17
0
int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
{
    BufferSourceContext *c = s->priv;
    int ret;

    if (!av_fifo_space(c->fifo) &&
        (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
                                         sizeof(buf))) < 0)
        return ret;

//     CHECK_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);

    if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0)
        return ret;

    return 0;
}
Пример #18
0
static int supply_new_packets(JackData *self, AVFormatContext *context)
{
    AVPacket pkt;
    int test, pkt_size = self->buffer_size * self->nports * sizeof(float);

    /* Supply the process callback with new empty packets, by filling the new
     * packets FIFO buffer with as many packets as possible. process_callback()
     * can't do this by itself, because it can't allocate memory in realtime. */
    while (av_fifo_space(self->new_pkts) >= sizeof(pkt)) {
        if ((test = av_new_packet(&pkt, pkt_size)) < 0) {
            av_log(context, AV_LOG_ERROR, "Could not create packet of size %d\n", pkt_size);
            return test;
        }
        av_fifo_generic_write(self->new_pkts, &pkt, sizeof(pkt), NULL);
    }
    return 0;
}
Пример #19
0
static int add_buffer_ref(AVFilterContext *ctx, AVFrame *ref)
{
    BufferSinkContext *buf = ctx->priv;

    if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) {
        /* realloc fifo size */
        if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) {
            av_log(ctx, AV_LOG_ERROR,
                   "Cannot buffer more frames. Consume some available frames "
                   "before adding new ones.\n");
            return AVERROR(ENOMEM);
        }
    }

    /* cache frame */
    av_fifo_generic_write(buf->fifo, &ref, sizeof(AVFilterBufferRef *), NULL);
    return 0;
}
Пример #20
0
static void end_frame(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    BufferSinkContext *buf = inlink->dst->priv;

    if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) {
        /* realloc fifo size */
        if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) {
            av_log(ctx, AV_LOG_ERROR,
                   "Cannot buffer more frames. Consume some available frames "
                   "before adding new ones.\n");
            return;
        }
    }

    /* cache frame */
    av_fifo_generic_write(buf->fifo,
                          &inlink->cur_buf, sizeof(AVFilterBufferRef *), NULL);
}
Пример #21
0
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{
    SelectContext *select = inlink->dst->priv;

    select->select = select_frame(inlink->dst, picref);
    if (select->select) {
        /* frame was requested through poll_frame */
        if (select->cache_frames) {
            if (!av_fifo_space(select->pending_frames))
                av_log(inlink->dst, AV_LOG_ERROR,
                       "Buffering limit reached, cannot cache more frames\n");
            else
                av_fifo_generic_write(select->pending_frames, &picref,
                                      sizeof(picref), NULL);
            return;
        }
        avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
    }
}
Пример #22
0
/*
 This function inserts a packet at fifo front.
*/
static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
{
    int fifo_size = av_fifo_size(q->pkt_fifo);
    if (!fifo_size) {
    /* easy case fifo is empty */
        av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
    } else {
    /* realloc necessary */
        AVPacket pkt;
        AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));

        av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);

        while (av_fifo_size(q->pkt_fifo)) {
            av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
            av_fifo_generic_write(fifo,       &pkt, sizeof(pkt), NULL);
        }
        av_fifo_free(q->pkt_fifo);
        q->pkt_fifo = fifo;
    }
}
Пример #23
0
static int poll_frame(AVFilterLink *outlink)
{
    SelectContext *select = outlink->src->priv;
    AVFilterLink *inlink = outlink->src->inputs[0];
    int count, ret;

    if (!av_fifo_size(select->pending_frames)) {
        if ((count = ff_poll_frame(inlink)) <= 0)
            return count;
        /* request frame from input, and apply select condition to it */
        select->cache_frames = 1;
        while (count-- && av_fifo_space(select->pending_frames)) {
            ret = ff_request_frame(inlink);
            if (ret < 0)
                break;
        }
        select->cache_frames = 0;
    }

    return av_fifo_size(select->pending_frames)/sizeof(AVFrame*);
}
Пример #24
0
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
    SelectContext *select = inlink->dst->priv;

    select->select = select_frame(inlink->dst, frame);
    if (select->select) {
        /* frame was requested through poll_frame */
        if (select->cache_frames) {
            if (!av_fifo_space(select->pending_frames)) {
                av_log(inlink->dst, AV_LOG_ERROR,
                       "Buffering limit reached, cannot cache more frames\n");
                av_frame_free(&frame);
            } else
                av_fifo_generic_write(select->pending_frames, &frame,
                                      sizeof(frame), NULL);
            return 0;
        }
        return ff_filter_frame(inlink->dst->outputs[0], frame);
    }

    av_frame_free(&frame);
    return 0;
}
Пример #25
0
static void *circular_buffer_task( void *_handle)
{
    CacheHttpContext * s = (CacheHttpContext *)_handle;
    URLContext *h = NULL;
    float config_value = 0.0;
    void * fp = NULL;
    int config_ret = 0;

    while(!s->EXIT) {

        av_log(h, AV_LOG_ERROR, "----------circular_buffer_task  item ");
        s->reset_flag = 1;
        if (url_interrupt_cb()) {
            s->circular_buffer_error = EINTR;
            goto FAIL;
        }

        if(h) {
            CacheHttp_ffurl_close(h);
            config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
            if(config_ret >= 0 && (int)config_value == 2)
                CacheHttp_dump_close(fp);
            h = NULL;
        }

        list_item_t * item = getCurrentSegment(NULL);
        if(!item||(!item->file&&!item->flags&ENDLIST_FLAG)) {
            usleep(WAIT_TIME);
            continue;
        }

        s->reset_flag = 0;
        s->item_starttime = item->start_time;
        s->item_duration = item->duration;
        s->have_list_end = item->have_list_end;
        s->ktype = item->ktype;
        if(item->key_ctx!=NULL&& s->ktype==KEY_AES_128) {
            ff_data_to_hex(s->iv, item->key_ctx->iv, sizeof(item->key_ctx->iv), 0);
            ff_data_to_hex(s->key, item->key_ctx->key, sizeof(item->key_ctx->key), 0);
            s->iv[32] = s->key[32] = '\0';
        }
        if(item&&item->flags&ENDLIST_FLAG) {
            s->finish_flag =1;
        } else {
            s->finish_flag =0;
        }

        if(s->finish_flag) {
            av_log(NULL, AV_LOG_INFO, "ENDLIST_FLAG, return 0\n");
            //break;
            usleep(500*1000);
            continue;
        }

        int err, http_code;
        char* filename = NULL;
        if(s->ktype == KEY_NONE) {
            filename = av_strdup(item->file);

        } else {
            char url[MAX_URL_SIZE];
            if (strstr(item->file, "://"))
                snprintf(url, sizeof(url), "crypto+%s", item->file);
            else
                snprintf(url, sizeof(url), "crypto:%s", item->file);

            filename = av_strdup(url);

        }
        int retry_num = 0;
OPEN_RETRY:
        if(s->RESET)
            goto SKIP;
        err = CacheHttp_advanced_ffurl_open_h(&h, filename,AVIO_FLAG_READ|AVIO_FLAG_NONBLOCK, s->headers, &http_code,s);
        if (err) {
            if(url_interrupt_cb()) {
                if(filename) {
                    av_free(filename);
                    filename = NULL;
                }
                break;
            }
            if(1 == http_code && !s->have_list_end) {
                av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h 404\n");
                if(retry_num++ < LIVE_HTTP_RETRY_TIMES) {
                    usleep(WAIT_TIME);
                    goto OPEN_RETRY;
                } else {
                    goto SKIP;
                }
            } else if(s->have_list_end || ((2 == http_code || 3 == http_code)&& !s->have_list_end)) {
                usleep(1000*20);
                goto OPEN_RETRY;
            } else if(!s->have_list_end&&err ==AVERROR(EIO)) {
                if(retry_num++ < LIVE_HTTP_RETRY_TIMES) {//if live streaming,just keep on 2s.
                    usleep(WAIT_TIME);
                    goto OPEN_RETRY;
                } else {
                    av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h failed ,%d\n",err);
                    if(filename) {
                        av_free(filename);
                        filename = NULL;
                    }
                    break;
                }

            } else {
                av_log(h, AV_LOG_ERROR, "----------CacheHttpContext : ffurl_open_h failed ,%d\n",err);
                if(filename) {
                    av_free(filename);
                    filename = NULL;
                }
                break;
            }
        }

        if(h && s->seek_flag) {
            int64_t cur_pos = CacheHttp_ffurl_seek(h, 0, SEEK_CUR);
            int64_t pos_ret = CacheHttp_ffurl_seek(h, s->seek_pos-cur_pos, SEEK_CUR);
            av_log(NULL,AV_LOG_INFO,"--------------> cachehttp_seek   seek_pos=%lld, pos_ret=%lld", s->seek_pos, pos_ret);
            s->seek_flag = 0;
        }

        s->hd = h;
        s->item_pos = 0;
        s->item_size = CacheHttp_ffurl_seek(s->hd, 0, AVSEEK_SIZE);
        item->item_size = s->item_size;
        char tmpbuf[TMP_BUFFER_SIZE];
        int left = 0;
        int tmpdatasize = 0;
        config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
        if(config_ret >= 0 && config_value > 0)
            CacheHttp_dump_open(&fp, filename, (int)config_value);

        while(!s->EXIT) {

            if(s->RESET)
                break;

            if (url_interrupt_cb()) {
                s->circular_buffer_error = EINTR;
                break;
            }

            if(!s->hd)
                break;

            if(s->hd && tmpdatasize <= 0) {
                bandwidth_measure_start_read(s->bandwidth_measure);
                tmpdatasize = CacheHttp_ffurl_read(s->hd, tmpbuf, TMP_BUFFER_SIZE);
                bandwidth_measure_finish_read(s->bandwidth_measure,tmpdatasize);
            }

            //if(tmpdatasize > 0) {
            pthread_mutex_lock(&s->read_mutex);
            left = av_fifo_space(s->fifo);
            left = FFMIN(left, s->fifo->end - s->fifo->wptr);


            if( !left) {
                pthread_mutex_unlock(&s->read_mutex);
                usleep(WAIT_TIME);
                continue;
            }
            left = FFMIN(left, tmpdatasize);
            if(left >0) {
                memcpy(s->fifo->wptr, tmpbuf , left);
                tmpdatasize-=left;
            }
            if(tmpdatasize>0) {
                memmove(tmpbuf, tmpbuf+left , tmpdatasize);
            }

            if (left > 0) {
                config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
                if(config_ret >= 0 && config_value > 0)
                    CacheHttp_dump_write(fp, s->fifo->wptr, left);
                s->fifo->wptr += left;
                if (s->fifo->wptr >= s->fifo->end)
                    s->fifo->wptr = s->fifo->buffer;
                s->fifo->wndx += left;
                s->item_pos += left;
            } else if(left == AVERROR(EAGAIN) || (left < 0 && s->have_list_end&& left != AVERROR_EOF)) {
                pthread_mutex_unlock(&s->read_mutex);
                continue;
            } else {
                pthread_mutex_unlock(&s->read_mutex);
                av_log(h, AV_LOG_ERROR, "---------- circular_buffer_task read left = %d\n", left);
                break;
            }
            pthread_mutex_unlock(&s->read_mutex);
            //}

            //usleep(WAIT_TIME);

        }

SKIP:
        if(filename) {
            av_free(filename);
            filename = NULL;
        }
        if(!s->RESET)
            switchNextSegment(NULL);
    }

FAIL:

    if(h)
        CacheHttp_ffurl_close(h);
    s->hd = NULL;
    s->EXITED = 1;
    config_ret = am_getconfig_float("libplayer.hls.dump",&config_value);
    if(config_ret >= 0 && config_value > 0)
        CacheHttp_dump_close(fp);
    av_log(NULL, AV_LOG_ERROR, "---------> CacheHttp thread quit !");
    return NULL;
}
Пример #26
0
int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
                  AVPacket *pkt, const AVFrame *frame, int *got_packet)
{
    AVPacket new_pkt = { 0 };
    mfxBitstream *bs;

    mfxFrameSurface1 *surf = NULL;
    mfxSyncPoint sync      = NULL;
    int ret;

    if (frame) {
        ret = submit_frame(q, frame, &surf);
        if (ret < 0) {
            av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
            return ret;
        }
    }

    ret = av_new_packet(&new_pkt, q->packet_size);
    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
        return ret;
    }

    bs = av_mallocz(sizeof(*bs));
    if (!bs) {
        av_packet_unref(&new_pkt);
        return AVERROR(ENOMEM);
    }
    bs->Data      = new_pkt.data;
    bs->MaxLength = new_pkt.size;

    do {
        ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
        if (ret == MFX_WRN_DEVICE_BUSY) {
            av_usleep(500);
            continue;
        }
        break;
    } while ( 1 );

    if (ret < 0) {
        av_packet_unref(&new_pkt);
        av_freep(&bs);
        if (ret == MFX_ERR_MORE_DATA)
            return 0;
        av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
        return ff_qsv_error(ret);
    }

    if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
        if (frame->interlaced_frame)
            print_interlace_msg(avctx, q);
        else
            av_log(avctx, AV_LOG_WARNING,
                   "EncodeFrameAsync returned 'incompatible param' code\n");
    }
    if (sync) {
        av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
        av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
        av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
    } else {
        av_packet_unref(&new_pkt);
        av_freep(&bs);
    }

    if (!av_fifo_space(q->async_fifo) ||
        (!frame && av_fifo_size(q->async_fifo))) {
        av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
        av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
        av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);

        MFXVideoCORE_SyncOperation(q->session, sync, 60000);

        new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
        new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
        new_pkt.size = bs->DataLength;

        if (bs->FrameType & MFX_FRAMETYPE_IDR ||
            bs->FrameType & MFX_FRAMETYPE_xIDR)
            new_pkt.flags |= AV_PKT_FLAG_KEY;

#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
        if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
            avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
        else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
            avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
        else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
            avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

        av_freep(&bs);

        if (pkt->data) {
            if (pkt->size < new_pkt.size) {
                av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
                       pkt->size, new_pkt.size);
                av_packet_unref(&new_pkt);
                return AVERROR(EINVAL);
            }

            memcpy(pkt->data, new_pkt.data, new_pkt.size);
            pkt->size = new_pkt.size;

            ret = av_packet_copy_props(pkt, &new_pkt);
            av_packet_unref(&new_pkt);
            if (ret < 0)
                return ret;
        } else
            *pkt = new_pkt;

        *got_packet = 1;
    }
Пример #27
0
static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
                      AVFrame *frame, int *got_frame,
                      AVPacket *avpkt)
{
    QSVFrame *out_frame;
    mfxFrameSurface1 *insurf;
    mfxFrameSurface1 *outsurf;
    mfxSyncPoint *sync;
    mfxBitstream bs = { { { 0 } } };
    int ret;

    if (avpkt->size) {
        bs.Data       = avpkt->data;
        bs.DataLength = avpkt->size;
        bs.MaxLength  = bs.DataLength;
        bs.TimeStamp  = avpkt->pts;
    }

    sync = av_mallocz(sizeof(*sync));
    if (!sync) {
        av_freep(&sync);
        return AVERROR(ENOMEM);
    }

    do {
        ret = get_surface(avctx, q, &insurf);
        if (ret < 0)
            return ret;

        ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL,
                                              insurf, &outsurf, sync);
        if (ret == MFX_WRN_DEVICE_BUSY)
            av_usleep(1);

    } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);

    if (ret != MFX_ERR_NONE &&
        ret != MFX_ERR_MORE_DATA &&
        ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
        ret != MFX_ERR_MORE_SURFACE) {
        av_freep(&sync);
        return ff_qsv_print_error(avctx, ret,
                                  "Error during QSV decoding.");
    }

    /* make sure we do not enter an infinite loop if the SDK
     * did not consume any data and did not return anything */
    if (!*sync && !bs.DataOffset) {
        ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data");
        bs.DataOffset = avpkt->size;
    }

    if (*sync) {
        QSVFrame *out_frame = find_frame(q, outsurf);

        if (!out_frame) {
            av_log(avctx, AV_LOG_ERROR,
                   "The returned surface does not correspond to any frame\n");
            av_freep(&sync);
            return AVERROR_BUG;
        }

        out_frame->queued = 1;
        av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
        av_fifo_generic_write(q->async_fifo, &sync,      sizeof(sync),      NULL);
    } else {
        av_freep(&sync);
    }

    if (!av_fifo_space(q->async_fifo) ||
        (!avpkt->size && av_fifo_size(q->async_fifo))) {
        AVFrame *src_frame;

        av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
        av_fifo_generic_read(q->async_fifo, &sync,      sizeof(sync),      NULL);
        out_frame->queued = 0;

        do {
            ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
        } while (ret == MFX_WRN_IN_EXECUTION);

        av_freep(&sync);

        src_frame = out_frame->frame;

        ret = av_frame_ref(frame, src_frame);
        if (ret < 0)
            return ret;

        outsurf = &out_frame->surface;

#if FF_API_PKT_PTS
FF_DISABLE_DEPRECATION_WARNINGS
        frame->pkt_pts = outsurf->Data.TimeStamp;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
        frame->pts = outsurf->Data.TimeStamp;

        frame->repeat_pict =
            outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
            outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
            outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
        frame->top_field_first =
            outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
        frame->interlaced_frame =
            !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);

        /* update the surface properties */
        if (avctx->pix_fmt == AV_PIX_FMT_QSV)
            ((mfxFrameSurface1*)frame->data[3])->Info = outsurf->Info;

        *got_frame = 1;
    }

    return bs.DataOffset;
}
Пример #28
0
static int get_space(void) {
  return av_fifo_space(buffer);
}
Пример #29
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;
}
Пример #30
0
/**
 * \brief insert len bytes into buffer
 * \param data data to insert
 * \param len length of data
 * \return number of bytes inserted into buffer
 *
 * If there is not enough room, the buffer is filled up
 */
static int write_buffer(unsigned char* data, int len) {
  int free = av_fifo_space(buffer);
  if (len > free) len = free;
  return av_fifo_generic_write(buffer, data, len, NULL);
}