示例#1
0
文件: bsf.c 项目: chris-magic/xplayer
static int bsf_list_filter(AVBSFContext *bsf, AVPacket *out)
{
    BSFListContext *lst = bsf->priv_data;
    int ret;

    if (!lst->nb_bsfs)
        return ff_bsf_get_packet_ref(bsf, out);

    while (1) {
        if (lst->idx > lst->flushed_idx) {
            ret = av_bsf_receive_packet(lst->bsfs[lst->idx-1], out);
            if (ret == AVERROR(EAGAIN)) {
                /* no more packets from idx-1, try with previous */
                ret = 0;
                lst->idx--;
                continue;
            } else if (ret == AVERROR_EOF) {
                /* filter idx-1 is done, continue with idx...nb_bsfs */
                lst->flushed_idx = lst->idx;
                continue;
            }else if (ret < 0) {
                /* filtering error */
                break;
            }
        } else {
            ret = ff_bsf_get_packet_ref(bsf, out);
            if (ret == AVERROR_EOF) {
                lst->idx = lst->flushed_idx;
            } else if (ret < 0)
                break;
        }

        if (lst->idx < lst->nb_bsfs) {
            AVPacket *pkt;
            if (ret == AVERROR_EOF && lst->idx == lst->flushed_idx) {
                /* ff_bsf_get_packet_ref returned EOF and idx is first
                 * filter of yet not flushed filter chain */
                pkt = NULL;
            } else {
                pkt = out;
            }
            ret = av_bsf_send_packet(lst->bsfs[lst->idx], pkt);
            if (ret < 0)
                break;
            lst->idx++;
        } else {
            /* The end of filter chain, break to return result */
            break;
        }
    }

    if (ret < 0)
        av_packet_unref(out);

    return ret;
}
示例#2
0
static int extract_extradata_filter(AVBSFContext *ctx, AVPacket *pkt)
{
    ExtractExtradataContext *s = ctx->priv_data;
    uint8_t *extradata = NULL;
    int extradata_size;
    int ret = 0;

    ret = ff_bsf_get_packet_ref(ctx, pkt);
    if (ret < 0)
        return ret;

    ret = s->extract(ctx, pkt, &extradata, &extradata_size);
    if (ret < 0)
        goto fail;

    if (extradata) {
        ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
                                      extradata, extradata_size);
        if (ret < 0) {
            av_freep(&extradata);
            goto fail;
        }
    }

    return 0;

fail:
    av_packet_unref(pkt);
    return ret;
}
示例#3
0
static int dump_extradata(AVBSFContext *ctx, AVPacket *out)
{
    DumpExtradataContext *s = ctx->priv_data;
    AVPacket *in = &s->pkt;
    int ret = 0;

    ret = ff_bsf_get_packet_ref(ctx, in);
    if (ret < 0)
        return ret;

    if (ctx->par_in->extradata &&
        (s->freq == DUMP_FREQ_ALL ||
         (s->freq == DUMP_FREQ_KEYFRAME && in->flags & AV_PKT_FLAG_KEY))) {
        if (in->size >= INT_MAX - ctx->par_in->extradata_size) {
            ret = AVERROR(ERANGE);
            goto fail;
        }

        ret = av_new_packet(out, in->size + ctx->par_in->extradata_size);
        if (ret < 0)
            goto fail;

        ret = av_packet_copy_props(out, in);
        if (ret < 0) {
            av_packet_unref(out);
            goto fail;
        }

        memcpy(out->data, ctx->par_in->extradata, ctx->par_in->extradata_size);
        memcpy(out->data + ctx->par_in->extradata_size, in->data, in->size);
    } else {
        av_packet_move_ref(out, in);
    }

fail:
    av_packet_unref(in);

    return ret;
}