diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2015-06-28 16:27:52 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2015-06-28 16:27:52 +0200 |
commit | 3943cdf18a0dcfe0f588f703c172c921e3ab99b9 (patch) | |
tree | 0129091a383ac5604b8e504a7776607b54983628 /ext/libav | |
parent | 3ca7c041b1cb15bbfc5c15a879c237e82c62fda0 (diff) |
avvidenc: Make sure to keep input data alive until libav is done with it
Diffstat (limited to 'ext/libav')
-rw-r--r-- | ext/libav/gstavvidenc.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/ext/libav/gstavvidenc.c b/ext/libav/gstavvidenc.c index 8c5d00f..1f46127 100644 --- a/ext/libav/gstavvidenc.c +++ b/ext/libav/gstavvidenc.c @@ -580,6 +580,22 @@ gst_ffmpegvidenc_free_avpacket (gpointer pkt) g_slice_free (AVPacket, pkt); } +typedef struct +{ + GstBuffer *buffer; + GstVideoFrame vframe; +} BufferInfo; + +static void +buffer_info_free (void *opaque, guint8 * data) +{ + BufferInfo *info = opaque; + + gst_video_frame_unmap (&info->vframe); + gst_buffer_unref (info->buffer); + g_slice_free (BufferInfo, info); +} + static GstFlowReturn gst_ffmpegvidenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame) @@ -588,24 +604,33 @@ gst_ffmpegvidenc_handle_frame (GstVideoEncoder * encoder, GstBuffer *outbuf; gint ret = 0, c; GstVideoInfo *info = &ffmpegenc->input_state->info; - GstVideoFrame vframe; AVPacket *pkt; int have_data = 0; + BufferInfo *buffer_info; if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)) ffmpegenc->picture->pict_type = AV_PICTURE_TYPE_I; - if (!gst_video_frame_map (&vframe, info, frame->input_buffer, GST_MAP_READ)) { + buffer_info = g_slice_new0 (BufferInfo); + buffer_info->buffer = gst_buffer_ref (frame->input_buffer); + + if (!gst_video_frame_map (&buffer_info->vframe, info, frame->input_buffer, + GST_MAP_READ)) { GST_ERROR_OBJECT (encoder, "Failed to map input buffer"); + gst_buffer_unref (buffer_info->buffer); + g_slice_free (BufferInfo, buffer_info); return GST_FLOW_ERROR; } /* Fill avpicture */ + ffmpegenc->picture->buf[0] = + av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0); for (c = 0; c < AV_NUM_DATA_POINTERS; c++) { if (c < GST_VIDEO_INFO_N_COMPONENTS (info)) { - ffmpegenc->picture->data[c] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, c); + ffmpegenc->picture->data[c] = + GST_VIDEO_FRAME_PLANE_DATA (&buffer_info->vframe, c); ffmpegenc->picture->linesize[c] = - GST_VIDEO_FRAME_COMP_STRIDE (&vframe, c); + GST_VIDEO_FRAME_COMP_STRIDE (&buffer_info->vframe, c); } else { ffmpegenc->picture->data[c] = NULL; ffmpegenc->picture->linesize[c] = 0; @@ -623,7 +648,7 @@ gst_ffmpegvidenc_handle_frame (GstVideoEncoder * encoder, avcodec_encode_video2 (ffmpegenc->context, pkt, ffmpegenc->picture, &have_data); - gst_video_frame_unmap (&vframe); + av_frame_unref (ffmpegenc->picture); if (ret < 0 || !have_data) g_slice_free (AVPacket, pkt); |