关键接口
// Query
const AVBitStreamFilter *av_bsf_next(void **opaque);
const AVBitStreamFilter *av_bsf_get_by_name(const char *name);
// Setup
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx);
int av_bsf_init(AVBSFContext *ctx);
// Usage
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt);
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt);
// Cleanup
void av_bsf_free(AVBSFContext **ctx);
查询
枚举方式
void *state = NULL;
const AVBitStreamFilter *bsf;
while ((bsf = av_bsf_next(&state)) {
av_log(NULL, AV_LOG_INFO, "%s\n", bsf->name);
}
通过名称指定
const AVBitStreamFilter *bsf = av_bsf_get_by_name("hevc_mp4toannexb");
设置
AVBSFContext *ctx;
ret = av_bsf_alloc(bsf, &ctx);
if (ret < 0)
return ret;
ret = avcodec_parameters_copy(ctx->par_in, in->codecpar);
if (ret < 0)
goto fail;
ctx->time_base_in = in->time_base;
ret = av_bsf_init(ctx);
if (ret < 0)
goto fail;
ret = avcodec_parameters_copy(out->codecpar, ctx->par_out);
if (ret < 0)
goto fail;
out->time_base = ctx->time_base_out;
使用
AVPacket *pkt;
while (got_new_packet(&pkt)) {
ret = av_bsf_send_packet(ctx, pkt);
if (ret < 0)
goto fail;
while ((ret = av_bsf_receive_packet(ctx, pkt)) == 0) {
yield_packet(pkt);
}
if (ret == AVERROR(EAGAIN)
continue;
IF (ret == AVERROR_EOF)
goto end;
if (ret < 0)
goto fail;
}
// Flush
ret = av_bsf_send_packet(ctx, NULL);
if (ret < 0)
goto fail;
while ((ret = av_bsf_receive_packet(ctx, pkt)) == 0) {
yield_packet(pkt);
}
if (ret != AVERROR_EOF)
goto fail;
为了让bsf知道是结束了,最后send一个NULL pkt。
释放
av_bsf_free(&ctx);