vtenc: Use correct strides, etc from the GstVideoFrame
https://bugzilla.gnome.org/show_bug.cgi?id=706211
This commit is contained in:
parent
e943f56bf8
commit
24c79af394
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010, 2013 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
* Copyright (C) 2010, 2013 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||||
|
* Copyright (C) 2013 Intel Corporation
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -45,7 +46,7 @@ typedef struct _GstVTEncFrame GstVTEncFrame;
|
|||||||
struct _GstVTEncFrame
|
struct _GstVTEncFrame
|
||||||
{
|
{
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstMapInfo map;
|
GstVideoFrame videoframe;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
@ -94,7 +95,8 @@ static VTStatus gst_vtenc_enqueue_buffer (void *data, int a2, int a3, int a4,
|
|||||||
static gboolean gst_vtenc_buffer_is_keyframe (GstVTEnc * self,
|
static gboolean gst_vtenc_buffer_is_keyframe (GstVTEnc * self,
|
||||||
CMSampleBufferRef sbuf);
|
CMSampleBufferRef sbuf);
|
||||||
|
|
||||||
static GstVTEncFrame *gst_vtenc_frame_new (GstBuffer * buf);
|
static GstVTEncFrame *gst_vtenc_frame_new (GstBuffer * buf,
|
||||||
|
GstVideoInfo * videoinfo);
|
||||||
static void gst_vtenc_frame_free (GstVTEncFrame * frame);
|
static void gst_vtenc_frame_free (GstVTEncFrame * frame);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -116,7 +118,7 @@ gst_vtenc_base_init (GstVTEncClass * klass)
|
|||||||
|
|
||||||
gst_element_class_set_metadata (element_class, longname,
|
gst_element_class_set_metadata (element_class, longname,
|
||||||
"Codec/Encoder/Video", description,
|
"Codec/Encoder/Video", description,
|
||||||
"Ole André Vadla Ravnås <oleavr@soundrop.com>");
|
"Ole André Vadla Ravnås <oleavr@soundrop.com>, Dominik Röttsches <dominik.rottsches@intel.com>");
|
||||||
|
|
||||||
g_free (longname);
|
g_free (longname);
|
||||||
g_free (description);
|
g_free (description);
|
||||||
@ -197,6 +199,8 @@ gst_vtenc_init (GstVTEnc * self)
|
|||||||
/* These could be controlled by properties later */
|
/* These could be controlled by properties later */
|
||||||
self->dump_properties = FALSE;
|
self->dump_properties = FALSE;
|
||||||
self->dump_attributes = FALSE;
|
self->dump_attributes = FALSE;
|
||||||
|
|
||||||
|
self->session = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
@ -377,6 +381,9 @@ gst_vtenc_sink_setcaps (GstVTEnc * self, GstCaps * caps)
|
|||||||
gst_structure_get_fraction (structure, "framerate",
|
gst_structure_get_fraction (structure, "framerate",
|
||||||
&self->negotiated_fps_n, &self->negotiated_fps_d);
|
&self->negotiated_fps_n, &self->negotiated_fps_d);
|
||||||
|
|
||||||
|
if (!gst_video_info_from_caps (&self->video_info, caps))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
gst_vtenc_destroy_session (self, &self->session);
|
gst_vtenc_destroy_session (self, &self->session);
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (self);
|
GST_OBJECT_UNLOCK (self);
|
||||||
@ -760,8 +767,7 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
|||||||
|
|
||||||
self->cur_inbuf = buf;
|
self->cur_inbuf = buf;
|
||||||
|
|
||||||
ts = CMTimeMake
|
ts = CMTimeMake (GST_TIME_AS_MSECONDS (GST_BUFFER_TIMESTAMP (buf)), 1000);
|
||||||
(GST_TIME_AS_MSECONDS (GST_BUFFER_TIMESTAMP (buf)), 1000);
|
|
||||||
duration = CMTimeMake
|
duration = CMTimeMake
|
||||||
(GST_TIME_AS_MSECONDS (GST_BUFFER_DURATION (buf)), 1000);
|
(GST_TIME_AS_MSECONDS (GST_BUFFER_DURATION (buf)), 1000);
|
||||||
|
|
||||||
@ -774,16 +780,45 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
|||||||
GstVTEncFrame *frame;
|
GstVTEncFrame *frame;
|
||||||
CVReturn cv_ret;
|
CVReturn cv_ret;
|
||||||
|
|
||||||
frame = gst_vtenc_frame_new (buf);
|
frame = gst_vtenc_frame_new (buf, &self->video_info);
|
||||||
cv_ret = CVPixelBufferCreateWithBytes (NULL,
|
if (!frame)
|
||||||
self->negotiated_width, self->negotiated_height,
|
|
||||||
kCVPixelFormatType_422YpCbCr8, frame->map.data,
|
|
||||||
self->negotiated_width * 2,
|
|
||||||
(CVPixelBufferReleaseBytesCallback) gst_vtenc_frame_free, frame,
|
|
||||||
NULL, &pbuf);
|
|
||||||
if (cv_ret != kCVReturnSuccess) {
|
|
||||||
gst_vtenc_frame_free (frame);
|
|
||||||
goto cv_error;
|
goto cv_error;
|
||||||
|
|
||||||
|
{
|
||||||
|
const size_t num_planes = GST_VIDEO_FRAME_N_PLANES (&frame->videoframe);
|
||||||
|
void *plane_base_addresses[num_planes];
|
||||||
|
size_t plane_widths[num_planes];
|
||||||
|
size_t plane_heights[num_planes];
|
||||||
|
size_t plane_bytes_per_row[num_planes];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_planes; i++) {
|
||||||
|
plane_base_addresses[i] =
|
||||||
|
GST_VIDEO_FRAME_PLANE_DATA (&frame->videoframe, i);
|
||||||
|
plane_widths[i] = GST_VIDEO_FRAME_COMP_WIDTH (&frame->videoframe, i);
|
||||||
|
plane_heights[i] = GST_VIDEO_FRAME_COMP_HEIGHT (&frame->videoframe, i);
|
||||||
|
plane_bytes_per_row[i] =
|
||||||
|
GST_VIDEO_FRAME_COMP_STRIDE (&frame->videoframe, i);
|
||||||
|
plane_bytes_per_row[i] =
|
||||||
|
GST_VIDEO_FRAME_COMP_STRIDE (&frame->videoframe, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv_ret = CVPixelBufferCreateWithPlanarBytes (NULL,
|
||||||
|
self->negotiated_width, self->negotiated_height,
|
||||||
|
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
|
||||||
|
NULL,
|
||||||
|
GST_VIDEO_FRAME_SIZE (&frame->videoframe),
|
||||||
|
num_planes,
|
||||||
|
plane_base_addresses,
|
||||||
|
plane_widths,
|
||||||
|
plane_heights,
|
||||||
|
plane_bytes_per_row,
|
||||||
|
(CVPixelBufferReleaseBytesCallback) gst_vtenc_frame_free, frame,
|
||||||
|
NULL, &pbuf);
|
||||||
|
if (cv_ret != kCVReturnSuccess) {
|
||||||
|
gst_vtenc_frame_free (frame);
|
||||||
|
goto cv_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -884,8 +919,7 @@ gst_vtenc_buffer_is_keyframe (GstVTEnc * self, CMSampleBufferRef sbuf)
|
|||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
CFArrayRef attachments_for_sample;
|
CFArrayRef attachments_for_sample;
|
||||||
|
|
||||||
attachments_for_sample =
|
attachments_for_sample = CMSampleBufferGetSampleAttachmentsArray (sbuf, 0);
|
||||||
CMSampleBufferGetSampleAttachmentsArray (sbuf, 0);
|
|
||||||
if (attachments_for_sample != NULL) {
|
if (attachments_for_sample != NULL) {
|
||||||
CFDictionaryRef attachments;
|
CFDictionaryRef attachments;
|
||||||
CFBooleanRef depends_on_others;
|
CFBooleanRef depends_on_others;
|
||||||
@ -900,13 +934,17 @@ gst_vtenc_buffer_is_keyframe (GstVTEnc * self, CMSampleBufferRef sbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GstVTEncFrame *
|
static GstVTEncFrame *
|
||||||
gst_vtenc_frame_new (GstBuffer * buf)
|
gst_vtenc_frame_new (GstBuffer * buf, GstVideoInfo * video_info)
|
||||||
{
|
{
|
||||||
GstVTEncFrame *frame;
|
GstVTEncFrame *frame;
|
||||||
|
|
||||||
frame = g_slice_new (GstVTEncFrame);
|
frame = g_slice_new (GstVTEncFrame);
|
||||||
frame->buf = gst_buffer_ref (buf);
|
frame->buf = gst_buffer_ref (buf);
|
||||||
gst_buffer_map (buf, &frame->map, GST_MAP_READ);
|
if (!gst_video_frame_map (&frame->videoframe, video_info, buf, GST_MAP_READ)) {
|
||||||
|
gst_buffer_unref (frame->buf);
|
||||||
|
g_slice_free (GstVTEncFrame, frame);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
@ -914,7 +952,7 @@ gst_vtenc_frame_new (GstBuffer * buf)
|
|||||||
static void
|
static void
|
||||||
gst_vtenc_frame_free (GstVTEncFrame * frame)
|
gst_vtenc_frame_free (GstVTEncFrame * frame)
|
||||||
{
|
{
|
||||||
gst_buffer_unmap (frame->buf, &frame->map);
|
gst_video_frame_unmap (&frame->videoframe);
|
||||||
gst_buffer_unref (frame->buf);
|
gst_buffer_unref (frame->buf);
|
||||||
g_slice_free (GstVTEncFrame, frame);
|
g_slice_free (GstVTEncFrame, frame);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define __GST_VTENC_H__
|
#define __GST_VTENC_H__
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
#include "coremediactx.h"
|
#include "coremediactx.h"
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ struct _GstVTEnc
|
|||||||
gint negotiated_fps_n, negotiated_fps_d;
|
gint negotiated_fps_n, negotiated_fps_d;
|
||||||
gint caps_width, caps_height;
|
gint caps_width, caps_height;
|
||||||
gint caps_fps_n, caps_fps_d;
|
gint caps_fps_n, caps_fps_d;
|
||||||
|
GstVideoInfo video_info;
|
||||||
VTCompressionSessionRef session;
|
VTCompressionSessionRef session;
|
||||||
CFMutableDictionaryRef options;
|
CFMutableDictionaryRef options;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user