Commit 0e72ad95 authored by Anton Khirnov's avatar Anton Khirnov

lavc: make avcodec_close() work properly on unopened codecs.

I.e. free the priv_data and other stuff allocated in
avcodec_alloc_context3() and not segfault.
parent af08d9ae
...@@ -3417,7 +3417,8 @@ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec); ...@@ -3417,7 +3417,8 @@ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec);
/** /**
* Allocate an AVCodecContext and set its fields to default values. The * Allocate an AVCodecContext and set its fields to default values. The
* resulting struct can be deallocated by simply calling av_free(). * resulting struct can be deallocated by calling avcodec_close() on it followed
* by av_free().
* *
* @param codec if non-NULL, allocate private data and initialize defaults * @param codec if non-NULL, allocate private data and initialize defaults
* for the given codec. It is illegal to then call avcodec_open2() * for the given codec. It is illegal to then call avcodec_open2()
...@@ -3809,6 +3810,15 @@ int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, ...@@ -3809,6 +3810,15 @@ int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
const AVSubtitle *sub); const AVSubtitle *sub);
/**
* Close a given AVCodecContext and free all the data associated with it
* (but not the AVCodecContext itself).
*
* Calling this function on an AVCodecContext that hasn't been opened will free
* the codec-specific data allocated in avcodec_alloc_context3() /
* avcodec_get_context_defaults3() with a non-NULL codec. Subsequent calls will
* do nothing.
*/
int avcodec_close(AVCodecContext *avctx); int avcodec_close(AVCodecContext *avctx);
/** /**
......
...@@ -1267,14 +1267,17 @@ av_cold int avcodec_close(AVCodecContext *avctx) ...@@ -1267,14 +1267,17 @@ av_cold int avcodec_close(AVCodecContext *avctx)
return -1; return -1;
} }
if (HAVE_THREADS && avctx->thread_opaque) if (avcodec_is_open(avctx)) {
ff_thread_free(avctx); if (HAVE_THREADS && avctx->thread_opaque)
if (avctx->codec && avctx->codec->close) ff_thread_free(avctx);
avctx->codec->close(avctx); if (avctx->codec && avctx->codec->close)
avcodec_default_free_buffers(avctx); avctx->codec->close(avctx);
avctx->coded_frame = NULL; avcodec_default_free_buffers(avctx);
av_freep(&avctx->internal); avctx->coded_frame = NULL;
if (avctx->codec && avctx->codec->priv_class) av_freep(&avctx->internal);
}
if (avctx->priv_data && avctx->codec && avctx->codec->priv_class)
av_opt_free(avctx->priv_data); av_opt_free(avctx->priv_data);
av_opt_free(avctx); av_opt_free(avctx);
av_freep(&avctx->priv_data); av_freep(&avctx->priv_data);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment