Commit 064f19f3 authored by James Almer's avatar James Almer Committed by Anton Khirnov

avconv: support parsing bitstream filter options

Example usage:

avconv -i INPUT -bsf filter[=opt1=val1:opt2=val2] OUTPUT
Signed-off-by: 's avatarJames Almer <jamrial@gmail.com>
Signed-off-by: 's avatarAnton Khirnov <anton@khirnov.net>
parent ecd2ec69
...@@ -190,7 +190,6 @@ static void avconv_cleanup(int ret) ...@@ -190,7 +190,6 @@ static void avconv_cleanup(int ret)
for (j = 0; j < ost->nb_bitstream_filters; j++) for (j = 0; j < ost->nb_bitstream_filters; j++)
av_bsf_free(&ost->bsf_ctx[j]); av_bsf_free(&ost->bsf_ctx[j]);
av_freep(&ost->bsf_ctx); av_freep(&ost->bsf_ctx);
av_freep(&ost->bitstream_filters);
av_frame_free(&ost->filtered_frame); av_frame_free(&ost->filtered_frame);
...@@ -1798,17 +1797,8 @@ static int init_output_bsfs(OutputStream *ost) ...@@ -1798,17 +1797,8 @@ static int init_output_bsfs(OutputStream *ost)
if (!ost->nb_bitstream_filters) if (!ost->nb_bitstream_filters)
return 0; return 0;
ost->bsf_ctx = av_mallocz_array(ost->nb_bitstream_filters, sizeof(*ost->bsf_ctx));
if (!ost->bsf_ctx)
return AVERROR(ENOMEM);
for (i = 0; i < ost->nb_bitstream_filters; i++) { for (i = 0; i < ost->nb_bitstream_filters; i++) {
ret = av_bsf_alloc(ost->bitstream_filters[i], &ctx); ctx = ost->bsf_ctx[i];
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n");
return ret;
}
ost->bsf_ctx[i] = ctx;
ret = avcodec_parameters_copy(ctx->par_in, ret = avcodec_parameters_copy(ctx->par_in,
i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar); i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar);
...@@ -1820,12 +1810,11 @@ static int init_output_bsfs(OutputStream *ost) ...@@ -1820,12 +1810,11 @@ static int init_output_bsfs(OutputStream *ost)
ret = av_bsf_init(ctx); ret = av_bsf_init(ctx);
if (ret < 0) { if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n", av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
ost->bitstream_filters[i]->name); ctx->filter->name);
return ret; return ret;
} }
} }
ctx = ost->bsf_ctx[ost->nb_bitstream_filters - 1];
ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out); ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -360,7 +360,6 @@ typedef struct OutputStream { ...@@ -360,7 +360,6 @@ typedef struct OutputStream {
AVRational mux_timebase; AVRational mux_timebase;
int nb_bitstream_filters; int nb_bitstream_filters;
const AVBitStreamFilter **bitstream_filters;
AVBSFContext **bsf_ctx; AVBSFContext **bsf_ctx;
AVCodecContext *enc_ctx; AVCodecContext *enc_ctx;
......
...@@ -1025,26 +1025,54 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ...@@ -1025,26 +1025,54 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st); MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
while (bsfs && *bsfs) { while (bsfs && *bsfs) {
const AVBitStreamFilter *filter; const AVBitStreamFilter *filter;
char *bsf; const char *bsf, *bsf_options_str, *bsf_name;
AVDictionary *bsf_options = NULL;
bsf = av_get_token(&bsfs, ","); bsf = bsf_options_str = av_get_token(&bsfs, ",");
if (!bsf) if (!bsf)
exit_program(1); exit_program(1);
bsf_name = av_get_token(&bsf_options_str, "=");
if (!bsf_name)
exit_program(1);
filter = av_bsf_get_by_name(bsf); filter = av_bsf_get_by_name(bsf_name);
if (!filter) { if (!filter) {
av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf); av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf_name);
exit_program(1); exit_program(1);
} }
if (*bsf_options_str++) {
ret = av_dict_parse_string(&bsf_options, bsf_options_str, "=", ":", 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error parsing options for bitstream filter %s\n", bsf_name);
exit_program(1);
}
}
av_freep(&bsf); av_freep(&bsf);
ost->bitstream_filters = av_realloc_array(ost->bitstream_filters, ost->bsf_ctx = av_realloc_array(ost->bsf_ctx,
ost->nb_bitstream_filters + 1, ost->nb_bitstream_filters + 1,
sizeof(*ost->bitstream_filters)); sizeof(*ost->bsf_ctx));
if (!ost->bitstream_filters) if (!ost->bsf_ctx)
exit_program(1);
ret = av_bsf_alloc(filter, &ost->bsf_ctx[ost->nb_bitstream_filters]);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error allocating a bistream filter context\n");
exit_program(1); exit_program(1);
}
ost->nb_bitstream_filters++;
if (bsf_options) {
ret = av_opt_set_dict(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, &bsf_options);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error setting options for bitstream filter %s\n", bsf_name);
exit_program(1);
}
assert_avoptions(bsf_options);
av_dict_free(&bsf_options);
}
av_freep(&bsf_name);
ost->bitstream_filters[ost->nb_bitstream_filters++] = filter;
if (*bsfs) if (*bsfs)
bsfs++; bsfs++;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment