+2008-08-01 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
+
+ * ext/ffmpeg/gstffmpegcfg.c: (gst_ffmpeg_cfg_fill_context):
+ * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_getcaps):
+ Latest ffmpeg revision's avcodec_close frees more; use safer coding to
+ prevent double free and other related segfaults.
+
2008-07-28 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_caps_to_pixfmt):
context_offset = qdata->offset - CONTEXT_CONFIG_OFFSET;
if (gst_ffmpeg_cfg_codec_has_pspec (klass->in_plugin->id, pspec)
&& context_offset >= 0) {
- /* memcpy a bit heavy for a small copy, but hardly part of 'inner loop' */
- memcpy (G_STRUCT_MEMBER_P (context, context_offset),
- G_STRUCT_MEMBER_P (ffmpegenc, qdata->offset), qdata->size);
+ if (G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_STRING) {
+ /* make a copy for ffmpeg, it will likely free only some,
+ * but in any case safer than a potential double free */
+ G_STRUCT_MEMBER (gchar *, context, context_offset) =
+ g_strdup (G_STRUCT_MEMBER (gchar *, ffmpegenc, qdata->offset));
+ } else {
+ /* memcpy a bit heavy for a small copy,
+ * but hardly part of 'inner loop' */
+ memcpy (G_STRUCT_MEMBER_P (context, context_offset),
+ G_STRUCT_MEMBER_P (ffmpegenc, qdata->offset), qdata->size);
+ }
}
list = list->next;
}
GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) GST_PAD_PARENT (pad);
GstFFMpegEncClass *oclass =
(GstFFMpegEncClass *) G_OBJECT_GET_CLASS (ffmpegenc);
- AVCodecContext *ctx;
+ AVCodecContext *ctx = NULL;
enum PixelFormat pixfmt;
GstCaps *caps = NULL;
}
/* create cache etc. */
- ctx = avcodec_alloc_context ();
- if (!ctx) {
- caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
- GST_DEBUG_OBJECT (ffmpegenc, "no context, return template caps %"GST_PTR_FORMAT, caps);
- return caps;
- }
-
- /* set some default properties */
- ctx->width = DEFAULT_WIDTH;
- ctx->height = DEFAULT_HEIGHT;
- ctx->time_base.num = DEFAULT_FRAME_RATE_BASE;
- ctx->time_base.den = 25 * DEFAULT_FRAME_RATE_BASE;
- ctx->bit_rate = DEFAULT_VIDEO_BITRATE;
- /* makes it silent */
- ctx->strict_std_compliance = -1;
/* shut up the logging while we autoprobe; we don't want warnings and
* errors about unsupported formats */
for (pixfmt = 0; pixfmt < PIX_FMT_NB; pixfmt++) {
GstCaps *tmpcaps;
+ /* need to start with a fresh codec_context each time around, since
+ * codec_close may have released stuff causing the next pass to segfault */
+ ctx = avcodec_alloc_context ();
+ if (!ctx) {
+ GST_DEBUG_OBJECT (ffmpegenc, "no context");
+ break;
+ }
+
+ /* set some default properties */
+ ctx->width = DEFAULT_WIDTH;
+ ctx->height = DEFAULT_HEIGHT;
+ ctx->time_base.num = DEFAULT_FRAME_RATE_BASE;
+ ctx->time_base.den = 25 * DEFAULT_FRAME_RATE_BASE;
+ ctx->bit_rate = DEFAULT_VIDEO_BITRATE;
+ /* makes it silent */
+ ctx->strict_std_compliance = -1;
+
ctx->pix_fmt = pixfmt;
if (gst_ffmpeg_avcodec_open (ctx, oclass->in_plugin) >= 0 &&
ctx->pix_fmt == pixfmt) {
}
if (ctx->priv_data)
gst_ffmpeg_avcodec_close (ctx);
+ av_free (ctx);
}
- av_free (ctx);
#ifndef GST_DISABLE_GST_DEBUG
_shut_up_I_am_probing = FALSE;
#endif
/* make sure we have something */
if (!caps) {
caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
- GST_DEBUG_OBJECT (ffmpegenc, "probing gave nothing, return template %"GST_PTR_FORMAT, caps);
+ GST_DEBUG_OBJECT (ffmpegenc, "probing gave nothing, "
+ "return template %" GST_PTR_FORMAT, caps);
return caps;
}