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 | 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 | 1300 | static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) |
| 1254 | 1301 | { |
| 1255 | 1302 | FFFormatContext *const si = ffformatcontext(s); |
| @@ -1286,8 +1333,10 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) · 30 unmodified lines | ||
| 1286 | 1333 | if (sti->need_context_update) { |
| 1287 | 1334 | if (avcodec_is_open(sti->avctx)) { |
| 1288 | 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 | 1337 | sti->info->found_decoder = 0; |
| 1338 | + if (ret < 0) | |
| 1339 | + return ret; | |
| 1291 | 1340 | } |
| 1292 | 1341 | |
| 1293 | 1342 | /* close parser, because it depends on the codec */ |
| @@ -3013,14 +3062,16 @@ find_stream_info_err: · 1719 unmodified lines | ||
| 3013 | 3062 | for (unsigned i = 0; i < ic->nb_streams; i++) { |
| 3014 | 3063 | AVStream *const st = ic->streams[i]; |
| 3015 | 3064 | FFStream *const sti = ffstream(st); |
| 3065 | + int err; | |
| 3066 | + | |
| 3016 | 3067 | if (sti->info) { |
| 3017 | 3068 | av_freep(&sti->info->duration_error); |
| 3018 | 3069 | av_freep(&sti->info); |
| 3019 | 3070 | } |
| 3020 | − avcodec_close(sti->avctx); | |
| 3021 | − // FIXME: avcodec_close() frees AVOption settable fields which includes ch_layout, | |
| 3022 | − // so we need to restore it. | |
| 3023 | − av_channel_layout_copy(&sti->avctx->ch_layout, &st->codecpar->ch_layout); | |
| 3071 | + | |
| 3072 | + err = codec_close(sti); | |
| 3073 | + if (err < 0 && ret >= 0) | |
| 3074 | + ret = err; | |
| 3024 | 3075 | av_bsf_free(&sti->extract_extradata.bsf); |
| 3025 | 3076 | } |
| 3026 | 3077 | if (ic->pb) { |