Replace it with recreating the codec context. This is the last remaining blocker for deprecating avcodec_close().
Unified · Split
| @@ -1250,6 +1250,53 @@ static int64_t ts_to_samples(AVStream *st, int64_t ts) · 1249 unmodified lines | |||
| 1250 | return av_rescale(ts, st->time_base.num * st->codecpar->sample_rate, st->time_base.den); | 1250 | return av_rescale(ts, st->time_base.num * st->codecpar->sample_rate, st->time_base.den); |
| 1251 | } | 1251 | } |
| 1252 | 1252 | ||
| 1253 | static int codec_close(FFStream *sti) | ||
| 1254 | { | ||
| 1255 | AVCodecContext *avctx_new = NULL; | ||
| 1256 | AVCodecParameters *par_tmp = NULL; | ||
| 1257 | int ret; | ||
| 1258 | |||
| 1259 | avctx_new = avcodec_alloc_context3(sti->avctx->codec); | ||
| 1260 | if (!avctx_new) { | ||
| 1261 | ret = AVERROR(ENOMEM); | ||
| 1262 | goto fail; | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | par_tmp = avcodec_parameters_alloc(); | ||
| 1266 | if (!par_tmp) { | ||
| 1267 | ret = AVERROR(ENOMEM); | ||
| 1268 | goto fail; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | ret = avcodec_parameters_from_context(par_tmp, sti->avctx); | ||
| 1272 | if (ret < 0) | ||
| 1273 | goto fail; | ||
| 1274 | |||
| 1275 | ret = avcodec_parameters_to_context(avctx_new, par_tmp); | ||
| 1276 | if (ret < 0) | ||
| 1277 | goto fail; | ||
| 1278 | |||
| 1279 | avctx_new->pkt_timebase = sti->avctx->pkt_timebase; | ||
| 1280 | |||
| 1281 | #if FF_API_TICKS_PER_FRAME | ||
| 1282 | FF_DISABLE_DEPRECATION_WARNINGS | ||
| 1283 | avctx_new->ticks_per_frame = sti->avctx->ticks_per_frame; | ||
| 1284 | FF_ENABLE_DEPRECATION_WARNINGS | ||
| 1285 | #endif | ||
| 1286 | |||
| 1287 | avcodec_free_context(&sti->avctx); | ||
| 1288 | sti->avctx = avctx_new; | ||
| 1289 | |||
| 1290 | avctx_new = NULL; | ||
| 1291 | ret = 0; | ||
| 1292 | |||
| 1293 | fail: | ||
| 1294 | avcodec_free_context(&avctx_new); | ||
| 1295 | avcodec_parameters_free(&par_tmp); | ||
| 1296 | |||
| 1297 | return ret; | ||
| 1298 | } | ||
| 1299 | |||
| 1253 | static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) | 1300 | static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) |
| 1254 | { | 1301 | { |
| 1255 | FFFormatContext *const si = ffformatcontext(s); | 1302 | FFFormatContext *const si = ffformatcontext(s); |
| @@ -1286,8 +1333,10 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) · 30 unmodified lines | |||
| 1286 | if (sti->need_context_update) { | 1333 | if (sti->need_context_update) { |
| 1287 | if (avcodec_is_open(sti->avctx)) { | 1334 | if (avcodec_is_open(sti->avctx)) { |
| 1288 | av_log(s, AV_LOG_DEBUG, "Demuxer context update while decoder is open, closing and trying to re-open\n"); | 1335 | av_log(s, AV_LOG_DEBUG, "Demuxer context update while decoder is open, closing and trying to re-open\n"); |
| 1289 | avcodec_close(sti->avctx); | 1336 | ret = codec_close(sti); |
| 1290 | sti->info->found_decoder = 0; | 1337 | sti->info->found_decoder = 0; |
| 1338 | if (ret < 0) | ||
| 1339 | return ret; | ||
| 1291 | } | 1340 | } |
| 1292 | 1341 | ||
| 1293 | /* close parser, because it depends on the codec */ | 1342 | /* close parser, because it depends on the codec */ |
| @@ -3013,14 +3062,16 @@ find_stream_info_err: · 1719 unmodified lines | |||
| 3013 | for (unsigned i = 0; i < ic->nb_streams; i++) { | 3062 | for (unsigned i = 0; i < ic->nb_streams; i++) { |
| 3014 | AVStream *const st = ic->streams[i]; | 3063 | AVStream *const st = ic->streams[i]; |
| 3015 | FFStream *const sti = ffstream(st); | 3064 | FFStream *const sti = ffstream(st); |
| 3065 | int err; | ||
| 3066 | |||
| 3016 | if (sti->info) { | 3067 | if (sti->info) { |
| 3017 | av_freep(&sti->info->duration_error); | 3068 | av_freep(&sti->info->duration_error); |
| 3018 | av_freep(&sti->info); | 3069 | av_freep(&sti->info); |
| 3019 | } | 3070 | } |
| 3020 | avcodec_close(sti->avctx); | 3071 | |
| 3021 | // FIXME: avcodec_close() frees AVOption settable fields which includes ch_layout, | 3072 | err = codec_close(sti); |
| 3022 | // so we need to restore it. | 3073 | if (err < 0 && ret >= 0) |
| 3023 | av_channel_layout_copy(&sti->avctx->ch_layout, &st->codecpar->ch_layout); | 3074 | ret = err; |
| 3024 | av_bsf_free(&sti->extract_extradata.bsf); | 3075 | av_bsf_free(&sti->extract_extradata.bsf); |
| 3025 | } | 3076 | } |
| 3026 | if (ic->pb) { | 3077 | if (ic->pb) { |