1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-10 06:10:52 +02:00

fftools/ffmpeg: move init_output_stream_streamcopy() to ffmpeg_mux_init

Everything in it can be done immediately when creating the output
stream, there is no reason to postpone it.
This commit is contained in:
Anton Khirnov
2023-04-10 15:10:34 +02:00
parent 9bae55165d
commit 12f3f41bbf
2 changed files with 143 additions and 136 deletions

View File

@@ -1985,136 +1985,6 @@ static int init_input_stream(InputStream *ist, char *error, int error_len)
return 0;
}
static int init_output_stream_streamcopy(OutputStream *ost)
{
OutputFile *of = output_files[ost->file_index];
InputStream *ist = ost->ist;
InputFile *ifile = input_files[ist->file_index];
AVCodecParameters *par = ost->st->codecpar;
AVCodecContext *codec_ctx;
AVRational sar;
int i, ret;
uint32_t codec_tag = par->codec_tag;
av_assert0(ist && !ost->filter);
codec_ctx = avcodec_alloc_context3(NULL);
if (!codec_ctx)
return AVERROR(ENOMEM);
ret = avcodec_parameters_to_context(codec_ctx, ist->par);
if (ret >= 0)
ret = av_opt_set_dict(codec_ctx, &ost->encoder_opts);
if (ret < 0) {
av_log(ost, AV_LOG_FATAL,
"Error setting up codec context options.\n");
avcodec_free_context(&codec_ctx);
return ret;
}
ret = avcodec_parameters_from_context(par, codec_ctx);
avcodec_free_context(&codec_ctx);
if (ret < 0) {
av_log(ost, AV_LOG_FATAL,
"Error getting reference codec parameters.\n");
return ret;
}
if (!codec_tag) {
unsigned int codec_tag_tmp;
if (!of->format->codec_tag ||
av_codec_get_id (of->format->codec_tag, par->codec_tag) == par->codec_id ||
!av_codec_get_tag2(of->format->codec_tag, par->codec_id, &codec_tag_tmp))
codec_tag = par->codec_tag;
}
par->codec_tag = codec_tag;
if (!ost->frame_rate.num)
ost->frame_rate = ist->framerate;
if (ost->frame_rate.num)
ost->st->avg_frame_rate = ost->frame_rate;
else
ost->st->avg_frame_rate = ist->st->avg_frame_rate;
ret = avformat_transfer_internal_stream_timing_info(of->format, ost->st, ist->st, copy_tb);
if (ret < 0)
return ret;
// copy timebase while removing common factors
if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) {
if (ost->frame_rate.num)
ost->st->time_base = av_inv_q(ost->frame_rate);
else
ost->st->time_base = av_add_q(av_stream_get_codec_timebase(ost->st), (AVRational){0, 1});
}
// copy estimated duration as a hint to the muxer
if (ost->st->duration <= 0 && ist->st->duration > 0)
ost->st->duration = av_rescale_q(ist->st->duration, ist->st->time_base, ost->st->time_base);
if (!ost->copy_prior_start) {
ost->ts_copy_start = (of->start_time == AV_NOPTS_VALUE) ?
0 : of->start_time;
if (copy_ts && ifile->start_time != AV_NOPTS_VALUE) {
ost->ts_copy_start = FFMAX(ost->ts_copy_start,
ifile->start_time + ifile->ts_offset);
}
}
if (ist->st->nb_side_data) {
for (i = 0; i < ist->st->nb_side_data; i++) {
const AVPacketSideData *sd_src = &ist->st->side_data[i];
uint8_t *dst_data;
dst_data = av_stream_new_side_data(ost->st, sd_src->type, sd_src->size);
if (!dst_data)
return AVERROR(ENOMEM);
memcpy(dst_data, sd_src->data, sd_src->size);
}
}
#if FFMPEG_ROTATION_METADATA
if (ost->rotate_overridden) {
uint8_t *sd = av_stream_new_side_data(ost->st, AV_PKT_DATA_DISPLAYMATRIX,
sizeof(int32_t) * 9);
if (sd)
av_display_rotation_set((int32_t *)sd, -ost->rotate_override_value);
}
#endif
switch (par->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if ((par->block_align == 1 || par->block_align == 1152 || par->block_align == 576) &&
par->codec_id == AV_CODEC_ID_MP3)
par->block_align = 0;
if (par->codec_id == AV_CODEC_ID_AC3)
par->block_align = 0;
break;
case AVMEDIA_TYPE_VIDEO:
if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
sar =
av_mul_q(ost->frame_aspect_ratio,
(AVRational){ par->height, par->width });
av_log(ost, AV_LOG_WARNING, "Overriding aspect ratio "
"with stream copy may produce invalid files\n");
}
else if (ist->st->sample_aspect_ratio.num)
sar = ist->st->sample_aspect_ratio;
else
sar = par->sample_aspect_ratio;
ost->st->sample_aspect_ratio = par->sample_aspect_ratio = sar;
ost->st->avg_frame_rate = ist->st->avg_frame_rate;
ost->st->r_frame_rate = ist->st->r_frame_rate;
break;
}
ost->mux_timebase = ist->st->time_base;
return 0;
}
static int init_output_stream_nofilter(OutputStream *ost)
{
int ret = 0;
@@ -2124,12 +1994,6 @@ static int init_output_stream_nofilter(OutputStream *ost)
if (ret < 0)
return ret;
} else {
if (ost->ist) {
ret = init_output_stream_streamcopy(ost);
if (ret < 0)
return ret;
}
ret = of_stream_init(output_files[ost->file_index], ost);
if (ret < 0)
return ret;

View File

@@ -37,6 +37,7 @@
#include "libavutil/avutil.h"
#include "libavutil/bprint.h"
#include "libavutil/dict.h"
#include "libavutil/display.h"
#include "libavutil/getenv_utf8.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
@@ -839,6 +840,142 @@ static void new_stream_subtitle(Muxer *mux, const OptionsContext *o,
}
}
static int streamcopy_init(const Muxer *mux, const OptionsContext *o,
OutputStream *ost)
{
const InputStream *ist = ost->ist;
const InputFile *ifile = input_files[ist->file_index];
AVCodecParameters *par = ost->st->codecpar;
uint32_t codec_tag = par->codec_tag;
AVCodecContext *codec_ctx = NULL;
AVDictionary *codec_opts = NULL;
int ret = 0;
codec_ctx = avcodec_alloc_context3(NULL);
if (!codec_ctx)
return AVERROR(ENOMEM);
ret = avcodec_parameters_to_context(codec_ctx, ist->par);
if (ret >= 0)
ret = av_opt_set_dict(codec_ctx, &ost->encoder_opts);
if (ret < 0) {
av_log(ost, AV_LOG_FATAL,
"Error setting up codec context options.\n");
goto fail;
}
ret = avcodec_parameters_from_context(par, codec_ctx);
if (ret < 0) {
av_log(ost, AV_LOG_FATAL,
"Error getting reference codec parameters.\n");
goto fail;
}
if (!codec_tag) {
const struct AVCodecTag * const *ct = mux->fc->oformat->codec_tag;
unsigned int codec_tag_tmp;
if (!ct || av_codec_get_id (ct, par->codec_tag) == par->codec_id ||
!av_codec_get_tag2(ct, par->codec_id, &codec_tag_tmp))
codec_tag = par->codec_tag;
}
par->codec_tag = codec_tag;
if (!ost->frame_rate.num)
ost->frame_rate = ist->framerate;
if (ost->frame_rate.num)
ost->st->avg_frame_rate = ost->frame_rate;
else
ost->st->avg_frame_rate = ist->st->avg_frame_rate;
ret = avformat_transfer_internal_stream_timing_info(mux->fc->oformat,
ost->st, ist->st, copy_tb);
if (ret < 0)
goto fail;
// copy timebase while removing common factors
if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) {
if (ost->frame_rate.num)
ost->st->time_base = av_inv_q(ost->frame_rate);
else
ost->st->time_base = av_add_q(av_stream_get_codec_timebase(ost->st), (AVRational){0, 1});
}
// copy estimated duration as a hint to the muxer
if (ost->st->duration <= 0 && ist->st->duration > 0)
ost->st->duration = av_rescale_q(ist->st->duration, ist->st->time_base, ost->st->time_base);
if (!ost->copy_prior_start) {
ost->ts_copy_start = (mux->of.start_time == AV_NOPTS_VALUE) ?
0 : mux->of.start_time;
if (copy_ts && ifile->start_time != AV_NOPTS_VALUE) {
ost->ts_copy_start = FFMAX(ost->ts_copy_start,
ifile->start_time + ifile->ts_offset);
}
}
if (ist->st->nb_side_data) {
for (int i = 0; i < ist->st->nb_side_data; i++) {
const AVPacketSideData *sd_src = &ist->st->side_data[i];
uint8_t *dst_data;
dst_data = av_stream_new_side_data(ost->st, sd_src->type, sd_src->size);
if (!dst_data) {
ret = AVERROR(ENOMEM);
goto fail;
}
memcpy(dst_data, sd_src->data, sd_src->size);
}
}
#if FFMPEG_ROTATION_METADATA
if (ost->rotate_overridden) {
uint8_t *sd = av_stream_new_side_data(ost->st, AV_PKT_DATA_DISPLAYMATRIX,
sizeof(int32_t) * 9);
if (sd)
av_display_rotation_set((int32_t *)sd, -ost->rotate_override_value);
}
#endif
switch (par->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if ((par->block_align == 1 || par->block_align == 1152 || par->block_align == 576) &&
par->codec_id == AV_CODEC_ID_MP3)
par->block_align = 0;
if (par->codec_id == AV_CODEC_ID_AC3)
par->block_align = 0;
break;
case AVMEDIA_TYPE_VIDEO: {
AVRational sar;
if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
sar =
av_mul_q(ost->frame_aspect_ratio,
(AVRational){ par->height, par->width });
av_log(ost, AV_LOG_WARNING, "Overriding aspect ratio "
"with stream copy may produce invalid files\n");
}
else if (ist->st->sample_aspect_ratio.num)
sar = ist->st->sample_aspect_ratio;
else
sar = par->sample_aspect_ratio;
ost->st->sample_aspect_ratio = par->sample_aspect_ratio = sar;
ost->st->avg_frame_rate = ist->st->avg_frame_rate;
ost->st->r_frame_rate = ist->st->r_frame_rate;
break;
}
}
ost->mux_timebase = ist->st->time_base;
fail:
avcodec_free_context(&codec_ctx);
av_dict_free(&codec_opts);
return ret;
}
static OutputStream *ost_add(Muxer *mux, const OptionsContext *o,
enum AVMediaType type, InputStream *ist)
{
@@ -1089,6 +1226,12 @@ static OutputStream *ost_add(Muxer *mux, const OptionsContext *o,
default: new_stream_unknown (mux, o, ost); break;
}
if (ost->ist && !ost->enc) {
ret = streamcopy_init(mux, o, ost);
if (ret < 0)
exit_program(1);
}
return ost;
}