完成 #292 » 0001-gstreamer-update-rochip-gstreamer-fix-record-error.patch
| external/gstreamer-rockchip/gst/rkximage/gstkmsallocator.c | ||
|---|---|---|
|
/* GStreamer
|
||
|
*
|
||
|
* Copyright (C) 2016 Igalia
|
||
|
* Copyright (C) <2024> Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* Authors:
|
||
|
* Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
|
||
|
* Javier Martin <javiermartin@by.com.es>
|
||
|
* Based on kmssink
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
| external/gstreamer-rockchip/gst/rkximage/gstkmsallocator.h | ||
|---|---|---|
|
/* GStreamer
|
||
|
*
|
||
|
* Copyright (C) 2016 Igalia
|
||
|
* Copyright (C) <2024> Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* Authors:
|
||
|
* Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
|
||
|
* Javier Martin <javiermartin@by.com.es>
|
||
|
* Based on kmssink
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
| external/gstreamer-rockchip/gst/rkximage/gstkmsbufferpool.c | ||
|---|---|---|
|
/*
|
||
|
* GStreamer
|
||
|
* Copyright (C) 2016 Igalia
|
||
|
* Copyright (C) <2024> Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* Authors:
|
||
|
* Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
|
||
|
* Javier Martin <javiermartin@by.com.es>
|
||
|
* Based on kmssink
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
| external/gstreamer-rockchip/gst/rkximage/gstkmsbufferpool.h | ||
|---|---|---|
|
/*
|
||
|
* GStreamer
|
||
|
* Copyright (C) 2016 Igalia
|
||
|
* Copyright (C) <2024> Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* Authors:
|
||
|
* Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
|
||
|
* Javier Martin <javiermartin@by.com.es>
|
||
|
* Based on kmssink
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
| external/gstreamer-rockchip/gst/rkximage/gstkmsutils.c | ||
|---|---|---|
|
/* GStreamer
|
||
|
*
|
||
|
* Copyright (C) 2016 Igalia
|
||
|
* Copyright (C) <2024> Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* Authors:
|
||
|
* Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
|
||
|
* Javier Martin <javiermartin@by.com.es>
|
||
|
* Based on kmssink
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
| external/gstreamer-rockchip/gst/rkximage/gstkmsutils.h | ||
|---|---|---|
|
/* GStreamer
|
||
|
*
|
||
|
* Copyright (C) 2016 Igalia
|
||
|
* Copyright (C) <2024> Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* Authors:
|
||
|
* Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
|
||
|
* Javier Martin <javiermartin@by.com.es>
|
||
|
* Based on kmssink
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
| external/gstreamer-rockchip/gst/rkximage/ximagesink.c | ||
|---|---|---|
|
/* GStreamer
|
||
|
*
|
||
|
* Copyright (C) 2016 Igalia
|
||
|
* Copyright (C) <2005> Julien Moutte <julien@moutte.net>
|
||
|
* Copyright ({) <2024> Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* Based on kmssink and ximagesink
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Library General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Library General Public
|
||
|
* License along with this library; if not, write to the
|
||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
#include "config.h"
|
||
|
#endif
|
||
| ... | ... | |
|
gboolean result;
|
||
|
drmModeCrtc *crtc;
|
||
|
if (conn->connection != DRM_MODE_CONNECTED)
|
||
|
return FALSE;
|
||
|
result = FALSE;
|
||
|
crtc = drm_find_crtc_for_connector (fd, res, conn, NULL);
|
||
|
if (crtc) {
|
||
| ... | ... | |
|
return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
||
|
}
|
||
|
/*ximagesink*/
|
||
|
static gboolean
|
||
|
xwindow_calculate_display_ratio (GstRkXImageSink * self, int *x, int *y,
|
||
|
gint * window_width, gint * window_height)
|
||
|
gst_kms_sink_calculate_display_ratio (GstRkXImageSink * self,
|
||
|
GstVideoInfo * vinfo, gint * scaled_width, gint * scaled_height)
|
||
|
{
|
||
|
guint dar_n, dar_d;
|
||
|
guint video_width, video_height;
|
||
|
guint video_par_n, video_par_d;
|
||
|
guint dpy_par_n, dpy_par_d;
|
||
|
gint video_width, video_height;
|
||
|
video_width = GST_VIDEO_INFO_WIDTH (&self->vinfo);
|
||
|
video_height = GST_VIDEO_INFO_HEIGHT (&self->vinfo);
|
||
|
video_par_n = self->par_n;
|
||
|
video_par_d = self->par_d;
|
||
|
video_width = GST_VIDEO_INFO_WIDTH (vinfo);
|
||
|
video_height = GST_VIDEO_INFO_HEIGHT (vinfo);
|
||
|
video_par_n = GST_VIDEO_INFO_PAR_N (vinfo);
|
||
|
video_par_d = GST_VIDEO_INFO_PAR_D (vinfo);
|
||
|
if (self->keep_aspect) {
|
||
|
*window_width = video_width;
|
||
|
*window_height = video_height;
|
||
|
gst_video_calculate_device_ratio (self->hdisplay, self->vdisplay,
|
||
|
self->mm_width, self->mm_height, &dpy_par_n, &dpy_par_d);
|
||
|
} else {
|
||
|
*scaled_width = video_width;
|
||
|
*scaled_height = video_height;
|
||
|
goto out;
|
||
|
}
|
||
|
gst_video_calculate_device_ratio (self->hdisplay, self->vdisplay,
|
||
|
self->mm_width, self->mm_height, &dpy_par_n, &dpy_par_d);
|
||
|
if (!gst_video_calculate_display_ratio (&dar_n, &dar_d, video_width,
|
||
|
video_height, video_par_n, video_par_d, dpy_par_n, dpy_par_d))
|
||
|
return FALSE;
|
||
| ... | ... | |
|
/* start with same height, because of interlaced video */
|
||
|
/* check hd / dar_d is an integer scale factor, and scale wd with the PAR */
|
||
|
video_width = gst_util_uint64_scale_int (self->xwindow->height, dar_n, dar_d);
|
||
|
video_height = gst_util_uint64_scale_int (self->xwindow->width, dar_d, dar_n);
|
||
|
if (video_width < *window_width) {
|
||
|
*x += (self->xwindow->width - video_width) / 2;
|
||
|
*window_width = video_width;
|
||
|
*window_height = self->xwindow->height;
|
||
|
if (video_height % dar_d == 0) {
|
||
|
GST_DEBUG_OBJECT (self, "keeping video height");
|
||
|
*scaled_width = (guint)
|
||
|
gst_util_uint64_scale_int (video_height, dar_n, dar_d);
|
||
|
*scaled_height = video_height;
|
||
|
} else if (video_width % dar_n == 0) {
|
||
|
GST_DEBUG_OBJECT (self, "keeping video width");
|
||
|
*scaled_width = video_width;
|
||
|
*scaled_height = (guint)
|
||
|
gst_util_uint64_scale_int (video_width, dar_d, dar_n);
|
||
|
} else {
|
||
|
*y += (self->xwindow->height - video_height) / 2;
|
||
|
*window_height = video_height;
|
||
|
*window_width = self->xwindow->width;
|
||
|
GST_DEBUG_OBJECT (self, "approximating while keeping video height");
|
||
|
*scaled_width = (guint)
|
||
|
gst_util_uint64_scale_int (video_height, dar_n, dar_d);
|
||
|
*scaled_height = video_height;
|
||
|
}
|
||
|
out:
|
||
|
GST_DEBUG_OBJECT (self, "scaling to %dx%d", *window_width, *window_height);
|
||
|
GST_DEBUG_OBJECT (self, "scaling to %dx%d", *scaled_width, *scaled_height);
|
||
|
return TRUE;
|
||
|
}
|
||
| ... | ... | |
|
return FALSE;
|
||
|
}
|
||
|
static void
|
||
|
xwindow_get_render_rectangle (GstRkXImageSink * ximagesink,
|
||
|
gint * x, gint * y, gint * width, gint * height)
|
||
|
{
|
||
|
if (ximagesink->save_rect.w != 0 && ximagesink->save_rect.h != 0) {
|
||
|
*width = ximagesink->save_rect.w;
|
||
|
*height = ximagesink->save_rect.h;
|
||
|
*x += ximagesink->save_rect.x;
|
||
|
*y += ximagesink->save_rect.y;
|
||
|
}
|
||
|
}
|
||
|
static void
|
||
|
gst_x_image_sink_xwindow_fill_key (GstRkXImageSink * ximagesink,
|
||
|
GstXWindow * xwindow, guint32 color)
|
||
| ... | ... | |
|
{
|
||
|
GstVideoCropMeta *crop;
|
||
|
GstVideoRectangle src = { 0, };
|
||
|
GstVideoRectangle result = { 0, };
|
||
|
gint video_width, video_height;
|
||
|
GstVideoRectangle dst = { 0, };
|
||
|
GstVideoRectangle result;
|
||
|
gint window_x, window_y;
|
||
|
GstBuffer *buffer = NULL;
|
||
|
gboolean draw_border = FALSE;
|
||
|
gboolean res = FALSE;
|
||
| ... | ... | |
|
src.w = GST_VIDEO_SINK_WIDTH (ximagesink);
|
||
|
src.h = GST_VIDEO_SINK_HEIGHT (ximagesink);
|
||
|
}
|
||
|
result.w = ximagesink->xwindow->width;
|
||
|
result.h = ximagesink->xwindow->height;
|
||
|
video_width = src.w;
|
||
|
video_height = src.h;
|
||
|
gst_kms_sink_calculate_display_ratio (ximagesink, &ximagesink->vinfo,
|
||
|
&src.w, &src.h);
|
||
|
dst.w = ximagesink->render_rect.w;
|
||
|
dst.h = ximagesink->render_rect.h;
|
||
|
if (!dst.w || !dst.h) {
|
||
|
dst.w = ximagesink->xwindow->width;
|
||
|
dst.h = ximagesink->xwindow->height;
|
||
|
}
|
||
|
gst_video_sink_center_rect (src, dst, &result, TRUE);
|
||
|
result.x += ximagesink->render_rect.x;
|
||
|
result.y += ximagesink->render_rect.y;
|
||
|
/* Restore the real source size */
|
||
|
src.w = video_width;
|
||
|
src.h = video_height;
|
||
|
g_mutex_lock (&ximagesink->x_lock);
|
||
| ... | ... | |
|
ximagesink->draw_border = FALSE;
|
||
|
}
|
||
|
xwindow_get_window_position (ximagesink, &result.x, &result.y);
|
||
|
xwindow_get_render_rectangle (ximagesink, &result.x, &result.y, &result.w,
|
||
|
&result.h);
|
||
|
xwindow_calculate_display_ratio (ximagesink, &result.x, &result.y, &result.w,
|
||
|
&result.h);
|
||
|
xwindow_get_window_position (ximagesink, &window_x, &window_y);
|
||
|
result.x += window_x;
|
||
|
result.y += window_y;
|
||
|
if (GST_VIDEO_INFO_IS_AFBC (&ximagesink->vinfo))
|
||
|
/* The AFBC's width should align to 4 */
|
||
| ... | ... | |
|
goto out;
|
||
|
}
|
||
|
/* HACK: Disable vsync might cause tearing */
|
||
|
if (!g_getenv ("KMSSINK_DISABLE_VSYNC"))
|
||
|
/* Wait for the previous frame to complete redraw */
|
||
| ... | ... | |
|
GST_VIDEO_SINK_HEIGHT (ximagesink) = info.height;
|
||
|
ximagesink->fps_n = info.fps_n;
|
||
|
ximagesink->fps_d = info.fps_d;
|
||
|
ximagesink->par_n = info.par_n;
|
||
|
ximagesink->par_d = info.par_d;
|
||
|
/* Notify application to set xwindow id now */
|
||
|
g_mutex_lock (&ximagesink->flow_lock);
|
||
| ... | ... | |
|
gint x, gint y, gint width, gint height)
|
||
|
{
|
||
|
GstRkXImageSink *ximagesink = GST_X_IMAGE_SINK (overlay);
|
||
|
GST_DEBUG_OBJECT (ximagesink, "Set Render Rectangle"
|
||
|
"x %d y %d width %d height %d", x, y, width, height);
|
||
|
ximagesink->save_rect.w = width;
|
||
|
ximagesink->save_rect.h = height;
|
||
|
ximagesink->save_rect.x = x;
|
||
|
ximagesink->save_rect.y = y;
|
||
|
ximagesink->render_rect.x = x;
|
||
|
ximagesink->render_rect.y = y;
|
||
|
ximagesink->render_rect.w = width;
|
||
|
ximagesink->render_rect.h = height;
|
||
|
gst_x_image_sink_expose (GST_VIDEO_OVERLAY (ximagesink));
|
||
|
}
|
||
| ... | ... | |
|
ximagesink->poll = gst_poll_new (TRUE);
|
||
|
gst_video_info_init (&ximagesink->vinfo);
|
||
|
ximagesink->save_rect.x = 0;
|
||
|
ximagesink->save_rect.y = 0;
|
||
|
ximagesink->save_rect.w = 0;
|
||
|
ximagesink->save_rect.h = 0;
|
||
|
ximagesink->render_rect.x = 0;
|
||
|
ximagesink->render_rect.y = 0;
|
||
|
ximagesink->render_rect.w = 0;
|
||
|
ximagesink->render_rect.h = 0;
|
||
|
ximagesink->paused = FALSE;
|
||
| external/gstreamer-rockchip/gst/rkximage/ximagesink.h | ||
|---|---|---|
|
/* GStreamer
|
||
|
*
|
||
|
* Copyright (C) 2016 Igalia
|
||
|
* Copyright (C) <2005> Julien Moutte <julien@moutte.net>
|
||
|
* Copyright (C) <2024> Rockchip Electronics Co., Ltd
|
||
|
*
|
||
|
* Based on kmssink and ximagesink
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Library General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Library General Public
|
||
|
* License along with this library; if not, write to the
|
||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
#ifndef __GST_X_IMAGE_SINK_H__
|
||
|
#define __GST_X_IMAGE_SINK_H__
|
||
| ... | ... | |
|
GstPollFD pollfd;
|
||
|
guint32 last_fb_id;
|
||
|
GstVideoRectangle save_rect;
|
||
|
GstVideoRectangle render_rect;
|
||
|
gboolean paused;
|
||
|
};
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmpp.c | ||
|---|---|---|
|
}
|
||
|
gboolean
|
||
|
gst_mpp_info_changed (GstVideoInfo * info, MppFrame * mframe)
|
||
|
gst_mpp_frame_info_changed (MppFrame * frame, MppFrame * other)
|
||
|
{
|
||
|
MppFrameFormat mpp_format = mpp_frame_get_fmt (mframe);
|
||
|
gint width = mpp_frame_get_width (mframe);
|
||
|
gint height = mpp_frame_get_height (mframe);
|
||
|
gint hstride = mpp_frame_get_hor_stride (mframe);
|
||
|
gint vstride = mpp_frame_get_ver_stride (mframe);
|
||
|
GstVideoFormat format = gst_mpp_mpp_format_to_gst_format (mpp_format);
|
||
|
gboolean afbc = !!MPP_FRAME_FMT_IS_FBC (mpp_format);
|
||
|
if (GST_VIDEO_INFO_FORMAT (info) != format)
|
||
|
if (!frame || !other)
|
||
|
return TRUE;
|
||
|
if (GST_VIDEO_INFO_WIDTH (info) != width)
|
||
|
if (mpp_frame_get_fmt (frame) != mpp_frame_get_fmt (other))
|
||
|
return TRUE;
|
||
|
if (GST_VIDEO_INFO_HEIGHT (info) != height)
|
||
|
if (mpp_frame_get_width (frame) != mpp_frame_get_width (other))
|
||
|
return TRUE;
|
||
|
if (GST_MPP_VIDEO_INFO_HSTRIDE (info) != hstride)
|
||
|
if (mpp_frame_get_height (frame) != mpp_frame_get_height (other))
|
||
|
return TRUE;
|
||
|
if (GST_VIDEO_INFO_N_PLANES (info) == 1 || afbc)
|
||
|
return FALSE;
|
||
|
if (mpp_frame_get_offset_x (frame) != mpp_frame_get_offset_x (other))
|
||
|
return TRUE;
|
||
|
if (mpp_frame_get_offset_y (frame) != mpp_frame_get_offset_y (other))
|
||
|
return TRUE;
|
||
|
if (mpp_frame_get_hor_stride (frame) != mpp_frame_get_hor_stride (other))
|
||
|
return TRUE;
|
||
|
if (GST_MPP_VIDEO_INFO_VSTRIDE (info) != vstride)
|
||
|
if (mpp_frame_get_ver_stride (frame) != mpp_frame_get_ver_stride (other))
|
||
|
return TRUE;
|
||
|
return FALSE;
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmpp.h | ||
|---|---|---|
|
gboolean gst_mpp_video_info_matched (GstVideoInfo * info, GstVideoInfo * other);
|
||
|
gboolean gst_mpp_info_changed (GstVideoInfo * info, MppFrame * mframe);
|
||
|
gboolean gst_mpp_frame_info_changed (MppFrame * frame, MppFrame * other);
|
||
|
guint gst_mpp_get_pixel_stride (GstVideoInfo * info);
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmppallocator.c | ||
|---|---|---|
|
mem = gst_mpp_allocator_import_mppbuf (allocator, mbuf);
|
||
|
mpp_buffer_put (mbuf);
|
||
|
gst_memory_resize (mem, 0, size);
|
||
|
if (mem)
|
||
|
gst_memory_resize (mem, 0, size);
|
||
|
return mem;
|
||
|
}
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmppalphadecodebin.c | ||
|---|---|---|
|
gst_ghost_pad_set_target (GST_GHOST_PAD (src_gpad), src_pad);
|
||
|
gst_object_unref (src_pad);
|
||
|
g_object_set (queue, "max-size-bytes", 0, "max-size-time", 0,
|
||
|
"max-size-buffers", 1, NULL);
|
||
|
g_object_set (alpha_queue, "max-size-bytes", 0, "max-size-time", 0,
|
||
|
"max-size-buffers", 1, NULL);
|
||
|
g_object_set (queue, "max-size-bytes", 0, "max-size-time",
|
||
|
G_GUINT64_CONSTANT (0), "max-size-buffers", 1, NULL);
|
||
|
g_object_set (alpha_queue, "max-size-bytes", 0, "max-size-time",
|
||
|
G_GUINT64_CONSTANT (0), "max-size-buffers", 1, NULL);
|
||
|
/* signal success, we will handle this in NULL->READY transition */
|
||
|
priv->constructed = TRUE;
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmppdec.c | ||
|---|---|---|
|
self->mpp_type = MPP_VIDEO_CodingUnused;
|
||
|
self->seen_valid_pts = FALSE;
|
||
|
self->convert = FALSE;
|
||
|
self->mpp_frame = NULL;
|
||
|
self->input_state = NULL;
|
||
| ... | ... | |
|
gst_mpp_dec_clear_allocator (decoder);
|
||
|
if (self->mpp_frame) {
|
||
|
mpp_frame_deinit (&self->mpp_frame);
|
||
|
self->mpp_frame = NULL;
|
||
|
}
|
||
|
mpp_destroy (self->mpp_ctx);
|
||
|
if (self->last_frame) {
|
||
|
gst_video_codec_frame_unref (self->last_frame);
|
||
|
self->last_frame = NULL;
|
||
|
}
|
||
|
GST_DEBUG_OBJECT (self, "stopped");
|
||
|
return TRUE;
|
||
| ... | ... | |
|
}
|
||
|
if (afbc) {
|
||
|
/* HACK: MPP would align width to 64 for AFBC */
|
||
|
/* HACK: Fake 64-aligned width for Mali DDK
|
||
|
*
|
||
|
* When importing AFBC dma-bufs, mali would re-calculate the row stride
|
||
|
* from width by itself. But the row stride aligning algorithms are
|
||
|
* different between MPP and Mali:
|
||
|
*
|
||
|
* MPP uses round_up_64(round_up_64(width) * bpp / 8)
|
||
|
* Mali uses round_up_64(width * bpp / 8)
|
||
|
*
|
||
|
* We need Mali to use the same row stride as MPP, so we fake a 64-aligned
|
||
|
* width here and crop to the real size later.
|
||
|
*/
|
||
|
dst_width = GST_ROUND_UP_64 (dst_width);
|
||
|
/* HACK: MPP might have extra offsets for AFBC */
|
||
|
dst_height += offset_y;
|
||
|
/* HACK: Fake hstride for Rockchip DRM driver
|
||
|
*
|
||
|
* When importing AFBC dma-bufs, the Rockchip DRM driver would calculate
|
||
|
* the pixel stride from pitch. But the pitch aligning algorithms are
|
||
|
* different between MPP and the driver:
|
||
|
*
|
||
|
* MPP uses round_up_64(round_up_64(width) * bpp / 8)
|
||
|
* Rockchip DRM driver expects (pixel_stride * bpp / 8)
|
||
|
*
|
||
|
* We need the driver to use the same pixel stride as MPP, so we
|
||
|
* re-calculate a fake hstride from the pixel stride (i.e. the 64-aligned
|
||
|
* fake width) here.
|
||
|
*
|
||
|
* NOTE: The hstride is not used by others for now.
|
||
|
*/
|
||
|
hstride = 0;
|
||
|
/* HACK: Fixup height and vstride with MPP's extra Y offsets
|
||
|
*
|
||
|
* The MPP might have extra rows for AFBC dma-bufs, and those rows are not
|
||
|
* counted in the height and vstride.
|
||
|
*/
|
||
|
dst_height += offset_y;
|
||
|
if (vstride < dst_height)
|
||
|
vstride = dst_height;
|
||
|
/* HACK: Fake hstride for Rockchip VOP driver */
|
||
|
hstride = 0;
|
||
|
}
|
||
|
if (!gst_mpp_dec_update_video_info (decoder, dst_format,
|
||
| ... | ... | |
|
frame->system_frame_number);
|
||
|
out:
|
||
|
if (frame) {
|
||
|
if (self->last_frame)
|
||
|
gst_video_codec_frame_unref (self->last_frame);
|
||
|
gst_video_codec_frame_ref (frame);
|
||
|
self->last_frame = frame;
|
||
|
} else if (self->last_frame) {
|
||
|
frame = self->last_frame;
|
||
|
GST_DEBUG_OBJECT (self, "reusing the last frame (#%d)",
|
||
|
frame->system_frame_number);
|
||
|
}
|
||
|
if (frame) {
|
||
|
gst_video_codec_frame_ref (frame);
|
||
| ... | ... | |
|
if (mpp_frame_get_discard (mframe) || mpp_frame_get_errinfo (mframe))
|
||
|
goto error;
|
||
|
if (!self->convert && gst_mpp_info_changed (&self->info, mframe)) {
|
||
|
if (!self->convert && gst_mpp_frame_info_changed (self->mpp_frame, mframe)) {
|
||
|
self->task_ret = gst_mpp_dec_apply_info_change (decoder, mframe);
|
||
|
if (self->task_ret != GST_FLOW_OK)
|
||
|
goto info_change;
|
||
|
}
|
||
|
/* Get gst buffer (might be converted) */
|
||
|
buffer = gst_mpp_dec_get_gst_buffer (decoder, mframe);
|
||
|
if (!buffer)
|
||
|
goto error;
|
||
|
/* Truncate MPP's extra data */
|
||
|
gst_buffer_resize (buffer, 0, GST_VIDEO_INFO_SIZE (&self->info));
|
||
|
mode = mpp_frame_get_mode (mframe);
|
||
| ... | ... | |
|
/* HACK: Mark lockable to avoid copying in make_writable() while shared */
|
||
|
GST_MINI_OBJECT_FLAG_SET (buffer, GST_MINI_OBJECT_FLAG_LOCKABLE);
|
||
|
frame->output_buffer = buffer;
|
||
|
gst_buffer_replace (&frame->output_buffer, buffer);
|
||
|
gst_buffer_unref (buffer);
|
||
|
GST_DEBUG_OBJECT (self, "finish frame ts=%" GST_TIME_FORMAT,
|
||
|
GST_TIME_ARGS (frame->pts));
|
||
| ... | ... | |
|
gst_video_decoder_finish_frame (decoder, frame);
|
||
|
out:
|
||
|
if (mpp_frame_get_eos (mframe)) {
|
||
|
GST_INFO_OBJECT (self, "got eos");
|
||
|
self->task_ret = GST_FLOW_EOS;
|
||
|
}
|
||
|
if (mframe) {
|
||
|
if (mpp_frame_get_eos (mframe)) {
|
||
|
GST_INFO_OBJECT (self, "got eos");
|
||
|
self->task_ret = GST_FLOW_EOS;
|
||
|
}
|
||
|
mpp_frame_deinit (&mframe);
|
||
|
if (self->mpp_frame)
|
||
|
mpp_frame_deinit (&self->mpp_frame);
|
||
|
/* Save the last MPP frame for info change detection */
|
||
|
mpp_frame_set_buffer (mframe, NULL);
|
||
|
self->mpp_frame = mframe;
|
||
|
}
|
||
|
if (self->task_ret != GST_FLOW_OK) {
|
||
|
GST_DEBUG_OBJECT (self, "leaving output thread: %s",
|
||
| ... | ... | |
|
start_time = gst_util_get_timestamp ();
|
||
|
deadline_time = start_time + MPP_INPUT_TIMEOUT_MS * GST_MSECOND;
|
||
|
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||
|
while (1) {
|
||
|
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||
|
if (klass->send_mpp_packet (decoder, mpkt, interval_ms)) {
|
||
|
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||
|
if (klass->send_mpp_packet (decoder, mpkt, interval_ms))
|
||
|
break;
|
||
|
}
|
||
|
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||
|
if (gst_util_get_timestamp () > deadline_time)
|
||
|
if (gst_util_get_timestamp () > deadline_time) {
|
||
|
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||
|
goto send_error;
|
||
|
}
|
||
|
}
|
||
|
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||
|
/* NOTE: Sub-class takes over the MPP packet when success */
|
||
|
mpkt = NULL;
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmppdec.h | ||
|---|---|---|
|
/* final output video info */
|
||
|
GstVideoInfo info;
|
||
|
/* decoded MPP frame info */
|
||
|
MppFrame mpp_frame;
|
||
|
/* specified output format */
|
||
|
GstVideoFormat format;
|
||
| ... | ... | |
|
guint32 decoded_frames;
|
||
|
GstVideoCodecFrame *last_frame;
|
||
|
MppCodingType mpp_type;
|
||
|
MppCtx mpp_ctx;
|
||
|
MppApi *mpi;
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmppenc.c | ||
|---|---|---|
|
#define parent_class gst_mpp_enc_parent_class
|
||
|
G_DEFINE_ABSTRACT_TYPE (GstMppEnc, gst_mpp_enc, GST_TYPE_VIDEO_ENCODER);
|
||
|
#define MPP_PENDING_MAX 16 /* Max number of MPP pending frame */
|
||
|
#define GST_MPP_ENC_TASK_STARTED(encoder) \
|
||
|
(gst_pad_get_task_state ((encoder)->srcpad) == GST_TASK_STARTED)
|
||
| ... | ... | |
|
/* Input isn't ARM AFBC by default */
|
||
|
static GstVideoFormat DEFAULT_PROP_ARM_AFBC = FALSE;
|
||
|
#define MPP_MAX_PENDING 16 /* Max number of MPP pending frames */
|
||
|
static guint32 DEFAULT_PROP_MAX_PENDING = MPP_MAX_PENDING;
|
||
|
#define DEFAULT_FPS 30
|
||
|
enum
|
||
|
{
|
||
|
PROP_0,
|
||
|
PROP_MAX_PENDING,
|
||
|
PROP_HEADER_MODE,
|
||
|
PROP_RC_MODE,
|
||
|
PROP_ROTATION,
|
||
| ... | ... | |
|
MPP_FMT_YUV444P,
|
||
|
MPP_FMT_RGB565LE,
|
||
|
MPP_FMT_BGR565LE,
|
||
|
MPP_FMT_RGB888,
|
||
|
MPP_FMT_BGR888,
|
||
|
MPP_FMT_ARGB8888,
|
||
|
MPP_FMT_ABGR8888,
|
||
|
MPP_FMT_RGBA8888,
|
||
| ... | ... | |
|
GstMppEnc *self = GST_MPP_ENC (encoder);
|
||
|
switch (prop_id) {
|
||
|
case PROP_MAX_PENDING:{
|
||
|
self->max_pending = g_value_get_uint (value);
|
||
|
GST_MPP_ENC_BROADCAST (encoder);
|
||
|
return;
|
||
|
}
|
||
|
case PROP_HEADER_MODE:{
|
||
|
MppEncHeaderMode header_mode = g_value_get_enum (value);
|
||
|
if (self->header_mode == header_mode)
|
||
| ... | ... | |
|
GstMppEnc *self = GST_MPP_ENC (encoder);
|
||
|
switch (prop_id) {
|
||
|
case PROP_MAX_PENDING:
|
||
|
g_value_set_uint (value, self->max_pending);
|
||
|
break;
|
||
|
case PROP_HEADER_MODE:
|
||
|
g_value_set_enum (value, self->header_mode);
|
||
|
break;
|
||
| ... | ... | |
|
{
|
||
|
GstMppEnc *self = GST_MPP_ENC (encoder);
|
||
|
GstVideoInfo *info = &self->info;
|
||
|
gint fps_num = GST_VIDEO_INFO_FPS_N (info);
|
||
|
gint fps_denorm = GST_VIDEO_INFO_FPS_D (info);
|
||
|
gint fps = fps_num / fps_denorm;
|
||
|
gint fps = GST_VIDEO_INFO_FPS_N (info) / GST_VIDEO_INFO_FPS_D (info);
|
||
|
if (!self->prop_dirty)
|
||
|
return TRUE;
|
||
| ... | ... | |
|
self->flushing = TRUE;
|
||
|
self->draining = drain;
|
||
|
gst_mpp_enc_stop_task (encoder, drain);
|
||
|
/* HACK: The MPP is not capable of handling resets properly. */
|
||
|
self->draining = TRUE;
|
||
|
gst_mpp_enc_stop_task (encoder, self->draining);
|
||
|
self->flushing = final;
|
||
|
self->draining = FALSE;
|
||
| ... | ... | |
|
gst_mpp_enc_start (GstVideoEncoder * encoder)
|
||
|
{
|
||
|
GstMppEnc *self = GST_MPP_ENC (encoder);
|
||
|
MppPollType timeout = MPP_POLL_NON_BLOCK;
|
||
|
MppPollType timeout;
|
||
|
GST_DEBUG_OBJECT (self, "starting");
|
||
| ... | ... | |
|
if (mpp_create (&self->mpp_ctx, &self->mpi))
|
||
|
goto err_unref_alloc;
|
||
|
timeout = MPP_POLL_NON_BLOCK;
|
||
|
if (self->mpi->control (self->mpp_ctx, MPP_SET_INPUT_TIMEOUT, &timeout))
|
||
|
goto err_destroy_mpp;
|
||
|
/* 1ms timeout for polling */
|
||
|
timeout = 1;
|
||
|
if (self->mpi->control (self->mpp_ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout))
|
||
|
goto err_destroy_mpp;
|
||
| ... | ... | |
|
mpp_frame_set_width (self->mpp_frame, width);
|
||
|
mpp_frame_set_height (self->mpp_frame, height);
|
||
|
if (!GST_VIDEO_INFO_FPS_N (info) || GST_VIDEO_INFO_FPS_N (info) > 240) {
|
||
|
if (!GST_VIDEO_INFO_FPS_N (info) ||
|
||
|
GST_VIDEO_INFO_FPS_N (info) / GST_VIDEO_INFO_FPS_D (info) > 256) {
|
||
|
GST_WARNING_OBJECT (self, "framerate (%d/%d) is insane!",
|
||
|
GST_VIDEO_INFO_FPS_N (info), GST_VIDEO_INFO_FPS_D (info));
|
||
|
GST_VIDEO_INFO_FPS_N (info) = DEFAULT_FPS;
|
||
|
GST_VIDEO_INFO_FPS_D (info) = 1;
|
||
|
}
|
||
|
mpp_enc_cfg_set_s32 (self->mpp_cfg, "prep:format", format);
|
||
| ... | ... | |
|
gst_buffer_pool_set_config (pool, config);
|
||
|
gst_query_add_allocation_pool (query, pool, size, MPP_PENDING_MAX, 0);
|
||
|
gst_query_add_allocation_pool (query, pool, size, 0, 0);
|
||
|
gst_query_add_allocation_param (query, self->allocator, NULL);
|
||
|
gst_object_unref (pool);
|
||
| ... | ... | |
|
src_hstride = GST_MPP_VIDEO_INFO_HSTRIDE (&src_info);
|
||
|
src_vstride = GST_MPP_VIDEO_INFO_VSTRIDE (&src_info);
|
||
|
/**
|
||
|
* Update the strides of the dst video info temporarily to test if we
|
||
|
* can use the src buffer directly.
|
||
|
*/
|
||
|
if (!gst_mpp_video_info_align (&dst_info, src_hstride, src_vstride) ||
|
||
|
!gst_mpp_enc_video_info_align (&dst_info) ||
|
||
|
!gst_mpp_video_info_matched (&src_info, &dst_info))
|
||
|
!gst_mpp_video_info_matched (&src_info, &dst_info)) {
|
||
|
/* Reset the temporarily modified dst video info. */
|
||
|
dst_info = self->info;
|
||
|
goto convert;
|
||
|
}
|
||
|
gst_mpp_enc_apply_strides (encoder, src_hstride, src_vstride);
|
||
|
if (!gst_mpp_enc_apply_properties (encoder))
|
||
| ... | ... | |
|
if (gst_video_frame_map (&src_frame, &src_info, inbuf, GST_MAP_READ)) {
|
||
|
if (gst_video_frame_map (&dst_frame, &dst_info, outbuf, GST_MAP_WRITE)) {
|
||
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
||
|
if (!gst_video_frame_copy (&dst_frame, &src_frame)) {
|
||
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||
|
gst_video_frame_unmap (&dst_frame);
|
||
|
gst_video_frame_unmap (&src_frame);
|
||
|
goto err;
|
||
|
}
|
||
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||
|
gst_video_frame_unmap (&dst_frame);
|
||
|
}
|
||
|
gst_video_frame_unmap (&src_frame);
|
||
| ... | ... | |
|
gst_buffer_copy_into (outbuf, inbuf,
|
||
|
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, 0);
|
||
|
dst_info = self->info;
|
||
|
gst_buffer_add_video_meta_full (outbuf, GST_VIDEO_FRAME_FLAG_NONE,
|
||
|
GST_VIDEO_INFO_FORMAT (&dst_info),
|
||
|
GST_VIDEO_INFO_WIDTH (&dst_info), GST_VIDEO_INFO_HEIGHT (&dst_info),
|
||
| ... | ... | |
|
gst_video_codec_frame_unref (frame);
|
||
|
if (!self->mpi->encode_put_frame (self->mpp_ctx, mframe)) {
|
||
|
GST_DEBUG_OBJECT (self, "encoding frame %d", frame_number);
|
||
|
self->frames = g_list_delete_link (self->frames, self->frames);
|
||
|
return TRUE;
|
||
|
if (self->mpi->encode_put_frame (self->mpp_ctx, mframe)) {
|
||
|
mpp_frame_deinit (&mframe);
|
||
|
return FALSE;
|
||
|
}
|
||
|
mpp_frame_deinit (mframe);
|
||
|
return FALSE;
|
||
|
GST_DEBUG_OBJECT (self, "encoding frame %d", frame_number);
|
||
|
self->frames = g_list_delete_link (self->frames, self->frames);
|
||
|
return TRUE;
|
||
|
}
|
||
|
static gboolean
|
||
| ... | ... | |
|
/* Deinit input frame */
|
||
|
meta = mpp_packet_get_meta (mpkt);
|
||
|
if (!mpp_meta_get_frame (meta, KEY_INPUT_FRAME, &mframe))
|
||
|
mpp_frame_deinit (mframe);
|
||
|
mpp_frame_deinit (&mframe);
|
||
|
/* Wake up the frame producer */
|
||
|
self->pending_frames--;
|
||
| ... | ... | |
|
/* Try sending ready frames to MPP (non-block) */
|
||
|
while (gst_mpp_enc_send_frame_locked (encoder));
|
||
|
/* Try polling encoded packets from MPP (non-block) */
|
||
|
/* Try polling encoded packets from MPP (1ms timeout) */
|
||
|
while (gst_mpp_enc_poll_packet_locked (encoder));
|
||
|
out:
|
||
| ... | ... | |
|
(GstTaskFunction) gst_mpp_enc_loop, encoder, NULL);
|
||
|
}
|
||
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
||
|
buffer = gst_mpp_enc_convert (encoder, frame);
|
||
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||
|
if (G_UNLIKELY (!buffer))
|
||
|
goto not_negotiated;
|
||
| ... | ... | |
|
frame->output_buffer = buffer;
|
||
|
/* Avoid holding too much frames */
|
||
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
||
|
GST_MPP_ENC_WAIT (encoder, self->pending_frames < MPP_PENDING_MAX
|
||
|
|| self->flushing);
|
||
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||
|
if (G_UNLIKELY (self->pending_frames >= self->max_pending)) {
|
||
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
||
|
GST_MPP_ENC_WAIT (encoder, self->pending_frames < self->max_pending
|
||
|
|| self->flushing);
|
||
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||
|
}
|
||
|
if (G_UNLIKELY (self->flushing))
|
||
|
goto flushing;
|
||
| ... | ... | |
|
{
|
||
|
self->mpp_type = MPP_VIDEO_CodingUnused;
|
||
|
self->max_pending = DEFAULT_PROP_MAX_PENDING;
|
||
|
self->header_mode = DEFAULT_PROP_HEADER_MODE;
|
||
|
self->sei_mode = DEFAULT_PROP_SEI_MODE;
|
||
|
self->rc_mode = DEFAULT_PROP_RC_MODE;
|
||
| ... | ... | |
|
GstVideoEncoderClass *encoder_class = GST_VIDEO_ENCODER_CLASS (klass);
|
||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||
|
const gchar *env;
|
||
|
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "mppenc", 0, "MPP encoder");
|
||
| ... | ... | |
|
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_mpp_enc_set_property);
|
||
|
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_mpp_enc_get_property);
|
||
|
env = g_getenv ("GST_MPP_ENC_MAX_PENDING");
|
||
|
if (env)
|
||
|
DEFAULT_PROP_MAX_PENDING = MAX (MIN (atoi (env), MPP_MAX_PENDING), 1);
|
||
|
g_object_class_install_property (gobject_class, PROP_MAX_PENDING,
|
||
|
g_param_spec_uint ("max-pending", "Max pending frames",
|
||
|
"Max pending frames",
|
||
|
1, MPP_MAX_PENDING, DEFAULT_PROP_MAX_PENDING,
|
||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
g_object_class_install_property (gobject_class, PROP_HEADER_MODE,
|
||
|
g_param_spec_enum ("header-mode", "Header mode",
|
||
|
"Header mode",
|
||
| ... | ... | |
|
"Zero-copy encoded packet", DEFAULT_PROP_ZERO_COPY_PKT,
|
||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
if (g_getenv ("GST_MPPENC_DEFAULT_ARM_AFBC"))
|
||
|
env = g_getenv ("GST_MPP_ENC_DEFAULT_ARM_AFBC");
|
||
|
if (env && env[0] == '1')
|
||
|
DEFAULT_PROP_ARM_AFBC = TRUE;
|
||
|
g_object_class_install_property (gobject_class, PROP_ARM_AFBC,
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmppenc.h | ||
|---|---|---|
|
/* frame system numbers that are ready for sending to MPP */
|
||
|
GList *frames;
|
||
|
/* Max number of pending frames */
|
||
|
guint32 max_pending;
|
||
|
guint32 required_keyframe_number;
|
||
|
guint pending_frames;
|
||
| ... | ... | |
|
#define MPP_ENC_IN_FORMATS \
|
||
|
"NV12, I420, YUY2, UYVY, " \
|
||
|
"BGR16, RGB16, " \
|
||
|
"BGR16, RGB16, BGR, RGB, " \
|
||
|
"ABGR, ARGB, BGRA, RGBA, xBGR, xRGB, BGRx, RGBx"
|
||
|
#ifdef HAVE_RGA
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmpph264enc.c | ||
|---|---|---|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
g_object_class_install_property (gobject_class, PROP_QP_MIN_I,
|
||
|
g_param_spec_int ("qp-min-i", "Min Intra QP",
|
||
|
g_param_spec_uint ("qp-min-i", "Min Intra QP",
|
||
|
"Min Intra QP (0 = default)", 0, 51, DEFAULT_PROP_QP_MIN_I,
|
||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
g_object_class_install_property (gobject_class, PROP_QP_MAX_I,
|
||
|
g_param_spec_int ("qp-max-i", "Max Intra QP",
|
||
|
g_param_spec_uint ("qp-max-i", "Max Intra QP",
|
||
|
"Max Intra QP (0 = default)", 0, 51, DEFAULT_PROP_QP_MAX_I,
|
||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmpph265enc.c | ||
|---|---|---|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
g_object_class_install_property (gobject_class, PROP_QP_MIN_I,
|
||
|
g_param_spec_int ("qp-min-i", "Min Intra QP",
|
||
|
g_param_spec_uint ("qp-min-i", "Min Intra QP",
|
||
|
"Min Intra QP (0 = default)", 0, 51, DEFAULT_PROP_QP_MIN_I,
|
||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
g_object_class_install_property (gobject_class, PROP_QP_MAX_I,
|
||
|
g_param_spec_int ("qp-max-i", "Max Intra QP",
|
||
|
g_param_spec_uint ("qp-max-i", "Max Intra QP",
|
||
|
"Max Intra QP (0 = default)", 0, 51, DEFAULT_PROP_QP_MAX_I,
|
||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmppjpegdec.c | ||
|---|---|---|
|
guint align = GST_MPP_ALIGNMENT;
|
||
|
if (!width || !height) {
|
||
|
GST_ERROR_OBJECT (self, "invalid input video info");
|
||
|
return FALSE;
|
||
|
if (self->buf_size) {
|
||
|
GST_ERROR_OBJECT (self, "ignore invalid input video info");
|
||
|
return TRUE;
|
||
|
} else {
|
||
|
GST_ERROR_OBJECT (self, "invalid input video info");
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
if (!pclass->set_format (decoder, state))
|
||
| external/gstreamer-rockchip/gst/rockchipmpp/gstmppjpegenc.c | ||
|---|---|---|
|
GST_MPP_JPEG_ENC_SIZE_CAPS));
|
||
|
static void
|
||
|
gst_mpp_h264_enc_set_property (GObject * object,
|
||
|
gst_mpp_jpeg_enc_set_property (GObject * object,
|
||
|
guint prop_id, const GValue * value, GParamSpec * pspec)
|
||
|
{
|
||
|
GstVideoEncoder *encoder = GST_VIDEO_ENCODER (object);
|
||
| ... | ... | |
|
}
|
||
|
static void
|
||
|
gst_mpp_h264_enc_get_property (GObject * object,
|
||
|
gst_mpp_jpeg_enc_get_property (GObject * object,
|
||
|
guint prop_id, GValue * value, GParamSpec * pspec)
|
||
|
{
|
||
|
GstVideoEncoder *encoder = GST_VIDEO_ENCODER (object);
|
||
| ... | ... | |
|
GST_DEBUG_FUNCPTR (gst_mpp_jpeg_enc_handle_frame);
|
||
|
gobject_class->set_property =
|
||
|
GST_DEBUG_FUNCPTR (gst_mpp_h264_enc_set_property);
|
||
|
GST_DEBUG_FUNCPTR (gst_mpp_jpeg_enc_set_property);
|
||
|
gobject_class->get_property =
|
||
|
GST_DEBUG_FUNCPTR (gst_mpp_h264_enc_get_property);
|
||
|
GST_DEBUG_FUNCPTR (gst_mpp_jpeg_enc_get_property);
|
||
|
g_object_class_install_property (gobject_class, PROP_Q_FACTOR,
|
||
|
g_param_spec_uint ("q-factor", "Quality Factor",
|
||
- « Previous
- 1
- 2
- 3
- Next »