You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
avconv: support parsing bitstream filter options
Example usage: avconv -i INPUT -bsf filter[=opt1=val1:opt2=val2] OUTPUT Signed-off-by: James Almer <jamrial@gmail.com> Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
committed by
Anton Khirnov
parent
ecd2ec69ce
commit
064f19f39e
15
avconv.c
15
avconv.c
@@ -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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
1
avconv.h
1
avconv.h
@@ -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;
|
||||||
|
48
avconv_opt.c
48
avconv_opt.c
@@ -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, "=");
|
||||||
filter = av_bsf_get_by_name(bsf);
|
if (!bsf_name)
|
||||||
if (!filter) {
|
|
||||||
av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
|
|
||||||
exit_program(1);
|
exit_program(1);
|
||||||
|
|
||||||
|
filter = av_bsf_get_by_name(bsf_name);
|
||||||
|
if (!filter) {
|
||||||
|
av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf_name);
|
||||||
|
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);
|
exit_program(1);
|
||||||
|
|
||||||
ost->bitstream_filters[ost->nb_bitstream_filters++] = filter;
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
if (*bsfs)
|
if (*bsfs)
|
||||||
bsfs++;
|
bsfs++;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user