osxvideosink: fix segfault when dealing with padded frames

Fixes crashes with vtdec ! osxvideosink where VideoToolbox outputs padded UYVY
This commit is contained in:
Alessandro Decina 2013-12-08 16:49:55 +01:00
parent f3c3dee148
commit fdf8ac40d8
2 changed files with 38 additions and 19 deletions

View file

@ -687,9 +687,6 @@ const gchar* gst_keycode_to_keyname(gint16 keycode)
width = w; width = w;
height = h; height = h;
// if (data) g_free(data);
// data = g_malloc0 (2 * w * h);
[self initTextures]; [self initTextures];
[self reshape]; [self reshape];
} }

View file

@ -39,6 +39,7 @@
#include "config.h" #include "config.h"
#include <gst/video/videooverlay.h> #include <gst/video/videooverlay.h>
#include <gst/video/navigation.h> #include <gst/video/navigation.h>
#include <gst/video/video.h>
#include "osxvideosink.h" #include "osxvideosink.h"
#include <unistd.h> #include <unistd.h>
@ -49,7 +50,7 @@ GST_DEBUG_CATEGORY (gst_debug_osx_video_sink);
#ifdef RUN_NS_APP_THREAD #ifdef RUN_NS_APP_THREAD
#include <pthread.h> #include <pthread.h>
extern void _CFRunLoopSetCurrent(CFRunLoopRef rl); extern void _CFRunLoopSetCurrent (CFRunLoopRef rl);
extern pthread_t _CFMainPThread; extern pthread_t _CFMainPThread;
#endif #endif
@ -357,7 +358,7 @@ gst_osx_video_sink_osxwindow_resize (GstOSXVideoSink * osxvideosink,
/* Directly resize the underlying view */ /* Directly resize the underlying view */
GST_DEBUG_OBJECT (osxvideosink, "Calling setVideoSize on %p", osxwindow->gstview); GST_DEBUG_OBJECT (osxvideosink, "Calling setVideoSize on %p", osxwindow->gstview);
gst_osx_video_sink_call_from_main_thread(osxvideosink, object, gst_osx_video_sink_call_from_main_thread (osxvideosink, object,
@selector(resize), (id)nil, YES); @selector(resize), (id)nil, YES);
[pool release]; [pool release];
@ -899,29 +900,50 @@ gst_osx_video_sink_get_type (void)
- (void) showFrame: (GstBufferObject *) object - (void) showFrame: (GstBufferObject *) object
{ {
GstMapInfo info; GstMapInfo info;
guint8 *viewdata; GstVideoMeta *vmeta;
guint8 *data, *readp, *writep;
gint i, active_width, stride;
guint8 *texture_buffer;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GstBuffer *buf = object->buf; GstBuffer *buf = object->buf;
GST_OBJECT_LOCK (osxvideosink); GST_OBJECT_LOCK (osxvideosink);
if (osxvideosink->osxwindow != NULL) if (osxvideosink->osxwindow == NULL)
{ goto no_window;
gst_buffer_map (buf, &info, GST_MAP_READ);
viewdata = (guint8 *) [osxvideosink->osxwindow->gstview getTextureBuffer]; texture_buffer = (guint8 *) [osxvideosink->osxwindow->gstview getTextureBuffer];
if (G_UNLIKELY (texture_buffer == NULL))
if (G_UNLIKELY (viewdata == NULL)) { goto no_texture_buffer;
GST_ELEMENT_ERROR (osxvideosink, RESOURCE, WRITE,
("Could not get a texture buffer"), (NULL)); vmeta = (GstVideoMeta *) gst_buffer_get_meta (buf, GST_VIDEO_META_API_TYPE);
} else { gst_video_meta_map (vmeta, 0, &info, (gpointer *) &data, &stride, GST_MAP_READ);
memcpy (viewdata, info.data, info.size); readp = data;
[osxvideosink->osxwindow->gstview displayTexture]; writep = texture_buffer;
gst_buffer_unmap (buf, &info); active_width = GST_VIDEO_SINK_WIDTH (osxvideosink) * sizeof (short);
} for (i = 0; i < GST_VIDEO_SINK_HEIGHT (osxvideosink); i++) {
memcpy (writep, readp, active_width);
writep += active_width;
readp += stride;
} }
[osxvideosink->osxwindow->gstview displayTexture];
gst_video_meta_unmap (vmeta, 0, &info);
out:
GST_OBJECT_UNLOCK (osxvideosink); GST_OBJECT_UNLOCK (osxvideosink);
[object release]; [object release];
[pool release]; [pool release];
return;
no_window:
GST_WARNING_OBJECT (osxvideosink, "not showing frame since we have no window (!?)");
goto out;
no_texture_buffer:
GST_ELEMENT_ERROR (osxvideosink, RESOURCE, WRITE, (NULL),
("the texture buffer is NULL"));
goto out;
} }
-(void) destroy -(void) destroy