Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Thompson <sw@jkqxz.net>2018-01-10 01:56:41 +0300
committerMark Thompson <sw@jkqxz.net>2018-01-21 03:37:35 +0300
commita0c624e299730c8c5800375c2f5f3c6c200053ff (patch)
tree6a7b9312d0b25d9a65d160d62165675d4985bdfb /libavcodec/v4l2_m2m_enc.c
parent6c1c6c6c71fc776c6dd25d13861b036dad2cdc1b (diff)
avcodec: v4l2_m2m: fix races around freeing data on close
Refcount all of the context information. This also fixes a potential segmentation fault when accessing freed memory (buffer returned after the codec has been closed). Tested-by: Jorge Ramirez-Ortiz <jorge.ramirez.ortiz@gmail.com>
Diffstat (limited to 'libavcodec/v4l2_m2m_enc.c')
-rw-r--r--libavcodec/v4l2_m2m_enc.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c
index 7e88f4d2e6..4c9ea1fd92 100644
--- a/libavcodec/v4l2_m2m_enc.c
+++ b/libavcodec/v4l2_m2m_enc.c
@@ -242,7 +242,7 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s)
static int v4l2_send_frame(AVCodecContext *avctx, const AVFrame *frame)
{
- V4L2m2mContext *s = avctx->priv_data;
+ V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
V4L2Context *const output = &s->output;
return ff_v4l2_context_enqueue_frame(output, frame);
@@ -250,7 +250,7 @@ static int v4l2_send_frame(AVCodecContext *avctx, const AVFrame *frame)
static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
{
- V4L2m2mContext *s = avctx->priv_data;
+ V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
V4L2Context *const capture = &s->capture;
V4L2Context *const output = &s->output;
int ret;
@@ -280,11 +280,17 @@ dequeue:
static av_cold int v4l2_encode_init(AVCodecContext *avctx)
{
- V4L2m2mContext *s = avctx->priv_data;
- V4L2Context *capture = &s->capture;
- V4L2Context *output = &s->output;
+ V4L2Context *capture, *output;
+ V4L2m2mContext *s;
int ret;
+ ret = ff_v4l2_m2m_create_context(avctx, &s);
+ if (ret < 0)
+ return ret;
+
+ capture = &s->capture;
+ output = &s->output;
+
/* common settings output/capture */
output->height = capture->height = avctx->height;
output->width = capture->width = avctx->width;
@@ -306,13 +312,13 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx)
return v4l2_prepare_encoder(s);
}
-#define OFFSET(x) offsetof(V4L2m2mContext, x)
+#define OFFSET(x) offsetof(V4L2m2mPriv, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
V4L_M2M_DEFAULT_OPTS,
{ "num_capture_buffers", "Number of buffers in the capture context",
- OFFSET(capture.num_buffers), AV_OPT_TYPE_INT, {.i64 = 4 }, 4, INT_MAX, FLAGS },
+ OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 4 }, 4, INT_MAX, FLAGS },
{ NULL },
};
@@ -329,7 +335,7 @@ AVCodec ff_ ## NAME ## _v4l2m2m_encoder = { \
.long_name = NULL_IF_CONFIG_SMALL("V4L2 mem2mem " LONGNAME " encoder wrapper"),\
.type = AVMEDIA_TYPE_VIDEO,\
.id = CODEC ,\
- .priv_data_size = sizeof(V4L2m2mContext),\
+ .priv_data_size = sizeof(V4L2m2mPriv),\
.priv_class = &v4l2_m2m_ ## NAME ##_enc_class,\
.init = v4l2_encode_init,\
.send_frame = v4l2_send_frame,\