mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-04-10 19:23:00 +00:00
avconv: switch to the new BSF API
This commit is contained in:
parent
33d18982fa
commit
4426540f0c
147
avconv.c
147
avconv.c
@ -175,13 +175,12 @@ static void avconv_cleanup(int ret)
|
|||||||
}
|
}
|
||||||
for (i = 0; i < nb_output_streams; i++) {
|
for (i = 0; i < nb_output_streams; i++) {
|
||||||
OutputStream *ost = output_streams[i];
|
OutputStream *ost = output_streams[i];
|
||||||
AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
|
|
||||||
while (bsfc) {
|
for (j = 0; j < ost->nb_bitstream_filters; j++)
|
||||||
AVBitStreamFilterContext *next = bsfc->next;
|
av_bsf_free(&ost->bsf_ctx[j]);
|
||||||
av_bitstream_filter_close(bsfc);
|
av_freep(&ost->bsf_ctx);
|
||||||
bsfc = next;
|
av_freep(&ost->bitstream_filters);
|
||||||
}
|
|
||||||
ost->bitstream_filters = NULL;
|
|
||||||
av_frame_free(&ost->filtered_frame);
|
av_frame_free(&ost->filtered_frame);
|
||||||
|
|
||||||
av_parser_close(ost->parser);
|
av_parser_close(ost->parser);
|
||||||
@ -255,10 +254,9 @@ static void abort_codec_experimental(AVCodec *c, int encoder)
|
|||||||
exit_program(1);
|
exit_program(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
static void write_packet(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
||||||
{
|
{
|
||||||
AVStream *st = ost->st;
|
AVStream *st = ost->st;
|
||||||
AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -286,32 +284,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bsfc) {
|
|
||||||
AVCodecContext *avctx = ost->encoding_needed ? ost->enc_ctx : ost->st->codec;
|
|
||||||
AVPacket new_pkt = *pkt;
|
|
||||||
int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
|
|
||||||
&new_pkt.data, &new_pkt.size,
|
|
||||||
pkt->data, pkt->size,
|
|
||||||
pkt->flags & AV_PKT_FLAG_KEY);
|
|
||||||
if (a > 0) {
|
|
||||||
av_packet_unref(pkt);
|
|
||||||
new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
|
|
||||||
av_buffer_default_free, NULL, 0);
|
|
||||||
if (!new_pkt.buf)
|
|
||||||
exit_program(1);
|
|
||||||
} else if (a < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "%s failed for stream %d, codec %s",
|
|
||||||
bsfc->filter->name, pkt->stream_index,
|
|
||||||
avctx->codec ? avctx->codec->name : "copy");
|
|
||||||
print_error("", a);
|
|
||||||
if (exit_on_error)
|
|
||||||
exit_program(1);
|
|
||||||
}
|
|
||||||
*pkt = new_pkt;
|
|
||||||
|
|
||||||
bsfc = bsfc->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
|
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
|
||||||
ost->last_mux_dts != AV_NOPTS_VALUE &&
|
ost->last_mux_dts != AV_NOPTS_VALUE &&
|
||||||
pkt->dts < ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT)) {
|
pkt->dts < ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT)) {
|
||||||
@ -342,6 +314,49 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void output_packet(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* apply the output bitstream filters, if any */
|
||||||
|
if (ost->nb_bitstream_filters) {
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
ret = av_bsf_send_packet(ost->bsf_ctx[0], pkt);
|
||||||
|
if (ret < 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
idx = 1;
|
||||||
|
while (idx) {
|
||||||
|
/* get a packet from the previous filter up the chain */
|
||||||
|
ret = av_bsf_receive_packet(ost->bsf_ctx[idx - 1], pkt);
|
||||||
|
if (ret == AVERROR(EAGAIN)) {
|
||||||
|
ret = 0;
|
||||||
|
idx--;
|
||||||
|
continue;
|
||||||
|
} else if (ret < 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
/* send it to the next filter down the chain or to the muxer */
|
||||||
|
if (idx < ost->nb_bitstream_filters) {
|
||||||
|
ret = av_bsf_send_packet(ost->bsf_ctx[idx], pkt);
|
||||||
|
if (ret < 0)
|
||||||
|
goto finish;
|
||||||
|
idx++;
|
||||||
|
} else
|
||||||
|
write_packet(s, pkt, ost);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
write_packet(s, pkt, ost);
|
||||||
|
|
||||||
|
finish:
|
||||||
|
if (ret < 0 && ret != AVERROR_EOF) {
|
||||||
|
av_log(NULL, AV_LOG_FATAL, "Error applying bitstream filters to an output "
|
||||||
|
"packet for stream #%d:%d.\n", ost->file_index, ost->index);
|
||||||
|
exit_program(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int check_recording_time(OutputStream *ost)
|
static int check_recording_time(OutputStream *ost)
|
||||||
{
|
{
|
||||||
OutputFile *of = output_files[ost->file_index];
|
OutputFile *of = output_files[ost->file_index];
|
||||||
@ -380,7 +395,7 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost,
|
|||||||
|
|
||||||
if (got_packet) {
|
if (got_packet) {
|
||||||
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
|
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
|
||||||
write_frame(s, &pkt, ost);
|
output_packet(s, &pkt, ost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,7 +464,7 @@ static void do_subtitle_out(AVFormatContext *s,
|
|||||||
else
|
else
|
||||||
pkt.pts += 90 * sub->end_display_time;
|
pkt.pts += 90 * sub->end_display_time;
|
||||||
}
|
}
|
||||||
write_frame(s, &pkt, ost);
|
output_packet(s, &pkt, ost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +531,7 @@ static void do_video_out(AVFormatContext *s,
|
|||||||
|
|
||||||
if (got_packet) {
|
if (got_packet) {
|
||||||
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
|
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
|
||||||
write_frame(s, &pkt, ost);
|
output_packet(s, &pkt, ost);
|
||||||
*frame_size = pkt.size;
|
*frame_size = pkt.size;
|
||||||
|
|
||||||
/* if two pass, output log */
|
/* if two pass, output log */
|
||||||
@ -983,7 +998,7 @@ static void flush_encoders(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
|
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
|
||||||
write_frame(os, &pkt, ost);
|
output_packet(os, &pkt, ost);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stop_encoding)
|
if (stop_encoding)
|
||||||
@ -1076,7 +1091,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
|||||||
opkt.size = pkt->size;
|
opkt.size = pkt->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_frame(of->ctx, &opkt, ost);
|
output_packet(of->ctx, &opkt, ost);
|
||||||
}
|
}
|
||||||
|
|
||||||
int guess_input_channel_layout(InputStream *ist)
|
int guess_input_channel_layout(InputStream *ist)
|
||||||
@ -1554,6 +1569,51 @@ static InputStream *get_input_stream(OutputStream *ost)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int init_output_bsfs(OutputStream *ost)
|
||||||
|
{
|
||||||
|
AVBSFContext *ctx;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (!ost->nb_bitstream_filters)
|
||||||
|
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++) {
|
||||||
|
ret = av_bsf_alloc(ost->bitstream_filters[i], &ctx);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Error allocating a bistream filter context\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ost->bsf_ctx[i] = ctx;
|
||||||
|
|
||||||
|
ret = avcodec_parameters_copy(ctx->par_in,
|
||||||
|
i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ctx->time_base_in = i ? ost->bsf_ctx[i - 1]->time_base_out : ost->st->time_base;
|
||||||
|
|
||||||
|
ret = av_bsf_init(ctx);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Error initializing bistream filter: %s\n",
|
||||||
|
ost->bitstream_filters[i]->name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = ost->bsf_ctx[ost->nb_bitstream_filters - 1];
|
||||||
|
ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ost->st->time_base = ctx->time_base_out;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int init_output_stream(OutputStream *ost, char *error, int error_len)
|
static int init_output_stream(OutputStream *ost, char *error, int error_len)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -1648,6 +1708,13 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize bitstream filters for the output stream
|
||||||
|
* needs to be done here, because the codec id for streamcopy is not
|
||||||
|
* known until now */
|
||||||
|
ret = init_output_bsfs(ost);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
avconv.h
6
avconv.h
@ -325,7 +325,11 @@ typedef struct OutputStream {
|
|||||||
int64_t first_pts;
|
int64_t first_pts;
|
||||||
/* dts of the last packet sent to the muxer */
|
/* dts of the last packet sent to the muxer */
|
||||||
int64_t last_mux_dts;
|
int64_t last_mux_dts;
|
||||||
AVBitStreamFilterContext *bitstream_filters;
|
|
||||||
|
int nb_bitstream_filters;
|
||||||
|
const AVBitStreamFilter **bitstream_filters;
|
||||||
|
AVBSFContext **bsf_ctx;
|
||||||
|
|
||||||
AVCodecContext *enc_ctx;
|
AVCodecContext *enc_ctx;
|
||||||
AVCodec *enc;
|
AVCodec *enc;
|
||||||
int64_t max_frames;
|
int64_t max_frames;
|
||||||
|
22
avconv_opt.c
22
avconv_opt.c
@ -912,7 +912,6 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
|
|||||||
AVStream *st = avformat_new_stream(oc, NULL);
|
AVStream *st = avformat_new_stream(oc, NULL);
|
||||||
int idx = oc->nb_streams - 1, ret = 0;
|
int idx = oc->nb_streams - 1, ret = 0;
|
||||||
char *bsf = NULL, *next, *codec_tag = NULL;
|
char *bsf = NULL, *next, *codec_tag = NULL;
|
||||||
AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
|
|
||||||
double qscale = -1;
|
double qscale = -1;
|
||||||
|
|
||||||
if (!st) {
|
if (!st) {
|
||||||
@ -980,19 +979,26 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
|
|||||||
|
|
||||||
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
|
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
|
||||||
while (bsf) {
|
while (bsf) {
|
||||||
|
const AVBitStreamFilter *filter;
|
||||||
|
|
||||||
if (next = strchr(bsf, ','))
|
if (next = strchr(bsf, ','))
|
||||||
*next++ = 0;
|
*next++ = 0;
|
||||||
if (!(bsfc = av_bitstream_filter_init(bsf))) {
|
|
||||||
|
filter = av_bsf_get_by_name(bsf);
|
||||||
|
if (!bsf) {
|
||||||
av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
|
av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
|
||||||
exit_program(1);
|
exit_program(1);
|
||||||
}
|
}
|
||||||
if (bsfc_prev)
|
|
||||||
bsfc_prev->next = bsfc;
|
|
||||||
else
|
|
||||||
ost->bitstream_filters = bsfc;
|
|
||||||
|
|
||||||
bsfc_prev = bsfc;
|
ost->bitstream_filters = av_realloc_array(ost->bitstream_filters,
|
||||||
bsf = next;
|
ost->nb_bitstream_filters + 1,
|
||||||
|
sizeof(*ost->bitstream_filters));
|
||||||
|
if (!ost->bitstream_filters)
|
||||||
|
exit_program(1);
|
||||||
|
|
||||||
|
ost->bitstream_filters[ost->nb_bitstream_filters++] = filter;
|
||||||
|
|
||||||
|
bsf = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
|
MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
|
||||||
|
@ -1173,10 +1173,11 @@ int show_encoders(void *optctx, const char *opt, const char *arg)
|
|||||||
|
|
||||||
int show_bsfs(void *optctx, const char *opt, const char *arg)
|
int show_bsfs(void *optctx, const char *opt, const char *arg)
|
||||||
{
|
{
|
||||||
AVBitStreamFilter *bsf = NULL;
|
const AVBitStreamFilter *bsf = NULL;
|
||||||
|
void *opaque = NULL;
|
||||||
|
|
||||||
printf("Bitstream filters:\n");
|
printf("Bitstream filters:\n");
|
||||||
while ((bsf = av_bitstream_filter_next(bsf)))
|
while ((bsf = av_bsf_next(&opaque)))
|
||||||
printf("%s\n", bsf->name);
|
printf("%s\n", bsf->name);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user