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; }
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; }
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; }