Project

General

Profile

完成 #292 » 0001-gstreamer-update-rochip-gstreamer-fix-record-error.patch

余 顺, 04/22/2026 06:28 AM

View differences:

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",
(3-3/3)