xuesong.jiang | 16983c9 | 2021-12-30 10:57:17 +0800 | [diff] [blame] | 1 | /* GStreamer |
xuesong.jiang | f6734c6 | 2022-04-26 13:46:11 +0800 | [diff] [blame] | 2 | * Copyright (C) 2022 <xuesong.jiang@amlogic.com> |
xuesong.jiang | 16983c9 | 2021-12-30 10:57:17 +0800 | [diff] [blame] | 3 | * |
| 4 | * This library is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of the GNU Library General Public |
| 6 | * License as published by the Free Software Foundation; either |
| 7 | * version 2 of the License, or (at your option) any later version. |
| 8 | * |
| 9 | * This library is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 | * Library General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU Library General Public |
| 15 | * License along with this library; if not, write to the |
| 16 | * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, |
| 17 | * Boston, MA 02110-1335, USA. |
| 18 | */ |
| 19 | /** |
| 20 | * SECTION:element-gstamlvideosink |
| 21 | * |
| 22 | * The gstamlvideosink element call render lib to render video |
| 23 | * |
| 24 | */ |
| 25 | |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 26 | #ifdef HAVE_CONFIG_H |
| 27 | #include <config.h> |
| 28 | #endif |
| 29 | |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 30 | #include <stdbool.h> |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 31 | #include <gst/gstdrmbufferpool.h> |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 32 | #include <gst/allocators/gstdmabuf.h> |
xuesong.jiang | 192316f | 2021-10-27 14:51:56 +0800 | [diff] [blame] | 33 | #include "gstamlvideosink.h" |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 34 | #include <render_lib.h> |
xuesong.jiang | 192316f | 2021-10-27 14:51:56 +0800 | [diff] [blame] | 35 | // #ifdef USE_AMLOGIC_MESON |
| 36 | // #ifdef USE_AMLOGIC_MESON_MSYNC |
| 37 | // #define INVALID_SESSION_ID (16) |
xuesong.jiang | 75ef01c | 2021-12-09 17:08:52 +0800 | [diff] [blame] | 38 | #include <stdio.h> |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 39 | #include <unistd.h> |
xuesong.jiang | 192316f | 2021-10-27 14:51:56 +0800 | [diff] [blame] | 40 | // #endif |
| 41 | // #endif |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 42 | #include "ge2drotation.h" |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 43 | |
xuesong.jiang | 91391f5 | 2021-11-19 15:42:30 +0800 | [diff] [blame] | 44 | #ifdef GST_OBJECT_LOCK |
| 45 | #undef GST_OBJECT_LOCK |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 46 | #define GST_OBJECT_LOCK(obj) \ |
| 47 | { \ |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 48 | GST_TRACE("dbg basesink ctxt lock | aml | locking | %p", obj); \ |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 49 | g_mutex_lock(GST_OBJECT_GET_LOCK(obj)); \ |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 50 | GST_TRACE("dbg basesink ctxt lock | aml | locked | %p", obj); \ |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 51 | } |
xuesong.jiang | 91391f5 | 2021-11-19 15:42:30 +0800 | [diff] [blame] | 52 | #endif |
| 53 | |
| 54 | #ifdef GST_OBJECT_UNLOCK |
| 55 | #undef GST_OBJECT_UNLOCK |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 56 | #define GST_OBJECT_UNLOCK(obj) \ |
| 57 | { \ |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 58 | GST_TRACE("dbg basesink ctxt lock | aml | unlocking | %p", obj); \ |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 59 | g_mutex_unlock(GST_OBJECT_GET_LOCK(obj)); \ |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 60 | GST_TRACE("dbg basesink ctxt lock | aml | unlocked | %p", obj); \ |
xuesong.jiang | 58e75f8 | 2022-06-30 19:23:20 +0800 | [diff] [blame] | 61 | } |
| 62 | #endif |
| 63 | |
| 64 | #ifdef GST_BASE_SINK_PREROLL_LOCK |
| 65 | #undef GST_BASE_SINK_PREROLL_LOCK |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 66 | #define GST_BASE_SINK_PREROLL_LOCK(obj) \ |
| 67 | { \ |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 68 | GST_TRACE("dbg basesink preroll lock | aml | locking | %p", obj); \ |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 69 | g_mutex_lock(GST_BASE_SINK_GET_PREROLL_LOCK(obj)); \ |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 70 | GST_TRACE("dbg basesink preroll lock | aml | locked | %p", obj); \ |
xuesong.jiang | 58e75f8 | 2022-06-30 19:23:20 +0800 | [diff] [blame] | 71 | } |
| 72 | #endif |
| 73 | |
| 74 | #ifdef GST_BASE_SINK_PREROLL_UNLOCK |
| 75 | #undef GST_BASE_SINK_PREROLL_UNLOCK |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 76 | #define GST_BASE_SINK_PREROLL_UNLOCK(obj) \ |
| 77 | { \ |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 78 | GST_TRACE("dbg basesink preroll lock | aml | unlocking | %p", obj); \ |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 79 | g_mutex_unlock(GST_BASE_SINK_GET_PREROLL_LOCK(obj)); \ |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 80 | GST_TRACE("dbg basesink preroll lock | aml | unlocked | %p", obj); \ |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 81 | } |
xuesong.jiang | 91391f5 | 2021-11-19 15:42:30 +0800 | [diff] [blame] | 82 | #endif |
| 83 | |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 84 | #define GST_IMPORT_LGE_PROP 0 |
| 85 | |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 86 | /* signals */ |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 87 | enum |
| 88 | { |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 89 | SIGNAL_FIRSTFRAME, |
| 90 | SIGNAL_UNDERFLOW, |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 91 | SIGNAL_DECODEDBUFFER, |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 92 | SIGNAL_FRAMEFREEZE, |
| 93 | SIGNAL_RESYNC, |
| 94 | SIGNAL_FRAMEDROP, |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 95 | LAST_SIGNAL |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 96 | }; |
| 97 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 98 | /* Properties */ |
| 99 | enum |
| 100 | { |
| 101 | PROP_0, |
| 102 | PROP_FULLSCREEN, |
| 103 | PROP_SETMUTE, |
xuesong.jiang | a507a4b | 2022-10-28 16:28:29 +0800 | [diff] [blame] | 104 | PROP_DEFAULT_SYNC, |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 105 | PROP_AVSYNC_MODE, |
xuesong.jiang | 62ed50e | 2022-04-13 16:55:47 +0800 | [diff] [blame] | 106 | PROP_VIDEO_FRAME_DROP_NUM, |
xuesong.jiang | 1a9c282 | 2022-04-24 11:35:07 +0800 | [diff] [blame] | 107 | PROP_WINDOW_SET, |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 108 | PROP_RES_USAGE, |
xuesong.jiang | 5eb0171 | 2022-10-21 19:47:54 +0800 | [diff] [blame] | 109 | PROP_DISPLAY_OUTPUT, |
fei.deng | 978b242 | 2023-11-30 10:33:23 +0000 | [diff] [blame] | 110 | PROP_SHOW_FIRST_FRAME_ASAP, |
le.han | b62dfce | 2024-02-28 03:23:12 +0000 | [diff] [blame] | 111 | PROP_KEEP_LAST_FRAME_ON_FLUSH, |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 112 | PROP_ENABLE_USER_RENDERING, |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 113 | PROP_IMMEDIATELY_RENDER, |
| 114 | PROP_VIDEO_FRAME_DISPLAY_NUM, |
kaiqiang.xiang | 5581e8e | 2024-07-23 10:39:41 +0800 | [diff] [blame] | 115 | PROP_VIDEO_PTS, |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 116 | PROP_ZORDER, |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 117 | PROP_FRAME_STEP_ON_PREROLL, |
fei.deng | 3a374e5 | 2024-10-29 17:04:42 +0800 | [diff] [blame] | 118 | PRO_VIDEO_LATENCY, |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 119 | PROP_FORCE_ASPECT_RATIO, |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 120 | #if GST_IMPORT_LGE_PROP |
| 121 | PROP_LGE_RESOURCE_INFO, |
| 122 | PROP_LGE_CURRENT_PTS, |
| 123 | PROP_LGE_INTERLEAVING_TYPE, |
| 124 | PROP_LGE_APP_TYPE, |
| 125 | PROP_LGE_SYNC, |
| 126 | PROP_LGE_DISH_TRICK, |
| 127 | PROP_LGE_DISH_TRICK_IGNORE_RATE, |
| 128 | #endif |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 129 | PROP_VIDEO_ROTATION, |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 130 | }; |
| 131 | |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 132 | typedef enum { |
| 133 | VIDEO_TRICK_MODE_NONE = 0, // Disable trick mode |
| 134 | VIDEO_TRICK_MODE_PAUSE = 1, // Pause the video decoder |
| 135 | VIDEO_TRICK_MODE_PAUSE_NEXT = 2, // Pause the video decoder when a new frame displayed |
| 136 | VIDEO_TRICK_MODE_IONLY = 3 // Decoding and out I frame only |
| 137 | } video_trick_mode; |
| 138 | |
xuesong.jiang | fa8903d | 2022-02-11 15:13:05 +0800 | [diff] [blame] | 139 | #define AML_VIDEO_FORMATS "{ NV21 }" |
| 140 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 141 | #define GST_CAPS_FEATURE_MEMORY_DMABUF "memory:DMABuf" |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 142 | #define GST_USE_PLAYBIN 1 |
xuesong.jiang | e0c6c54 | 2022-04-11 16:10:23 +0800 | [diff] [blame] | 143 | #define GST_DEFAULT_AVSYNC_MODE 1 // 0:v master, 1:a master |
xuesong.jiang | 5d2761f | 2022-05-05 11:43:21 +0800 | [diff] [blame] | 144 | #define GST_DUMP_STAT_FILENAME "amlvideosink_buf_stat" |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 145 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 146 | #define USE_DMABUF TRUE |
| 147 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 148 | #define DRMBP_EXTRA_BUF_SIZE_FOR_DISPLAY 1 |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 149 | #define DRMBP_LIMIT_MAX_BUFSIZE_TO_BUFSIZE 1 |
| 150 | #define DRMBP_UNLIMIT_MAX_BUFSIZE 0 |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 151 | #define GST_AML_WAIT_TIME 5000 |
| 152 | #define FORMAT_NV21 0x3231564e // this value is used to be same as cobalt |
xuesong.jiang | b3f0f15 | 2021-12-23 20:19:08 +0800 | [diff] [blame] | 153 | |
kaiqiang.xiang | ecbc171 | 2024-07-24 15:29:38 +0800 | [diff] [blame] | 154 | #define PTS_90K (90000) |
| 155 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 156 | #define ROT_BUFFER_MAX (5) |
| 157 | #define ROT_QUEUE_MAX (20) |
| 158 | |
xuesong.jiang | 1a9c282 | 2022-04-24 11:35:07 +0800 | [diff] [blame] | 159 | typedef struct _GstAmlVideoSinkWindowSet |
| 160 | { |
| 161 | gboolean window_change; |
| 162 | gint x; |
| 163 | gint y; |
| 164 | gint w; |
| 165 | gint h; |
| 166 | } GstAmlVideoSinkWindowSet; |
| 167 | |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 168 | #if GST_IMPORT_LGE_PROP |
| 169 | typedef struct _GstAmlResourceInfo |
| 170 | { |
| 171 | gchar *coretype; |
| 172 | gint videoport; |
| 173 | gint audioport; |
| 174 | gint maxwidth; |
| 175 | gint maxheight; |
| 176 | gint mixerport; |
| 177 | } GstAmlResourceInfo; |
| 178 | |
| 179 | typedef struct _GstAmlVideoSinkLgeCtxt |
| 180 | { |
| 181 | GstAmlResourceInfo res_info; |
| 182 | guint interleaving_type; |
| 183 | gchar *app_type; |
| 184 | gboolean sync; |
| 185 | gboolean dish_trick; |
| 186 | gboolean dish_trick_ignore_rate; |
| 187 | } GstAmlVideoSinkLgeCtxt; |
| 188 | #endif |
| 189 | |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 190 | typedef struct ReportInfo |
| 191 | { |
| 192 | gint msg; |
| 193 | FrameDisplayInfo info; |
| 194 | } ReportInfo; |
| 195 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 196 | struct _GstAmlVideoSinkPrivate |
| 197 | { |
xuesong.jiang | 1a9c282 | 2022-04-24 11:35:07 +0800 | [diff] [blame] | 198 | GstAmlVideoSinkWindowSet window_set; |
xuesong.jiang | ebd1835 | 2021-12-28 17:13:22 +0800 | [diff] [blame] | 199 | GstBuffer *preroll_buffer; |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 200 | void *render_device_handle; |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 201 | gboolean video_info_changed; |
| 202 | gboolean use_dmabuf; |
| 203 | gboolean is_flushing; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 204 | gboolean got_eos; |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 205 | gint mediasync_instanceid; |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 206 | GstSegment segment; |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 207 | GList *reportInfos; |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 208 | gboolean frame_step_on_preroll; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 209 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 210 | /* property params */ |
| 211 | gboolean fullscreen; |
| 212 | gboolean mute; |
fei.deng | 978b242 | 2023-11-30 10:33:23 +0000 | [diff] [blame] | 213 | gboolean show_first_frame_asap; |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 214 | gboolean emitUnderflowSignal; |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 215 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 216 | /* video info from caps */ |
| 217 | GstVideoFormat format; |
| 218 | gboolean interlace; |
| 219 | gint dw_width; |
| 220 | gint dw_height; |
| 221 | gint src_width; |
| 222 | gint src_height; |
| 223 | gsize dw_size; |
le.han | 30f126e | 2024-10-09 02:42:55 +0000 | [diff] [blame] | 224 | gint dw_mode; |
| 225 | gint stride; |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 226 | gint par_n; |
| 227 | gint par_d; |
| 228 | gint fps_n; |
| 229 | gint fps_d; |
fei.deng | 3a374e5 | 2024-10-29 17:04:42 +0800 | [diff] [blame] | 230 | gint video_latency; |
| 231 | gboolean set_video_latency; |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 232 | gboolean force_aspect_ratio; |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 233 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 234 | /* rotation and ge2d */ |
| 235 | aml_ge2d_info_t *pge2dinfo; |
| 236 | aml_ge2d_t amlge2d; |
| 237 | ROTBuffer* rot_buffer; |
| 238 | ROTATION_DEGREE rot_degree; |
| 239 | gboolean rot_changed; |
| 240 | gboolean rot_enable_property; |
| 241 | |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 242 | #if GST_IMPORT_LGE_PROP |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 243 | GstAmlVideoSinkLgeCtxt lge_ctxt; |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 244 | #endif |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 245 | }; |
| 246 | |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 247 | typedef struct bufferInfo |
| 248 | { |
| 249 | GstAmlVideoSink *sink; |
| 250 | GstBuffer *buf; |
| 251 | } bufferInfo; |
| 252 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 253 | static guint g_signals[LAST_SIGNAL]= {0}; |
| 254 | |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 255 | static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE( |
| 256 | "sink", GST_PAD_SINK, GST_PAD_ALWAYS, |
| 257 | GST_STATIC_CAPS( |
| 258 | GST_VIDEO_CAPS_MAKE(AML_VIDEO_FORMATS) ";" GST_VIDEO_CAPS_MAKE_WITH_FEATURES( |
| 259 | GST_CAPS_FEATURE_MEMORY_DMABUF, AML_VIDEO_FORMATS))); |
| 260 | |
| 261 | GST_DEBUG_CATEGORY(gst_aml_video_sink_debug); |
| 262 | #define GST_CAT_DEFAULT gst_aml_video_sink_debug |
| 263 | #define gst_aml_video_sink_parent_class parent_class |
xuesong.jiang | 192316f | 2021-10-27 14:51:56 +0800 | [diff] [blame] | 264 | // #define GST_AML_VIDEO_SINK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GST_TYPE_AML_VIDEO_SINK, GstAmlVideoSinkPrivate)) |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 265 | G_DEFINE_TYPE_WITH_CODE(GstAmlVideoSink, gst_aml_video_sink, |
| 266 | GST_TYPE_VIDEO_SINK, G_ADD_PRIVATE(GstAmlVideoSink)); |
| 267 | |
| 268 | /* public interface define */ |
| 269 | static void gst_aml_video_sink_get_property(GObject *object, guint prop_id, |
| 270 | GValue *value, GParamSpec *pspec); |
| 271 | static void gst_aml_video_sink_set_property(GObject *object, guint prop_id, |
| 272 | const GValue *value, |
| 273 | GParamSpec *pspec); |
| 274 | static void gst_aml_video_sink_finalize(GObject *object); |
xuesong.jiang | 6903199 | 2022-06-09 19:30:35 +0800 | [diff] [blame] | 275 | static GstStateChangeReturn gst_aml_video_sink_change_state(GstElement *element, GstStateChange transition); |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 276 | static gboolean gst_aml_video_sink_query(GstElement *element, GstQuery *query); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 277 | static gboolean gst_aml_video_sink_propose_allocation(GstBaseSink *bsink, GstQuery *query); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 278 | static GstCaps *gst_aml_video_sink_get_caps(GstBaseSink *bsink, |
| 279 | GstCaps *filter); |
| 280 | static gboolean gst_aml_video_sink_set_caps(GstBaseSink *bsink, GstCaps *caps); |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 281 | static gboolean gst_aml_video_sink_show_frame(GstVideoSink *bsink, GstBuffer *buffer); |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 282 | static GstFlowReturn gst_aml_video_sink_show_frame_ex(GstVideoSink *vsink, GstBuffer *buffer); |
xuesong.jiang | 22afe86 | 2022-11-09 16:27:33 +0800 | [diff] [blame] | 283 | static gboolean gst_aml_video_sink_pad_event (GstBaseSink *basesink, GstEvent *event); |
xuesong.jiang | 6903199 | 2022-06-09 19:30:35 +0800 | [diff] [blame] | 284 | static gboolean gst_aml_video_sink_send_event(GstElement *element, GstEvent *event); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 285 | |
| 286 | /* private interface define */ |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 287 | static gboolean gst_aml_video_sink_check_buf(GstAmlVideoSink *sink, GstBuffer *buffer); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 288 | static void gst_aml_video_sink_reset_private(GstAmlVideoSink *sink); |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 289 | static void gst_render_msg_callback(void *userData, RenderMsgType type, void *msg); |
| 290 | static int gst_render_val_callback(void *userData, int key, void *value); |
| 291 | static gboolean gst_aml_video_sink_tunnel_buf(GstAmlVideoSink *vsink, GstBuffer *gst_buf, RenderBuffer *tunnel_lib_buf_wrap); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 292 | static gboolean gst_get_mediasync_instanceid(GstAmlVideoSink *vsink); |
le.han | 9ff888d | 2024-09-09 03:04:31 +0000 | [diff] [blame] | 293 | static void gst_set_report_info(void *userData, RenderMsgType type, int64_t pts, int64_t duration); |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 294 | static int get_rotation_buffer_idx(GstAmlVideoSink *vsink); |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 295 | |
xuesong.jiang | 16983c9 | 2021-12-30 10:57:17 +0800 | [diff] [blame] | 296 | #if GST_USE_PLAYBIN |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 297 | static GstElement *gst_aml_video_sink_find_audio_sink(GstAmlVideoSink *sink); |
xuesong.jiang | 16983c9 | 2021-12-30 10:57:17 +0800 | [diff] [blame] | 298 | #endif |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 299 | static gboolean gst_render_set_params(GstVideoSink *vsink); |
fei.deng | ab16ff1 | 2024-08-07 17:58:07 +0800 | [diff] [blame] | 300 | //static void gst_aml_video_sink_dump_stat(GstAmlVideoSink *sink, const gchar *file_name); |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 301 | static gpointer detection_thread(gpointer data); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 302 | |
| 303 | /* public interface definition */ |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 304 | static void gst_aml_video_sink_class_init(GstAmlVideoSinkClass *klass) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 305 | { |
| 306 | GObjectClass *gobject_class; |
| 307 | GstElementClass *gstelement_class; |
| 308 | GstBaseSinkClass *gstbasesink_class; |
| 309 | GstVideoSinkClass *gstvideosink_class; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 310 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 311 | gobject_class = (GObjectClass *)klass; |
| 312 | gstelement_class = (GstElementClass *)klass; |
| 313 | gstbasesink_class = (GstBaseSinkClass *)klass; |
| 314 | gstvideosink_class = (GstVideoSinkClass *)klass; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 315 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 316 | gobject_class->set_property = gst_aml_video_sink_set_property; |
| 317 | gobject_class->get_property = gst_aml_video_sink_get_property; |
| 318 | gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_aml_video_sink_finalize); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 319 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 320 | gst_element_class_add_static_pad_template(gstelement_class, &sink_template); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 321 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 322 | gst_element_class_set_static_metadata( |
| 323 | gstelement_class, "aml video sink", "Sink/Video", |
| 324 | "Output to video tunnel lib", |
| 325 | "Xuesong.Jiang@amlogic.com<Xuesong.Jiang@amlogic.com>"); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 326 | |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 327 | gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_aml_video_sink_change_state); |
| 328 | gstelement_class->query = GST_DEBUG_FUNCPTR(gst_aml_video_sink_query); |
xuesong.jiang | 6903199 | 2022-06-09 19:30:35 +0800 | [diff] [blame] | 329 | gstelement_class->send_event = GST_DEBUG_FUNCPTR(gst_aml_video_sink_send_event); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 330 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 331 | gstbasesink_class->propose_allocation = GST_DEBUG_FUNCPTR(gst_aml_video_sink_propose_allocation); |
| 332 | gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR(gst_aml_video_sink_get_caps); |
| 333 | gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR(gst_aml_video_sink_set_caps); |
xuesong.jiang | 22afe86 | 2022-11-09 16:27:33 +0800 | [diff] [blame] | 334 | gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_aml_video_sink_pad_event); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 335 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 336 | gstvideosink_class->show_frame = GST_DEBUG_FUNCPTR(gst_aml_video_sink_show_frame_ex); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 337 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 338 | g_object_class_install_property( |
| 339 | gobject_class, PROP_FULLSCREEN, |
| 340 | g_param_spec_boolean("fullscreen", "Fullscreen", |
| 341 | "Whether the surface should be made fullscreen ", |
| 342 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 343 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 344 | g_object_class_install_property( |
xuesong.jiang | a507a4b | 2022-10-28 16:28:29 +0800 | [diff] [blame] | 345 | gobject_class, PROP_DEFAULT_SYNC, |
| 346 | g_param_spec_boolean("set-sync", "use basesink avsync", |
| 347 | "Whether use basesink sync flow. Configure when make element ", |
| 348 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
| 349 | |
| 350 | g_object_class_install_property( |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 351 | gobject_class, PROP_IMMEDIATELY_RENDER, |
| 352 | g_param_spec_int("set-immediately-render", "set immediately render", |
| 353 | "set renderlib immediately render ", |
| 354 | G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); |
| 355 | |
| 356 | g_object_class_install_property( |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 357 | gobject_class, PROP_SETMUTE, |
| 358 | g_param_spec_boolean("set mute", "set mute params", |
| 359 | "Whether set screen mute ", |
| 360 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 361 | |
le.han | b62dfce | 2024-02-28 03:23:12 +0000 | [diff] [blame] | 362 | g_object_class_install_property ( |
| 363 | gobject_class, PROP_KEEP_LAST_FRAME_ON_FLUSH, |
| 364 | g_param_spec_boolean ("keep-last-frame-on-flush", |
| 365 | "set keep last frame on flush or not,default is keep last frame", |
| 366 | "0: clean; 1: keep", TRUE, G_PARAM_READWRITE)); |
| 367 | |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 368 | g_object_class_install_property( |
| 369 | G_OBJECT_CLASS(klass), PROP_AVSYNC_MODE, |
| 370 | g_param_spec_int("avsync-mode", "avsync mode", |
| 371 | "Vmaster(0) Amaster(1) PCRmaster(2) IPTV(3) FreeRun(4)", |
| 372 | G_MININT, G_MAXINT, 0, G_PARAM_WRITABLE)); |
xuesong.jiang | 62ed50e | 2022-04-13 16:55:47 +0800 | [diff] [blame] | 373 | |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 374 | g_object_class_install_property( |
| 375 | G_OBJECT_CLASS(klass), PROP_VIDEO_FRAME_DROP_NUM, |
| 376 | g_param_spec_int("frames-dropped", "frames-dropped", |
| 377 | "number of dropped frames", |
| 378 | 0, G_MAXINT32, 0, G_PARAM_READABLE)); |
xuesong.jiang | 1a9c282 | 2022-04-24 11:35:07 +0800 | [diff] [blame] | 379 | |
| 380 | g_object_class_install_property( |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 381 | gobject_class, PROP_VIDEO_FRAME_DISPLAY_NUM, |
| 382 | g_param_spec_int("display-frame-num", "display frame num", |
| 383 | "number of displayed frames ", |
| 384 | 0, G_MAXINT32, 0, G_PARAM_READABLE)); |
| 385 | |
| 386 | g_object_class_install_property( |
kaiqiang.xiang | 5581e8e | 2024-07-23 10:39:41 +0800 | [diff] [blame] | 387 | G_OBJECT_CLASS (klass), PROP_VIDEO_PTS, |
kaiqiang.xiang | ecbc171 | 2024-07-24 15:29:38 +0800 | [diff] [blame] | 388 | g_param_spec_int64 ("video-pts", "video PTS", |
kaiqiang.xiang | 5581e8e | 2024-07-23 10:39:41 +0800 | [diff] [blame] | 389 | "current video PTS value", |
| 390 | G_MININT64, G_MAXINT64, 0, G_PARAM_READABLE)); |
| 391 | |
| 392 | g_object_class_install_property( |
xuesong.jiang | 1a9c282 | 2022-04-24 11:35:07 +0800 | [diff] [blame] | 393 | G_OBJECT_CLASS(klass), PROP_WINDOW_SET, |
| 394 | g_param_spec_string("rectangle", "rectangle", |
| 395 | "Window Set Format: x,y,width,height", |
| 396 | NULL, G_PARAM_WRITABLE)); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 397 | |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 398 | g_object_class_install_property( |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 399 | G_OBJECT_CLASS(klass), PROP_RES_USAGE, |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 400 | g_param_spec_int("res-usage", "res-usage", |
| 401 | "Flags to indicate intended usage", |
| 402 | G_MININT, G_MAXINT, 0, G_PARAM_WRITABLE)); |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 403 | |
xuesong.jiang | 5eb0171 | 2022-10-21 19:47:54 +0800 | [diff] [blame] | 404 | g_object_class_install_property( |
| 405 | G_OBJECT_CLASS(klass), PROP_DISPLAY_OUTPUT, |
| 406 | g_param_spec_int("display-output", "display output index", |
| 407 | "display output index, 0 is primary output and default value; 1 is extend display output", |
| 408 | G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); |
| 409 | |
fei.deng | 978b242 | 2023-11-30 10:33:23 +0000 | [diff] [blame] | 410 | g_object_class_install_property( |
| 411 | G_OBJECT_CLASS(klass), PROP_SHOW_FIRST_FRAME_ASAP, |
| 412 | g_param_spec_boolean("show-first-frame-asap", "show first video frame asap", |
| 413 | "Whether showing first video frame asap, default is disable", |
| 414 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 415 | g_object_class_install_property ( |
| 416 | G_OBJECT_CLASS(klass), PROP_ENABLE_USER_RENDERING, |
| 417 | g_param_spec_boolean ("enable-user-rendering", |
| 418 | "enable signal decoded buffer to user to rendering", |
| 419 | "0: disable; 1: enable", |
| 420 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
fei.deng | 978b242 | 2023-11-30 10:33:23 +0000 | [diff] [blame] | 421 | |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 422 | g_object_class_install_property( |
| 423 | G_OBJECT_CLASS(klass), PROP_ZORDER, |
| 424 | g_param_spec_int("zorder", "video plane zorder", |
| 425 | "video plane zorder", |
| 426 | G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); |
| 427 | |
fei.deng | 3a374e5 | 2024-10-29 17:04:42 +0800 | [diff] [blame] | 428 | g_object_class_install_property( |
| 429 | G_OBJECT_CLASS(klass), PRO_VIDEO_LATENCY, |
| 430 | g_param_spec_int("video-latency", "video latency", |
| 431 | "video extra latency,the unit of value is us", |
| 432 | G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); |
| 433 | |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 434 | /* |
| 435 | * frame-step-on-preroll is for nts case VPEEK-001-TC2 |
| 436 | * case step: |
| 437 | * 1.change pipeline state from null to pause |
| 438 | * 2.send a frame |
| 439 | * 3.invoke frame-step-on-preroll property |
| 440 | */ |
| 441 | g_object_class_install_property ( |
| 442 | G_OBJECT_CLASS(klass), PROP_FRAME_STEP_ON_PREROLL, |
| 443 | g_param_spec_boolean ("frame-step-on-preroll", |
| 444 | "frame step on preroll", |
| 445 | "allow frame stepping on preroll into pause", |
| 446 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
| 447 | |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 448 | g_object_class_install_property ( |
| 449 | G_OBJECT_CLASS(klass), PROP_FORCE_ASPECT_RATIO, |
| 450 | g_param_spec_boolean ("force-aspect-ratio", |
| 451 | "force aspect ratio", |
| 452 | "When enabled scaling respects source aspect ratio", FALSE, G_PARAM_READWRITE)); |
| 453 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 454 | g_signals[SIGNAL_FIRSTFRAME]= g_signal_new( "first-video-frame-callback", |
| 455 | G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)), |
| 456 | (GSignalFlags) (G_SIGNAL_RUN_LAST), |
| 457 | 0, /* class offset */ |
| 458 | NULL, /* accumulator */ |
| 459 | NULL, /* accu data */ |
| 460 | g_cclosure_marshal_VOID__UINT_POINTER, |
| 461 | G_TYPE_NONE, |
| 462 | 2, |
| 463 | G_TYPE_UINT, |
| 464 | G_TYPE_POINTER ); |
| 465 | |
| 466 | g_signals[SIGNAL_UNDERFLOW]= g_signal_new( "buffer-underflow-callback", |
| 467 | G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)), |
| 468 | (GSignalFlags) (G_SIGNAL_RUN_LAST), |
| 469 | 0, // class offset |
| 470 | NULL, // accumulator |
| 471 | NULL, // accu data |
| 472 | g_cclosure_marshal_VOID__UINT_POINTER, |
| 473 | G_TYPE_NONE, |
| 474 | 2, |
| 475 | G_TYPE_UINT, |
| 476 | G_TYPE_POINTER ); |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 477 | g_signals[SIGNAL_DECODEDBUFFER]= g_signal_new ("decoded-buffer-callback", |
| 478 | G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)), |
| 479 | (GSignalFlags) (G_SIGNAL_RUN_FIRST), |
| 480 | 0, /* class offset */ |
| 481 | NULL, /* accumulator */ |
| 482 | NULL, /* accu data */ |
| 483 | NULL, |
| 484 | G_TYPE_NONE, |
| 485 | 1, |
| 486 | GST_TYPE_BUFFER); |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 487 | g_signals[SIGNAL_FRAMEFREEZE]= g_signal_new( "video-frame-freeze", |
| 488 | G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)), |
| 489 | (GSignalFlags) (G_SIGNAL_RUN_LAST), |
| 490 | 0, /* class offset */ |
| 491 | NULL, /* accumulator */ |
| 492 | NULL, /* accu data */ |
| 493 | NULL, |
| 494 | G_TYPE_NONE, |
| 495 | 2, |
| 496 | G_TYPE_INT64, |
| 497 | G_TYPE_INT64); |
| 498 | g_signals[SIGNAL_RESYNC]= g_signal_new( "av-resync", |
| 499 | G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)), |
| 500 | (GSignalFlags) (G_SIGNAL_RUN_LAST), |
| 501 | 0, /* class offset */ |
| 502 | NULL, /* accumulator */ |
| 503 | NULL, /* accu data */ |
| 504 | NULL, |
| 505 | G_TYPE_NONE, |
| 506 | 2, |
| 507 | G_TYPE_INT64, |
| 508 | G_TYPE_INT64); |
| 509 | g_signals[SIGNAL_FRAMEDROP]= g_signal_new( "video-frame-drop", |
| 510 | G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)), |
| 511 | (GSignalFlags) (G_SIGNAL_RUN_LAST), |
| 512 | 0, /* class offset */ |
| 513 | NULL, /* accumulator */ |
| 514 | NULL, /* accu data */ |
| 515 | NULL, |
| 516 | G_TYPE_NONE, |
| 517 | 1, |
| 518 | G_TYPE_INT64); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 519 | #if GST_IMPORT_LGE_PROP |
| 520 | g_object_class_install_property( |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 521 | G_OBJECT_CLASS(klass), PROP_LGE_RESOURCE_INFO, |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 522 | g_param_spec_object("resource-info", "resource-info", |
| 523 | "After acquisition of H/W resources is completed, allocated resource information must be delivered to the decoder and the sink", |
| 524 | GST_TYPE_STRUCTURE, |
| 525 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); |
| 526 | |
| 527 | g_object_class_install_property( |
| 528 | G_OBJECT_CLASS(klass), PROP_LGE_CURRENT_PTS, |
| 529 | g_param_spec_uint64("current-pts", "current pts", |
| 530 | "get rendering timing video position", |
| 531 | 0, G_MAXUINT64, |
| 532 | 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
| 533 | |
| 534 | g_object_class_install_property( |
| 535 | G_OBJECT_CLASS(klass), PROP_LGE_INTERLEAVING_TYPE, |
| 536 | g_param_spec_uint("interleaving-type", "interleaving type", |
| 537 | "set 3D type", |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 538 | 0, G_MAXUINT, |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 539 | 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
| 540 | |
| 541 | g_object_class_install_property( |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 542 | G_OBJECT_CLASS(klass), PROP_LGE_APP_TYPE, |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 543 | g_param_spec_string("app-type", "app-type", |
| 544 | "set application type.", |
| 545 | "default_app", |
| 546 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
| 547 | |
| 548 | g_object_class_install_property( |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 549 | G_OBJECT_CLASS(klass), PROP_LGE_SYNC, |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 550 | g_param_spec_boolean("sync", "sync", |
| 551 | "M16, H15, K2L", |
| 552 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
| 553 | |
| 554 | g_object_class_install_property( |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 555 | G_OBJECT_CLASS(klass), PROP_LGE_DISH_TRICK, |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 556 | g_param_spec_boolean("dish-trick", "dish trick", |
| 557 | "H15, M16", |
| 558 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
| 559 | |
| 560 | g_object_class_install_property( |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 561 | G_OBJECT_CLASS(klass), PROP_LGE_DISH_TRICK_IGNORE_RATE, |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 562 | g_param_spec_boolean("dish-trick-ignore-rate", "dish trick ignore rate", |
| 563 | "H15, M16", |
| 564 | FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
| 565 | #endif |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 566 | |
| 567 | g_object_class_install_property ( |
| 568 | G_OBJECT_CLASS (klass), PROP_VIDEO_ROTATION, |
| 569 | g_param_spec_int ("video-rotation", "video-rotation", |
| 570 | "video rotation", |
| 571 | 0, 3, 0, G_PARAM_WRITABLE)); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 572 | } |
| 573 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 574 | static void gst_aml_video_sink_init(GstAmlVideoSink *sink) |
| 575 | { |
| 576 | GstBaseSink *basesink = (GstBaseSink *)sink; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 577 | |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 578 | sink->last_displayed_buf_pts = 0; |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 579 | sink->last_dec_buf_pts = GST_CLOCK_TIME_NONE; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 580 | /* init eos detect */ |
| 581 | sink->queued = 0; |
| 582 | sink->dequeued = 0; |
| 583 | sink->rendered = 0; |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 584 | sink->dropped = 0; |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 585 | sink->avsync_mode = GST_DEFAULT_AVSYNC_MODE; |
xuesong.jiang | a507a4b | 2022-10-28 16:28:29 +0800 | [diff] [blame] | 586 | sink->default_sync = FALSE; |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 587 | sink->immediately_render = 0; |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 588 | sink->pip_mode = 0; |
xuesong.jiang | 5eb0171 | 2022-10-21 19:47:54 +0800 | [diff] [blame] | 589 | sink->display_output_index = 0; |
sheng.liu | c9f3496 | 2022-06-17 21:42:48 +0800 | [diff] [blame] | 590 | sink->secure_mode = FALSE; |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 591 | sink->detect_thread_handle = NULL; |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 592 | sink->quit_eos_detect_thread = FALSE; |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 593 | sink->rotation_thread_handle = NULL; |
| 594 | sink->quit_rotation_thread = FALSE; |
| 595 | sink->buffer_queue = gst_queue_array_new (ROT_QUEUE_MAX); |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 596 | sink->frame_rate_num = 0; |
| 597 | sink->frame_rate_denom = 0; |
| 598 | sink->frame_rate_changed = FALSE; |
| 599 | sink->frame_rate = 0.0; |
sheng.liu | 1a07969 | 2023-12-26 06:33:41 +0000 | [diff] [blame] | 600 | sink->pixel_aspect_ratio_changed = FALSE; |
| 601 | sink->pixel_aspect_ratio = 1.0; |
le.han | b62dfce | 2024-02-28 03:23:12 +0000 | [diff] [blame] | 602 | sink->keep_last_frame_on_flush = TRUE; |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 603 | //sink->enable_decoded_buffer_signal = FALSE; |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 604 | sink->zorder = 0; |
| 605 | sink->update_zorder = FALSE; |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 606 | g_mutex_init(&sink->eos_lock); |
| 607 | g_cond_init(&sink->eos_cond); |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 608 | g_mutex_init(&sink->report_info_lock); |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 609 | g_mutex_init(&sink->rotation_buffer_lock); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 610 | |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 611 | GST_AML_VIDEO_SINK_GET_PRIVATE(sink) = malloc(sizeof(GstAmlVideoSinkPrivate)); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 612 | gst_aml_video_sink_reset_private(sink); |
xuesong.jiang | d261956 | 2021-12-23 16:38:50 +0800 | [diff] [blame] | 613 | gst_base_sink_set_sync(basesink, FALSE); |
xuesong.jiang | fc27c27 | 2022-05-11 17:09:02 +0800 | [diff] [blame] | 614 | |
| 615 | gst_base_sink_set_qos_enabled(basesink, FALSE); |
xuesong.jiang | 41e0e12 | 2023-02-02 19:25:16 +0800 | [diff] [blame] | 616 | gst_base_sink_set_last_sample_enabled(basesink, FALSE); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 617 | } |
| 618 | |
| 619 | static void gst_aml_video_sink_get_property(GObject *object, guint prop_id, |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 620 | GValue *value, GParamSpec *pspec) |
| 621 | { |
| 622 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(object); |
| 623 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 624 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 625 | switch (prop_id) |
| 626 | { |
| 627 | case PROP_FULLSCREEN: |
| 628 | GST_OBJECT_LOCK(sink); |
| 629 | g_value_set_boolean(value, sink_priv->fullscreen); |
| 630 | GST_OBJECT_UNLOCK(sink); |
| 631 | break; |
| 632 | case PROP_SETMUTE: |
| 633 | GST_OBJECT_LOCK(sink); |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 634 | g_value_set_boolean(value, sink_priv->mute); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 635 | GST_OBJECT_UNLOCK(sink); |
| 636 | break; |
xuesong.jiang | a507a4b | 2022-10-28 16:28:29 +0800 | [diff] [blame] | 637 | case PROP_DEFAULT_SYNC: |
| 638 | GST_OBJECT_LOCK(sink); |
| 639 | g_value_set_boolean(value, sink->default_sync); |
| 640 | GST_OBJECT_UNLOCK(sink); |
| 641 | break; |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 642 | case PROP_IMMEDIATELY_RENDER: |
| 643 | GST_OBJECT_LOCK(sink); |
| 644 | g_value_set_int(value, sink->immediately_render); |
| 645 | GST_OBJECT_UNLOCK(sink); |
| 646 | break; |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 647 | case PROP_AVSYNC_MODE: |
| 648 | GST_OBJECT_LOCK(sink); |
| 649 | g_value_set_boolean(value, sink->avsync_mode); |
| 650 | GST_OBJECT_UNLOCK(sink); |
| 651 | break; |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 652 | case PROP_VIDEO_FRAME_DROP_NUM: |
xuesong.jiang | 62ed50e | 2022-04-13 16:55:47 +0800 | [diff] [blame] | 653 | GST_OBJECT_LOCK(sink); |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 654 | GST_DEBUG_OBJECT(sink, "app get frame drop num | queued:%d, dequeued:%d, dropped:%d, rendered:%d", |
| 655 | sink->queued, sink->dequeued, sink->dropped, sink->rendered); |
| 656 | g_value_set_int(value, sink->dropped); |
xuesong.jiang | 62ed50e | 2022-04-13 16:55:47 +0800 | [diff] [blame] | 657 | GST_OBJECT_UNLOCK(sink); |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 658 | break; |
kaiqiang.xiang | 5581e8e | 2024-07-23 10:39:41 +0800 | [diff] [blame] | 659 | case PROP_VIDEO_PTS: |
| 660 | { |
| 661 | GST_OBJECT_LOCK(sink); |
| 662 | gint64 currentPTS = sink->last_displayed_buf_pts; |
| 663 | GST_OBJECT_UNLOCK(sink); |
kaiqiang.xiang | ecbc171 | 2024-07-24 15:29:38 +0800 | [diff] [blame] | 664 | //90K |
| 665 | currentPTS = gst_util_uint64_scale_int (currentPTS, PTS_90K, GST_SECOND); |
kaiqiang.xiang | 5581e8e | 2024-07-23 10:39:41 +0800 | [diff] [blame] | 666 | g_value_set_int64(value, currentPTS); |
| 667 | break; |
| 668 | } |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 669 | case PROP_VIDEO_FRAME_DISPLAY_NUM: |
| 670 | GST_OBJECT_LOCK(sink); |
| 671 | GST_DEBUG_OBJECT(sink, "displayed frame num: %d", sink->queued); |
| 672 | g_value_set_int(value, sink->queued); |
| 673 | GST_OBJECT_UNLOCK(sink); |
| 674 | break; |
xuesong.jiang | 5eb0171 | 2022-10-21 19:47:54 +0800 | [diff] [blame] | 675 | case PROP_DISPLAY_OUTPUT: |
| 676 | { |
| 677 | GST_OBJECT_LOCK(sink); |
| 678 | g_value_set_int(value, sink->display_output_index); |
| 679 | GST_OBJECT_UNLOCK(sink); |
| 680 | break; |
| 681 | } |
le.han | b62dfce | 2024-02-28 03:23:12 +0000 | [diff] [blame] | 682 | case PROP_KEEP_LAST_FRAME_ON_FLUSH: |
| 683 | { |
| 684 | GST_OBJECT_LOCK(sink); |
| 685 | g_value_set_boolean(value, sink->keep_last_frame_on_flush); |
| 686 | GST_OBJECT_UNLOCK(sink); |
| 687 | break; |
| 688 | } |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 689 | case PROP_ENABLE_USER_RENDERING: |
| 690 | { |
| 691 | GST_OBJECT_LOCK(sink); |
| 692 | g_value_set_boolean(value, sink->enable_decoded_buffer_signal); |
| 693 | GST_OBJECT_UNLOCK(sink); |
| 694 | break; |
| 695 | } |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 696 | case PROP_ZORDER: |
| 697 | { |
| 698 | GST_OBJECT_LOCK(sink); |
| 699 | g_value_set_int(value, sink->zorder); |
| 700 | GST_OBJECT_UNLOCK(sink); |
| 701 | break; |
| 702 | } |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 703 | case PROP_FRAME_STEP_ON_PREROLL: |
| 704 | { |
| 705 | GST_OBJECT_LOCK(sink); |
| 706 | g_value_set_boolean(value, sink_priv->frame_step_on_preroll); |
| 707 | GST_OBJECT_UNLOCK(sink); |
| 708 | break; |
| 709 | } |
fei.deng | 3a374e5 | 2024-10-29 17:04:42 +0800 | [diff] [blame] | 710 | case PRO_VIDEO_LATENCY: |
| 711 | { |
| 712 | GST_OBJECT_LOCK(sink); |
| 713 | g_value_set_int(value, sink_priv->video_latency); |
| 714 | GST_OBJECT_UNLOCK(sink); |
| 715 | break; |
| 716 | } |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 717 | case PROP_FORCE_ASPECT_RATIO: |
| 718 | { |
| 719 | g_value_set_boolean(value, sink_priv->force_aspect_ratio); |
| 720 | break; |
| 721 | } |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 722 | #if GST_IMPORT_LGE_PROP |
| 723 | case PROP_LGE_CURRENT_PTS: |
| 724 | { |
| 725 | GST_OBJECT_LOCK(sink); |
| 726 | g_value_set_uint64(value, sink->last_displayed_buf_pts); |
| 727 | GST_OBJECT_UNLOCK(sink); |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 728 | break; |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 729 | } |
| 730 | #endif |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 731 | default: |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 732 | // G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 733 | break; |
| 734 | } |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 735 | } |
| 736 | |
| 737 | static void gst_aml_video_sink_set_property(GObject *object, guint prop_id, |
| 738 | const GValue *value, |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 739 | GParamSpec *pspec) |
| 740 | { |
| 741 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(object); |
| 742 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 743 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 744 | switch (prop_id) |
| 745 | { |
| 746 | case PROP_FULLSCREEN: |
| 747 | GST_OBJECT_LOCK(sink); |
| 748 | gboolean is_fullscreen = g_value_get_boolean(value); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 749 | if (sink_priv->fullscreen != is_fullscreen) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 750 | { |
| 751 | sink_priv->fullscreen = is_fullscreen; |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 752 | // TODO set full screen to tunnel lib |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 753 | } |
| 754 | GST_OBJECT_UNLOCK(sink); |
| 755 | break; |
| 756 | case PROP_SETMUTE: |
| 757 | GST_OBJECT_LOCK(sink); |
| 758 | gboolean is_mute = g_value_get_boolean(value); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 759 | if (sink_priv->mute != is_mute) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 760 | { |
xuesong.jiang | 75ef01c | 2021-12-09 17:08:52 +0800 | [diff] [blame] | 761 | sink_priv->mute = is_mute; |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 762 | // TODO set full screen to tunnel lib |
| 763 | } |
| 764 | GST_OBJECT_UNLOCK(sink); |
| 765 | break; |
xuesong.jiang | a507a4b | 2022-10-28 16:28:29 +0800 | [diff] [blame] | 766 | case PROP_DEFAULT_SYNC: |
| 767 | { |
| 768 | GST_OBJECT_LOCK(sink); |
| 769 | sink->default_sync = g_value_get_boolean(value); |
| 770 | GST_OBJECT_UNLOCK(sink); |
xuesong.jiang | 22afe86 | 2022-11-09 16:27:33 +0800 | [diff] [blame] | 771 | gst_base_sink_set_sync(GST_BASE_SINK(sink), sink->default_sync); |
xuesong.jiang | a507a4b | 2022-10-28 16:28:29 +0800 | [diff] [blame] | 772 | GST_DEBUG_OBJECT(sink, "use basessink avsync flow %d", sink->default_sync); |
| 773 | break; |
| 774 | } |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 775 | case PROP_IMMEDIATELY_RENDER: |
| 776 | { |
| 777 | GST_OBJECT_LOCK(sink); |
| 778 | sink->immediately_render = g_value_get_int(value); |
| 779 | GST_OBJECT_UNLOCK(sink); |
| 780 | GST_DEBUG_OBJECT(sink, "set renderlib immediately render %d", sink->immediately_render); |
| 781 | break; |
| 782 | } |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 783 | case PROP_AVSYNC_MODE: |
| 784 | GST_OBJECT_LOCK(sink); |
| 785 | gint mode = g_value_get_int(value); |
| 786 | if (mode >= 0) |
| 787 | { |
| 788 | sink->avsync_mode = mode; |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 789 | GST_DEBUG_OBJECT(sink, "AV sync mode %d", mode); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 790 | } |
| 791 | GST_OBJECT_UNLOCK(sink); |
| 792 | break; |
xuesong.jiang | 1a9c282 | 2022-04-24 11:35:07 +0800 | [diff] [blame] | 793 | case PROP_WINDOW_SET: |
| 794 | { |
| 795 | const gchar *str = g_value_get_string(value); |
| 796 | gchar **parts = g_strsplit(str, ",", 4); |
| 797 | |
| 798 | if (!parts[0] || !parts[1] || !parts[2] || !parts[3]) |
| 799 | { |
| 800 | GST_ERROR("Bad window properties string"); |
| 801 | } |
| 802 | else |
| 803 | { |
| 804 | int nx, ny, nw, nh; |
| 805 | nx = atoi(parts[0]); |
| 806 | ny = atoi(parts[1]); |
| 807 | nw = atoi(parts[2]); |
| 808 | nh = atoi(parts[3]); |
| 809 | |
| 810 | if ((nx != sink_priv->window_set.x) || |
| 811 | (ny != sink_priv->window_set.y) || |
| 812 | (nw != sink_priv->window_set.w) || |
| 813 | (nh != sink_priv->window_set.h)) |
| 814 | { |
| 815 | GST_OBJECT_LOCK(sink); |
| 816 | sink_priv->window_set.window_change = true; |
| 817 | sink_priv->window_set.x = nx; |
| 818 | sink_priv->window_set.y = ny; |
| 819 | sink_priv->window_set.w = nw; |
| 820 | sink_priv->window_set.h = nh; |
| 821 | |
| 822 | GST_DEBUG("set window rect (%d,%d,%d,%d)\n", |
| 823 | sink_priv->window_set.x, |
| 824 | sink_priv->window_set.y, |
| 825 | sink_priv->window_set.w, |
| 826 | sink_priv->window_set.h); |
| 827 | GST_OBJECT_UNLOCK(sink); |
| 828 | } |
| 829 | } |
| 830 | |
| 831 | g_strfreev(parts); |
| 832 | break; |
| 833 | } |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 834 | case PROP_RES_USAGE: |
| 835 | { |
| 836 | GST_OBJECT_LOCK(sink); |
| 837 | sink->pip_mode = 1; |
| 838 | GST_DEBUG_OBJECT(sink, "play video in sub layer(pip)"); |
| 839 | GST_OBJECT_UNLOCK(sink); |
| 840 | break; |
| 841 | } |
xuesong.jiang | 5eb0171 | 2022-10-21 19:47:54 +0800 | [diff] [blame] | 842 | case PROP_DISPLAY_OUTPUT: |
| 843 | { |
| 844 | GST_OBJECT_LOCK(sink); |
| 845 | gint index = g_value_get_int(value); |
| 846 | if (index == 0 || index == 1) |
| 847 | { |
| 848 | sink->display_output_index = index; |
| 849 | if (sink_priv->render_device_handle) |
| 850 | { |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 851 | if (render_set_value(sink_priv->render_device_handle, KEY_SELECT_DISPLAY_OUTPUT, &sink->display_output_index) == -1) |
| 852 | GST_ERROR_OBJECT(sink, "render lib update output index error"); |
xuesong.jiang | 5eb0171 | 2022-10-21 19:47:54 +0800 | [diff] [blame] | 853 | } |
| 854 | } |
| 855 | GST_DEBUG_OBJECT(sink, "update display output index to:%d", sink->display_output_index); |
| 856 | GST_OBJECT_UNLOCK(sink); |
| 857 | break; |
| 858 | } |
fei.deng | 978b242 | 2023-11-30 10:33:23 +0000 | [diff] [blame] | 859 | case PROP_SHOW_FIRST_FRAME_ASAP: |
| 860 | { |
| 861 | sink_priv->show_first_frame_asap = g_value_get_boolean(value); |
| 862 | GST_DEBUG_OBJECT(sink, "set show first frame asap %d",sink_priv->show_first_frame_asap); |
| 863 | break; |
| 864 | } |
le.han | b62dfce | 2024-02-28 03:23:12 +0000 | [diff] [blame] | 865 | case PROP_KEEP_LAST_FRAME_ON_FLUSH: |
| 866 | { |
| 867 | GST_OBJECT_LOCK(sink); |
| 868 | sink->keep_last_frame_on_flush = g_value_get_boolean(value); |
| 869 | GST_DEBUG_OBJECT(sink, "keep last frame on flush %d", sink->keep_last_frame_on_flush); |
| 870 | GST_OBJECT_UNLOCK(sink); |
| 871 | break; |
| 872 | } |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 873 | case PROP_ENABLE_USER_RENDERING: |
| 874 | { |
| 875 | sink->enable_decoded_buffer_signal = g_value_get_boolean(value); |
| 876 | GST_DEBUG("set enable decoded buffer signal %d", sink->enable_decoded_buffer_signal); |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 877 | } break; |
| 878 | case PROP_ZORDER: |
| 879 | { |
| 880 | GST_OBJECT_LOCK(sink); |
| 881 | sink->zorder = g_value_get_int(value); |
| 882 | sink->update_zorder = TRUE; |
| 883 | GST_DEBUG_OBJECT(sink, "set video plane zorder:%d",sink->zorder); |
| 884 | GST_OBJECT_UNLOCK(sink); |
| 885 | if (sink_priv->render_device_handle) |
| 886 | { |
| 887 | sink->update_zorder = FALSE; |
| 888 | render_set_value(sink_priv->render_device_handle, KEY_ZORDER, &sink->zorder); |
| 889 | } |
| 890 | } break; |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 891 | case PROP_FRAME_STEP_ON_PREROLL: |
| 892 | { |
| 893 | GstBaseSink *basesink; |
| 894 | basesink= GST_BASE_SINK(sink); |
| 895 | sink_priv->frame_step_on_preroll = g_value_get_boolean(value); |
| 896 | GST_ERROR_OBJECT(sink, "frame step on preroll:%d",sink_priv->frame_step_on_preroll); |
| 897 | |
| 898 | GST_BASE_SINK_PREROLL_LOCK(basesink); |
| 899 | if (GST_BASE_SINK(sink)->need_preroll && |
| 900 | GST_BASE_SINK(sink)->have_preroll ) |
| 901 | { |
| 902 | GST_ERROR_OBJECT(sink,"frame step on preroll,Already prerolled"); |
| 903 | GST_BASE_SINK(sink)->need_preroll= FALSE; |
| 904 | GST_BASE_SINK(sink)->have_preroll= TRUE; |
| 905 | } |
| 906 | GST_BASE_SINK_PREROLL_UNLOCK(basesink); |
| 907 | |
| 908 | if (sink_priv->render_device_handle) |
| 909 | { |
| 910 | int trick_mode = VIDEO_TRICK_MODE_NONE; |
| 911 | if (sink_priv->frame_step_on_preroll) { |
| 912 | trick_mode = VIDEO_TRICK_MODE_PAUSE_NEXT; |
| 913 | } |
| 914 | render_set_value(sink_priv->render_device_handle, KEY_VIDEO_TRICK_MODE, &trick_mode); |
| 915 | if (sink->video_playing == FALSE) { |
| 916 | render_resume(sink_priv->render_device_handle); |
| 917 | } |
| 918 | } |
| 919 | } break; |
fei.deng | 3a374e5 | 2024-10-29 17:04:42 +0800 | [diff] [blame] | 920 | case PRO_VIDEO_LATENCY: |
| 921 | { |
| 922 | GST_OBJECT_LOCK(sink); |
| 923 | sink_priv->video_latency = g_value_get_int(value); |
| 924 | sink_priv->set_video_latency = TRUE; |
| 925 | GST_DEBUG_OBJECT(sink, "set video latency:%d us",sink_priv->video_latency); |
| 926 | GST_OBJECT_UNLOCK(sink); |
| 927 | } break; |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 928 | case PROP_FORCE_ASPECT_RATIO: |
| 929 | { |
| 930 | sink_priv->force_aspect_ratio = g_value_get_boolean(value); |
| 931 | GST_DEBUG_OBJECT(sink, "set force aspect ratio:%d",sink_priv->force_aspect_ratio); |
| 932 | if (sink_priv->render_device_handle) |
| 933 | { |
| 934 | int force = sink_priv->force_aspect_ratio? 1: 0; |
| 935 | render_set_value(sink_priv->render_device_handle, KEY_FORCE_ASPECT_RATIO, &force); |
| 936 | } |
| 937 | } break; |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 938 | #if GST_IMPORT_LGE_PROP |
| 939 | case PROP_LGE_RESOURCE_INFO: |
| 940 | { |
| 941 | GST_OBJECT_LOCK(sink); |
| 942 | GstStructure *r_info = g_value_get_object(value); |
| 943 | if (r_info) |
| 944 | { |
| 945 | if (gst_structure_has_field(r_info, "coretype")) |
| 946 | { |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 947 | if (sink_priv->lge_ctxt.res_info.coretype) |
| 948 | { |
| 949 | g_free(sink_priv->lge_ctxt.res_info.coretype); |
| 950 | sink_priv->lge_ctxt.res_info.coretype = NULL; |
| 951 | } |
| 952 | sink_priv->lge_ctxt.res_info.coretype = g_strdup(gst_structure_get_string(r_info, "coretype")); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 953 | } |
| 954 | if (gst_structure_has_field(r_info, "videoport")) |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 955 | gst_structure_get_int(r_info, "videoport", &(sink_priv->lge_ctxt.res_info.videoport)); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 956 | if (gst_structure_has_field(r_info, "audioport")) |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 957 | gst_structure_get_int(r_info, "audioport", &(sink_priv->lge_ctxt.res_info.audioport)); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 958 | if (gst_structure_has_field(r_info, "maxwidth")) |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 959 | gst_structure_get_int(r_info, "maxwidth", &(sink_priv->lge_ctxt.res_info.maxwidth)); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 960 | if (gst_structure_has_field(r_info, "maxheight")) |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 961 | gst_structure_get_int(r_info, "maxheight", &(sink_priv->lge_ctxt.res_info.maxheight)); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 962 | if (gst_structure_has_field(r_info, "mixerport")) |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 963 | gst_structure_get_int(r_info, "mixerport", &(sink_priv->lge_ctxt.res_info.mixerport)); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 964 | } |
| 965 | GST_OBJECT_UNLOCK(sink); |
| 966 | break; |
| 967 | } |
| 968 | case PROP_LGE_INTERLEAVING_TYPE: |
| 969 | { |
| 970 | GST_OBJECT_LOCK(sink); |
| 971 | guint interlv_type = g_value_get_uint(value); |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 972 | sink_priv->lge_ctxt.interleaving_type = interlv_type; |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 973 | GST_OBJECT_UNLOCK(sink); |
| 974 | break; |
| 975 | } |
| 976 | case PROP_LGE_APP_TYPE: |
| 977 | { |
| 978 | GST_OBJECT_LOCK(sink); |
| 979 | GST_DEBUG_OBJECT(sink, "LGE up layer set app type"); |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 980 | if (sink_priv->lge_ctxt.app_type) |
| 981 | g_free(sink_priv->lge_ctxt.app_type); |
| 982 | sink_priv->lge_ctxt.app_type = g_strdup(g_value_get_string(value)); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 983 | GST_OBJECT_UNLOCK(sink); |
| 984 | break; |
| 985 | } |
| 986 | case PROP_LGE_SYNC: |
| 987 | { |
| 988 | GST_OBJECT_LOCK(sink); |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 989 | sink_priv->lge_ctxt.sync = g_value_get_boolean(value); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 990 | GST_OBJECT_UNLOCK(sink); |
| 991 | break; |
| 992 | } |
| 993 | case PROP_LGE_DISH_TRICK: |
| 994 | { |
| 995 | GST_OBJECT_LOCK(sink); |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 996 | sink_priv->lge_ctxt.dish_trick = g_value_get_boolean(value); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 997 | GST_OBJECT_UNLOCK(sink); |
| 998 | break; |
| 999 | } |
| 1000 | case PROP_LGE_DISH_TRICK_IGNORE_RATE: |
| 1001 | { |
| 1002 | GST_OBJECT_LOCK(sink); |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 1003 | sink_priv->lge_ctxt.dish_trick_ignore_rate = g_value_get_boolean(value); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 1004 | GST_OBJECT_UNLOCK(sink); |
| 1005 | break; |
| 1006 | } |
| 1007 | #endif |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1008 | case PROP_VIDEO_ROTATION: |
| 1009 | { |
| 1010 | int rotationDegree = g_value_get_int(value); |
kaiqiang.xiang | e5044f2 | 2024-12-20 11:43:33 +0800 | [diff] [blame^] | 1011 | // dw=0 only AFBC, don't support rotation |
| 1012 | if (sink_priv->dw_mode != 0 && rotationDegree >= WST_ROTATION_0 && rotationDegree <= WST_ROTATION_270) |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1013 | { |
| 1014 | GST_DEBUG_OBJECT(sink, "set rotation degree %d", rotationDegree); |
| 1015 | sink_priv->rot_degree = (ROTATION_DEGREE)rotationDegree; |
| 1016 | sink_priv->rot_changed = TRUE; |
| 1017 | sink_priv->rot_enable_property = TRUE; |
| 1018 | } |
| 1019 | break; |
| 1020 | } |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1021 | default: |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 1022 | // G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1023 | break; |
| 1024 | } |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1025 | } |
| 1026 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1027 | static void gst_aml_video_sink_finalize(GObject *object) |
| 1028 | { |
| 1029 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(object); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1030 | GST_DEBUG_OBJECT(sink, "Finalizing aml video sink.."); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1031 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1032 | if (sink->buffer_queue) |
| 1033 | { |
| 1034 | gst_queue_array_free (sink->buffer_queue); |
| 1035 | sink->buffer_queue = NULL; |
| 1036 | } |
| 1037 | |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 1038 | g_mutex_clear(&sink->eos_lock); |
| 1039 | g_cond_clear(&sink->eos_cond); |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 1040 | g_mutex_clear(&sink->report_info_lock); |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1041 | g_mutex_clear(&sink->rotation_buffer_lock); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1042 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1043 | gst_aml_video_sink_reset_private(sink); |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 1044 | if (GST_AML_VIDEO_SINK_GET_PRIVATE(sink)) |
xuesong.jiang | 5c0d1b8 | 2021-11-16 19:30:56 +0800 | [diff] [blame] | 1045 | free(GST_AML_VIDEO_SINK_GET_PRIVATE(sink)); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1046 | G_OBJECT_CLASS(parent_class)->finalize(object); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1047 | } |
| 1048 | |
| 1049 | static GstStateChangeReturn |
| 1050 | gst_aml_video_sink_change_state(GstElement *element, |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1051 | GstStateChange transition) |
| 1052 | { |
| 1053 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(element); |
| 1054 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1055 | GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; |
xuesong.jiang | 9d55c67 | 2022-05-09 18:33:03 +0800 | [diff] [blame] | 1056 | GstState state, next; |
| 1057 | |
| 1058 | state = (GstState)GST_STATE_TRANSITION_CURRENT(transition); |
| 1059 | next = GST_STATE_TRANSITION_NEXT(transition); |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1060 | GST_DEBUG_OBJECT(sink, |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 1061 | "amlvideosink handler tries setting state from %s to %s (%04x)", |
| 1062 | gst_element_state_get_name(state), |
| 1063 | gst_element_state_get_name(next), transition); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1064 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1065 | GST_OBJECT_LOCK(sink); |
| 1066 | switch (transition) |
| 1067 | { |
| 1068 | case GST_STATE_CHANGE_NULL_TO_READY: |
| 1069 | { |
fei.deng | 88a6f02 | 2024-04-10 02:23:55 +0000 | [diff] [blame] | 1070 | //set env to enable essos |
| 1071 | setenv("ENABLE_WST_ESSOS","1",1); |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1072 | sink_priv->render_device_handle = render_open(); |
| 1073 | if (sink_priv->render_device_handle == NULL) |
| 1074 | { |
| 1075 | GST_ERROR_OBJECT(sink, "render lib: open device fail"); |
| 1076 | goto error; |
| 1077 | } |
| 1078 | RenderCallback cb = {gst_render_msg_callback, gst_render_val_callback}; |
| 1079 | render_set_callback(sink_priv->render_device_handle, sink, &cb); |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 1080 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1081 | GST_DEBUG_OBJECT(sink, "tunnel lib: set pip mode %d",sink->pip_mode); |
| 1082 | int pip = 1; |
| 1083 | if (sink->pip_mode && render_set_value(sink_priv->render_device_handle, KEY_VIDEO_PIP, &pip) == -1) |
| 1084 | { |
| 1085 | GST_ERROR_OBJECT(sink, "tunnel lib: set pip error"); |
| 1086 | goto error; |
| 1087 | } |
fei.deng | 978b242 | 2023-11-30 10:33:23 +0000 | [diff] [blame] | 1088 | //check if showing first frame no sync |
le.han | 9ff888d | 2024-09-09 03:04:31 +0000 | [diff] [blame] | 1089 | int show_frame_asap = sink_priv->show_first_frame_asap ? 1 : 0; |
| 1090 | if (render_set_value(sink_priv->render_device_handle, KEY_SHOW_FRIST_FRAME_NOSYNC, &show_frame_asap)) |
| 1091 | { |
| 1092 | GST_ERROR_OBJECT(sink, "tunnel lib: set show first frame no sync error"); |
| 1093 | goto error; |
fei.deng | 978b242 | 2023-11-30 10:33:23 +0000 | [diff] [blame] | 1094 | } |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 1095 | |
xuesong.jiang | fc27c27 | 2022-05-11 17:09:02 +0800 | [diff] [blame] | 1096 | GST_DEBUG_OBJECT(sink, "set qos fail"); |
| 1097 | gst_base_sink_set_qos_enabled((GstBaseSink *)sink, FALSE); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1098 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1099 | break; |
| 1100 | } |
| 1101 | case GST_STATE_CHANGE_READY_TO_PAUSED: |
| 1102 | { |
xuesong.jiang | 5eb0171 | 2022-10-21 19:47:54 +0800 | [diff] [blame] | 1103 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1104 | if (render_set_value(sink_priv->render_device_handle, KEY_SELECT_DISPLAY_OUTPUT, &sink->display_output_index) == -1) |
| 1105 | { |
| 1106 | GST_ERROR_OBJECT(sink, "render lib first set output index error"); |
| 1107 | goto error; |
| 1108 | } |
xuesong.jiang | a507a4b | 2022-10-28 16:28:29 +0800 | [diff] [blame] | 1109 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1110 | if (render_connect(sink_priv->render_device_handle) == -1) |
| 1111 | { |
| 1112 | GST_ERROR_OBJECT(sink, "render lib connect device fail"); |
| 1113 | goto error; |
| 1114 | } |
xuesong.jiang | a507a4b | 2022-10-28 16:28:29 +0800 | [diff] [blame] | 1115 | |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 1116 | if (render_set_value(sink_priv->render_device_handle, KEY_IMMEDIATELY_OUTPUT, &sink->immediately_render) == -1) |
| 1117 | { |
| 1118 | GST_ERROR_OBJECT(sink, "render lib set immediately output error"); |
| 1119 | goto error; |
| 1120 | } |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 1121 | if (sink_priv->force_aspect_ratio) |
| 1122 | { |
| 1123 | int force = 1; |
| 1124 | render_set_value(sink_priv->render_device_handle, KEY_FORCE_ASPECT_RATIO, &force); |
| 1125 | } |
le.han | de92b68 | 2024-05-30 07:18:19 +0000 | [diff] [blame] | 1126 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1127 | if (render_pause(sink_priv->render_device_handle) == -1) |
| 1128 | { |
| 1129 | GST_ERROR_OBJECT(sink, "render lib pause device fail when first into paused state"); |
| 1130 | goto error; |
| 1131 | } |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1132 | rotation_init(&sink_priv->amlge2d, &sink_priv->pge2dinfo); |
xuesong.jiang | 6903199 | 2022-06-09 19:30:35 +0800 | [diff] [blame] | 1133 | break; |
| 1134 | } |
| 1135 | case GST_STATE_CHANGE_PAUSED_TO_PLAYING: |
| 1136 | { |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 1137 | sink->video_playing = TRUE; |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1138 | if (render_resume(sink_priv->render_device_handle) == -1) |
| 1139 | { |
| 1140 | GST_ERROR_OBJECT(sink, "render lib resume device fail"); |
| 1141 | goto error; |
| 1142 | } |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 1143 | //drop all frames thoes donot rendered |
| 1144 | if (sink_priv->got_eos) { |
| 1145 | sink->rendered = sink->queued - sink->dropped; |
| 1146 | } |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1147 | break; |
| 1148 | } |
xuesong.jiang | 58e75f8 | 2022-06-30 19:23:20 +0800 | [diff] [blame] | 1149 | case GST_STATE_CHANGE_PLAYING_TO_PAUSED: |
| 1150 | { |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 1151 | sink->video_playing = FALSE; |
xuesong.jiang | 58e75f8 | 2022-06-30 19:23:20 +0800 | [diff] [blame] | 1152 | if (gst_base_sink_is_async_enabled(GST_BASE_SINK(sink))) |
| 1153 | { |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 1154 | GST_OBJECT_UNLOCK(sink); |
xuesong.jiang | 58e75f8 | 2022-06-30 19:23:20 +0800 | [diff] [blame] | 1155 | GstBaseSink *basesink; |
| 1156 | basesink = GST_BASE_SINK(sink); |
fei.deng | 2dee940 | 2023-05-06 08:21:21 +0000 | [diff] [blame] | 1157 | //GST_BASE_SINK_PREROLL_LOCK(basesink); |
xuesong.jiang | 58e75f8 | 2022-06-30 19:23:20 +0800 | [diff] [blame] | 1158 | basesink->have_preroll = 1; |
fei.deng | 2dee940 | 2023-05-06 08:21:21 +0000 | [diff] [blame] | 1159 | //GST_BASE_SINK_PREROLL_UNLOCK(basesink); |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 1160 | GST_OBJECT_LOCK(sink); |
xuesong.jiang | 58e75f8 | 2022-06-30 19:23:20 +0800 | [diff] [blame] | 1161 | } |
| 1162 | break; |
| 1163 | } |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1164 | default: |
| 1165 | break; |
| 1166 | } |
| 1167 | GST_OBJECT_UNLOCK(sink); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1168 | |
xuesong.jiang | 1700bab | 2021-11-17 17:11:11 +0800 | [diff] [blame] | 1169 | GST_LOG_OBJECT(sink, "amlvideosink deal state change ok, goto basesink state change"); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1170 | ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); |
| 1171 | |
| 1172 | GST_OBJECT_LOCK(sink); |
| 1173 | if (ret == GST_STATE_CHANGE_FAILURE) |
| 1174 | goto error; |
| 1175 | |
| 1176 | switch (transition) |
| 1177 | { |
xuesong.jiang | 6903199 | 2022-06-09 19:30:35 +0800 | [diff] [blame] | 1178 | case GST_STATE_CHANGE_PLAYING_TO_PAUSED: |
| 1179 | { |
xuesong.jiang | 22afe86 | 2022-11-09 16:27:33 +0800 | [diff] [blame] | 1180 | // GstBaseSink *basesink; |
| 1181 | // basesink = GST_BASE_SINK(sink); |
xuesong.jiang | 6903199 | 2022-06-09 19:30:35 +0800 | [diff] [blame] | 1182 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1183 | if (render_pause(sink_priv->render_device_handle) == -1) |
| 1184 | { |
| 1185 | GST_ERROR_OBJECT(sink, "render lib pause device fail"); |
| 1186 | goto error; |
| 1187 | } |
xuesong.jiang | 6903199 | 2022-06-09 19:30:35 +0800 | [diff] [blame] | 1188 | |
| 1189 | // GST_BASE_SINK_PREROLL_LOCK(basesink); |
| 1190 | // basesink->have_preroll = 1; |
| 1191 | // GST_BASE_SINK_PREROLL_UNLOCK(basesink); |
| 1192 | break; |
| 1193 | } |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1194 | case GST_STATE_CHANGE_PAUSED_TO_READY: |
| 1195 | { |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 1196 | if ( sink->detect_thread_handle ) |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1197 | { |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1198 | sink->quit_eos_detect_thread = TRUE; |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 1199 | g_thread_join(sink->detect_thread_handle); |
| 1200 | sink->detect_thread_handle = NULL; |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1201 | } |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1202 | if (sink->rotation_thread_handle) |
| 1203 | { |
| 1204 | sink->quit_rotation_thread = TRUE; |
| 1205 | GST_OBJECT_UNLOCK(sink); |
| 1206 | g_thread_join(sink->rotation_thread_handle); |
| 1207 | GST_OBJECT_LOCK(sink); |
| 1208 | sink->rotation_thread_handle = NULL; |
| 1209 | } |
xuesong.jiang | aed3094 | 2022-06-17 14:27:27 +0800 | [diff] [blame] | 1210 | GST_DEBUG_OBJECT(sink, "before disconnect rlib"); |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1211 | render_disconnect(sink_priv->render_device_handle); |
xuesong.jiang | aed3094 | 2022-06-17 14:27:27 +0800 | [diff] [blame] | 1212 | GST_DEBUG_OBJECT(sink, "after disconnect rlib"); |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 1213 | GST_DEBUG_OBJECT(sink, "buf stat | queued:%d, dequeued:%d, dropped:%d, rendered:%d", |
| 1214 | sink->queued, sink->dequeued, sink->dropped, sink->rendered); |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1215 | |
| 1216 | if (sink_priv->rot_buffer) |
| 1217 | { |
| 1218 | rotation_buffer_teardown(sink_priv->rot_buffer, ROT_BUFFER_MAX); |
| 1219 | sink_priv->rot_buffer = NULL; |
| 1220 | } |
| 1221 | rotation_exit(&sink_priv->amlge2d); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1222 | break; |
| 1223 | } |
| 1224 | case GST_STATE_CHANGE_READY_TO_NULL: |
| 1225 | { |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 1226 | if (sink_priv->render_device_handle) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1227 | { |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1228 | render_close(sink_priv->render_device_handle); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1229 | } |
| 1230 | gst_aml_video_sink_reset_private(sink); |
fei.deng | 88a6f02 | 2024-04-10 02:23:55 +0000 | [diff] [blame] | 1231 | //set env to invalid essos |
| 1232 | setenv("ENABLE_WST_ESSOS","0",1); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1233 | |
| 1234 | break; |
| 1235 | } |
| 1236 | default: |
| 1237 | break; |
| 1238 | } |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 1239 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1240 | //gst_aml_video_sink_dump_stat(sink, GST_DUMP_STAT_FILENAME); |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 1241 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1242 | GST_OBJECT_UNLOCK(sink); |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1243 | GST_DEBUG_OBJECT(sink, "done"); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1244 | return ret; |
| 1245 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1246 | error: |
| 1247 | GST_OBJECT_UNLOCK(sink); |
| 1248 | ret = GST_STATE_CHANGE_FAILURE; |
| 1249 | return ret; |
| 1250 | } |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1251 | |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 1252 | static gboolean gst_aml_video_sink_query(GstElement *element, GstQuery *query) |
| 1253 | { |
| 1254 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(element); |
| 1255 | |
| 1256 | switch (GST_QUERY_TYPE(query)) |
| 1257 | { |
| 1258 | case GST_QUERY_POSITION: |
| 1259 | { |
| 1260 | GstFormat format; |
| 1261 | gst_query_parse_position(query, &format, NULL); |
| 1262 | if (GST_FORMAT_BYTES == format) |
| 1263 | { |
| 1264 | return GST_ELEMENT_CLASS(parent_class)->query(element, query); |
| 1265 | } |
| 1266 | else |
| 1267 | { |
| 1268 | GST_OBJECT_LOCK(sink); |
| 1269 | gint64 position = sink->last_displayed_buf_pts; |
xuesong.jiang | aed3094 | 2022-06-17 14:27:27 +0800 | [diff] [blame] | 1270 | // gint64 position = sink->last_dec_buf_pts; |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 1271 | GST_OBJECT_UNLOCK(sink); |
xuesong.jiang | 0ebc033 | 2022-07-05 10:58:02 +0800 | [diff] [blame] | 1272 | GST_DEBUG_OBJECT(sink, "got position: %" GST_TIME_FORMAT, GST_TIME_ARGS(position)); |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 1273 | gst_query_set_position(query, GST_FORMAT_TIME, position); |
| 1274 | return TRUE; |
| 1275 | } |
| 1276 | break; |
| 1277 | } |
| 1278 | default: |
| 1279 | return GST_ELEMENT_CLASS(parent_class)->query(element, query); |
| 1280 | } |
| 1281 | } |
| 1282 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1283 | static gboolean gst_aml_video_sink_propose_allocation(GstBaseSink *bsink, GstQuery *query) |
| 1284 | { |
xuesong.jiang | eb46f67 | 2021-11-19 19:05:56 +0800 | [diff] [blame] | 1285 | GST_DEBUG_OBJECT(bsink, "trace in"); |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 1286 | // TODO only implement dma case |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1287 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(bsink); |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 1288 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
| 1289 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1290 | GstCaps *caps; |
| 1291 | GstBufferPool *pool = NULL; |
| 1292 | gboolean need_pool; |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1293 | |
| 1294 | gst_query_parse_allocation(query, &caps, &need_pool); |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1295 | GST_DEBUG_OBJECT(bsink, "need_pool: %d, secure_mode: %d, size=%d", need_pool, sink->secure_mode, sink_priv->dw_size); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1296 | |
| 1297 | if (need_pool) |
sheng.liu | c9f3496 | 2022-06-17 21:42:48 +0800 | [diff] [blame] | 1298 | pool = gst_drm_bufferpool_new(sink->secure_mode, GST_DRM_BUFFERPOOL_TYPE_VIDEO_PLANE); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1299 | |
sheng.liu | bbb893b | 2022-06-24 15:49:04 +0800 | [diff] [blame] | 1300 | // Do not store the last received sample if it is secure_mode |
| 1301 | if (TRUE == sink->secure_mode) |
| 1302 | gst_base_sink_set_last_sample_enabled(bsink, FALSE); |
| 1303 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1304 | gst_query_add_allocation_pool(query, pool, sink_priv->dw_size, DRMBP_EXTRA_BUF_SIZE_FOR_DISPLAY, DRMBP_LIMIT_MAX_BUFSIZE_TO_BUFSIZE); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1305 | if (pool) |
| 1306 | g_object_unref(pool); |
| 1307 | |
| 1308 | gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL); |
| 1309 | |
| 1310 | return TRUE; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1311 | } |
| 1312 | |
| 1313 | static GstCaps *gst_aml_video_sink_get_caps(GstBaseSink *bsink, |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1314 | GstCaps *filter) |
| 1315 | { |
| 1316 | GstAmlVideoSink *sink; |
| 1317 | GstCaps *caps; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1318 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1319 | sink = GST_AML_VIDEO_SINK(bsink); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1320 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1321 | caps = gst_pad_get_pad_template_caps(GST_VIDEO_SINK_PAD(sink)); |
| 1322 | caps = gst_caps_make_writable(caps); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1323 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1324 | if (filter) |
| 1325 | { |
| 1326 | GstCaps *intersection; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1327 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1328 | intersection = |
| 1329 | gst_caps_intersect_full(filter, caps, GST_CAPS_INTERSECT_FIRST); |
| 1330 | gst_caps_unref(caps); |
| 1331 | caps = intersection; |
| 1332 | } |
xuesong.jiang | 22afe86 | 2022-11-09 16:27:33 +0800 | [diff] [blame] | 1333 | GST_DEBUG_OBJECT(sink, "filter caps: %" GST_PTR_FORMAT, filter); |
| 1334 | GST_DEBUG_OBJECT(sink, "final caps: %" GST_PTR_FORMAT, caps); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1335 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1336 | return caps; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1337 | } |
| 1338 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1339 | static gboolean gst_aml_video_sink_set_caps(GstBaseSink *bsink, GstCaps *caps) |
| 1340 | { |
| 1341 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(bsink); |
| 1342 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 1343 | // gboolean use_dmabuf; |
xuesong.jiang | 91391f5 | 2021-11-19 15:42:30 +0800 | [diff] [blame] | 1344 | gboolean ret = TRUE; |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1345 | GstStructure *structure; |
| 1346 | const gchar *s; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1347 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1348 | g_return_val_if_fail (caps != NULL, FALSE); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1349 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1350 | GST_DEBUG_OBJECT(sink, "set caps %" GST_PTR_FORMAT, caps); |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1351 | |
| 1352 | GST_OBJECT_LOCK(sink); |
xuesong.jiang | eb46f67 | 2021-11-19 19:05:56 +0800 | [diff] [blame] | 1353 | // use_dmabuf = gst_caps_features_contains(gst_caps_get_features(caps, 0), GST_CAPS_FEATURE_MEMORY_DMABUF); |
| 1354 | // if (use_dmabuf == FALSE) |
| 1355 | // { |
| 1356 | // GST_ERROR_OBJECT(sink, "not support non dma buffer case"); |
| 1357 | // ret = FALSE; |
| 1358 | // goto done; |
| 1359 | // } |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1360 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1361 | structure = gst_caps_get_structure (caps, 0); |
| 1362 | |
| 1363 | if (!(s = gst_structure_get_string (structure, "format"))) { |
| 1364 | GST_WARNING_OBJECT(sink, "can't get format from caps"); |
| 1365 | } else { |
| 1366 | sink_priv->format = gst_video_format_from_string (s); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1367 | } |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1368 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1369 | if (!gst_structure_get_int (structure, "width", &sink_priv->dw_width)) { |
| 1370 | GST_WARNING_OBJECT(sink, "can't get width from caps"); |
| 1371 | } |
| 1372 | if (!gst_structure_get_int (structure, "height", &sink_priv->dw_height)) { |
| 1373 | GST_WARNING_OBJECT(sink, "can't get height from caps"); |
| 1374 | } |
| 1375 | if (!gst_structure_get_int (structure, "src_width", &sink_priv->src_width)) { |
| 1376 | GST_WARNING_OBJECT(sink, "can't get src_width from caps"); |
| 1377 | } |
| 1378 | if (!gst_structure_get_int (structure, "src_height", &sink_priv->src_height)) { |
| 1379 | GST_WARNING_OBJECT(sink, "can't get src_height from caps"); |
| 1380 | } |
le.han | 30f126e | 2024-10-09 02:42:55 +0000 | [diff] [blame] | 1381 | if (!gst_structure_get_int (structure, "dw_mode", &sink_priv->dw_mode)) { |
| 1382 | GST_WARNING_OBJECT(sink, "can't get dw_mode from caps"); |
| 1383 | } |
| 1384 | if (!gst_structure_get_int (structure, "stride", &sink_priv->stride)) { |
| 1385 | GST_WARNING_OBJECT(sink, "can't get stride from caps"); |
| 1386 | } |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1387 | |
| 1388 | sink_priv->dw_size = sink_priv->dw_width*sink_priv->dw_height*3/2; |
| 1389 | |
| 1390 | if (!gst_structure_get_fraction (structure, "framerate", &sink_priv->fps_n, &sink_priv->fps_d)) { |
| 1391 | GST_WARNING_OBJECT(sink, "can't get fps from caps"); |
| 1392 | sink_priv->fps_n = 0; |
| 1393 | sink_priv->fps_d = 1; |
| 1394 | } |
| 1395 | if (!gst_structure_get_fraction (structure, "pixel-aspect-ratio", &sink_priv->par_n, &sink_priv->par_d)) { |
| 1396 | GST_WARNING_OBJECT(sink, "can't get par from caps"); |
| 1397 | sink_priv->par_n = 1; |
| 1398 | sink_priv->par_d = 1; |
| 1399 | } |
| 1400 | |
| 1401 | if (!(s = gst_structure_get_string (structure, "interlace-mode"))) { |
| 1402 | GST_WARNING_OBJECT(sink, "can't get interlace-mode from caps"); |
| 1403 | } else { |
| 1404 | sink_priv->interlace = !g_str_equal ("progressive", s); |
| 1405 | } |
xuesong.jiang | c26425b | 2022-05-12 20:37:22 +0800 | [diff] [blame] | 1406 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1407 | sink_priv->video_info_changed = TRUE; |
| 1408 | |
| 1409 | GST_OBJECT_UNLOCK(sink); |
xuesong.jiang | 91391f5 | 2021-11-19 15:42:30 +0800 | [diff] [blame] | 1410 | return ret; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1411 | } |
| 1412 | |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1413 | |
| 1414 | static void gst_show_vr_cb(gpointer data) |
| 1415 | { |
| 1416 | bufferInfo *binfo = (bufferInfo*)data; |
| 1417 | GstAmlVideoSink *sink = binfo->sink; |
| 1418 | GST_DEBUG("unref vr360 buffer %p ",binfo->buf); |
| 1419 | sink->rendered++; |
| 1420 | if (binfo->buf) |
| 1421 | gst_buffer_unref(binfo->buf); |
| 1422 | free(binfo); |
| 1423 | } |
| 1424 | |
| 1425 | static gboolean gst_aml_video_sink_show_vr_frame(GstAmlVideoSink *sink, GstBuffer *buffer) |
| 1426 | { |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1427 | bufferInfo *binfo = NULL; |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1428 | GstStructure *s; |
| 1429 | GstBuffer *buf; |
| 1430 | gint fd0 = -1, fd1 = -1, fd2 = -1; |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1431 | gint stride0 = 0, stride1 = 0, stride2 = 0; |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1432 | GstVideoMeta *vmeta = NULL; |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1433 | int offset1= 0, offset2 = 0; |
| 1434 | guint n_mem = 0; |
| 1435 | GstMemory *dma_mem0 = NULL; |
| 1436 | GstMemory *dma_mem1 = NULL; |
| 1437 | |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1438 | GST_DEBUG("pts: %lld %p", GST_BUFFER_PTS (buffer),buffer); |
| 1439 | |
| 1440 | binfo= (bufferInfo*)malloc( sizeof(bufferInfo) ); |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1441 | if (!binfo) { |
| 1442 | GST_ERROR_OBJECT(sink, "malloc bufferInfo fail."); |
| 1443 | return FALSE; |
| 1444 | } |
| 1445 | |
| 1446 | gst_buffer_ref(buffer); |
| 1447 | binfo->sink= sink; |
| 1448 | binfo->buf = buffer; |
| 1449 | n_mem = gst_buffer_n_memory(buffer); |
| 1450 | vmeta = gst_buffer_get_video_meta(buffer); |
| 1451 | if (vmeta == NULL) |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1452 | { |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1453 | GST_ERROR_OBJECT(sink, "not found video meta info"); |
| 1454 | gst_buffer_unref(binfo->buf); |
| 1455 | free(binfo); |
| 1456 | return FALSE; |
| 1457 | } |
| 1458 | GST_DEBUG("height:%d,width:%d,n_mem:%d",vmeta->height,vmeta->width,n_mem); |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1459 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1460 | if (n_mem > 1) |
| 1461 | { |
| 1462 | dma_mem0 = gst_buffer_peek_memory(buffer, 0); |
| 1463 | dma_mem1 = gst_buffer_peek_memory(buffer, 1); |
| 1464 | fd0 = gst_dmabuf_memory_get_fd(dma_mem0); |
| 1465 | fd1 = gst_dmabuf_memory_get_fd(dma_mem1); |
| 1466 | GST_DEBUG("fd0:%d,fd1:%d,fd2:%d",fd0,fd1,fd2); |
| 1467 | stride0 = vmeta->stride[0]; |
| 1468 | stride1 = vmeta->stride[1]; |
| 1469 | stride2 = 0; |
| 1470 | if ( fd1 < 0 ) |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1471 | { |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1472 | stride1= stride0; |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1473 | offset1= stride0*vmeta->height; |
| 1474 | } |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1475 | if ( fd2 < 0 ) |
| 1476 | { |
| 1477 | offset2= offset1+(vmeta->width*vmeta->height)/2; |
| 1478 | stride2= stride0; |
| 1479 | } |
| 1480 | GST_DEBUG("stride0:%d,stride1:%d,stride2:%d",stride0,stride1,stride2); |
| 1481 | GST_DEBUG("offset0:%d,offset1:%d,offset2:%d",offset2,offset2,offset2); |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1482 | } |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1483 | else |
| 1484 | { |
| 1485 | GST_DEBUG("single plane"); |
| 1486 | dma_mem0 = gst_buffer_peek_memory(buffer, 0); |
| 1487 | fd0 = gst_dmabuf_memory_get_fd(dma_mem0); |
| 1488 | stride0 = vmeta->stride[0]; |
| 1489 | offset1= stride0*vmeta->height; |
| 1490 | } |
| 1491 | |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1492 | s = gst_structure_new ("drmbuffer_info", |
| 1493 | "fd0", G_TYPE_INT, fd0, |
| 1494 | "fd1", G_TYPE_INT, fd1, |
| 1495 | "fd2", G_TYPE_INT, fd2, |
| 1496 | "stride0", G_TYPE_INT, stride0, |
| 1497 | "stride1", G_TYPE_INT, stride1, |
| 1498 | "stride2", G_TYPE_INT, stride2, |
| 1499 | "width", G_TYPE_INT, vmeta->width, |
| 1500 | "height", G_TYPE_INT, vmeta->height, |
| 1501 | "format", G_TYPE_INT, FORMAT_NV21, |
| 1502 | NULL); |
| 1503 | GST_DEBUG("structure: %" GST_PTR_FORMAT,s); |
| 1504 | |
| 1505 | buf = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, |
| 1506 | (gpointer) binfo, sizeof(bufferInfo), 0, sizeof(bufferInfo), |
| 1507 | (gpointer) binfo, gst_show_vr_cb); |
| 1508 | if (!buf) |
| 1509 | { |
| 1510 | GST_ERROR_OBJECT(sink, "new buffer fail!"); |
| 1511 | gst_buffer_unref(buf); |
| 1512 | gst_buffer_unref(binfo->buf); |
| 1513 | free(binfo); |
| 1514 | return FALSE;; |
| 1515 | } |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1516 | |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1517 | gst_buffer_add_protection_meta(buf, s); |
| 1518 | GST_BUFFER_PTS (buf) = GST_BUFFER_PTS(buffer); |
| 1519 | GST_DEBUG("pts: %lld, %p", GST_BUFFER_PTS (buf),buf); |
| 1520 | g_signal_emit (G_OBJECT(sink),g_signals[SIGNAL_DECODEDBUFFER],0,buf); |
| 1521 | gst_buffer_unref(buf); |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 1522 | |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1523 | return TRUE; |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1524 | } |
| 1525 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1526 | static void rotation_flush_buffer(GstAmlVideoSink *vsink) |
| 1527 | { |
| 1528 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(vsink); |
| 1529 | |
| 1530 | g_mutex_lock(&sink->rotation_buffer_lock); |
| 1531 | if (sink->buffer_queue) |
| 1532 | { |
| 1533 | while (!gst_queue_array_is_empty(sink->buffer_queue)) |
| 1534 | { |
| 1535 | GstBuffer* buffer = (GstBuffer *)gst_queue_array_pop_head(sink->buffer_queue); |
| 1536 | gst_buffer_unref(buffer); |
| 1537 | GST_DEBUG_OBJECT(sink, "reset pop head buffer_queue len:%d", gst_queue_array_get_length(sink->buffer_queue)); |
| 1538 | } |
| 1539 | } |
| 1540 | g_mutex_unlock(&sink->rotation_buffer_lock); |
| 1541 | GST_DEBUG_OBJECT(sink, "flush over buffer_queue len:%d", gst_queue_array_get_length(sink->buffer_queue)); |
| 1542 | } |
| 1543 | |
| 1544 | static gpointer rotation_thread(gpointer data) |
| 1545 | { |
| 1546 | GstAmlVideoSink *sink = (GstAmlVideoSink *)data; |
| 1547 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
| 1548 | |
| 1549 | while (!sink->quit_rotation_thread) |
| 1550 | { |
| 1551 | if (sink_priv->rot_buffer && -1 == get_rotation_buffer_idx(sink)) |
| 1552 | { |
| 1553 | usleep(5000); |
| 1554 | continue; |
| 1555 | } |
| 1556 | |
| 1557 | if (sink->buffer_queue && !gst_queue_array_is_empty(sink->buffer_queue)) |
| 1558 | { |
| 1559 | // pop queue |
| 1560 | g_mutex_lock(&sink->rotation_buffer_lock); |
| 1561 | GstBuffer *buffer = (GstBuffer *)gst_queue_array_pop_head(sink->buffer_queue); |
| 1562 | g_mutex_unlock(&sink->rotation_buffer_lock); |
| 1563 | |
| 1564 | // show frame |
| 1565 | gst_aml_video_sink_show_frame((GstVideoSink*)sink, buffer); |
| 1566 | gst_buffer_unref(buffer); |
| 1567 | } |
| 1568 | else |
| 1569 | { |
| 1570 | usleep(10000); |
| 1571 | } |
| 1572 | } |
| 1573 | |
| 1574 | // thread join, unref all gst buffer |
| 1575 | rotation_flush_buffer(sink); |
| 1576 | |
| 1577 | if (!sink->quit_rotation_thread) |
| 1578 | { |
| 1579 | g_thread_unref( sink->rotation_thread_handle ); |
| 1580 | sink->rotation_thread_handle= NULL; |
| 1581 | } |
| 1582 | GST_DEBUG("rotation_thread: exit"); |
| 1583 | return NULL; |
| 1584 | } |
| 1585 | |
| 1586 | static GstFlowReturn gst_aml_video_sink_push_queue(GstVideoSink *vsink, GstBuffer *buffer) |
| 1587 | { |
| 1588 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(vsink); |
| 1589 | if (sink->rotation_thread_handle == NULL ) |
| 1590 | { |
| 1591 | sink->quit_rotation_thread = FALSE; |
| 1592 | GST_DEBUG_OBJECT(sink, "start rotation thread"); |
| 1593 | sink->rotation_thread_handle = g_thread_new("video_sink_rotation", rotation_thread, sink); |
| 1594 | } |
| 1595 | |
| 1596 | g_mutex_lock(&sink->rotation_buffer_lock); |
| 1597 | // push queue |
| 1598 | if (sink->buffer_queue) |
| 1599 | { |
| 1600 | gst_queue_array_push_tail (sink->buffer_queue, buffer); |
| 1601 | gst_buffer_ref(buffer); |
| 1602 | } |
| 1603 | g_mutex_unlock(&sink->rotation_buffer_lock); |
| 1604 | return GST_FLOW_OK; |
| 1605 | } |
| 1606 | |
| 1607 | |
| 1608 | static GstFlowReturn gst_aml_video_sink_show_frame_ex(GstVideoSink *vsink, GstBuffer *buffer) |
| 1609 | { |
| 1610 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(vsink); |
| 1611 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
| 1612 | |
| 1613 | if (sink_priv->rot_degree == WST_ROTATION_90 || sink_priv->rot_degree == WST_ROTATION_270) |
| 1614 | { |
| 1615 | return gst_aml_video_sink_push_queue(vsink, buffer); |
| 1616 | } |
| 1617 | return gst_aml_video_sink_show_frame(vsink, buffer); |
| 1618 | } |
| 1619 | |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 1620 | static GstFlowReturn gst_aml_video_sink_show_frame(GstVideoSink *vsink, GstBuffer *buffer) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1621 | { |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 1622 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(vsink); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1623 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
| 1624 | GstFlowReturn ret = GST_FLOW_OK; |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1625 | RenderBuffer *tunnel_lib_buf_wrap = NULL; |
xuesong.jiang | 103d292 | 2022-04-26 13:37:20 +0800 | [diff] [blame] | 1626 | |
xuesong.jiang | 5d2761f | 2022-05-05 11:43:21 +0800 | [diff] [blame] | 1627 | GST_LOG_OBJECT(sink, "revice buffer:%p (start: %" GST_TIME_FORMAT ", end: %" GST_TIME_FORMAT "), from pool:%p, need_preroll:%d", |
| 1628 | buffer, GST_TIME_ARGS(GST_BUFFER_PTS(buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION(buffer)), |
xuesong.jiang | 103d292 | 2022-04-26 13:37:20 +0800 | [diff] [blame] | 1629 | buffer->pool, ((GstBaseSink *)sink)->need_preroll); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1630 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1631 | GST_OBJECT_LOCK(vsink); |
xuesong.jiang | aed3094 | 2022-06-17 14:27:27 +0800 | [diff] [blame] | 1632 | sink->last_dec_buf_pts = GST_BUFFER_PTS(buffer); |
| 1633 | GST_DEBUG_OBJECT(sink, "set last_dec_buf_pts %" GST_TIME_FORMAT, GST_TIME_ARGS(sink->last_dec_buf_pts)); |
| 1634 | |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 1635 | if (!sink_priv->render_device_handle) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1636 | { |
| 1637 | GST_ERROR_OBJECT(sink, "flow error, render_device_handle == NULL"); |
| 1638 | goto error; |
| 1639 | } |
| 1640 | |
xuesong.jiang | ebd1835 | 2021-12-28 17:13:22 +0800 | [diff] [blame] | 1641 | if (sink_priv->preroll_buffer && sink_priv->preroll_buffer == buffer) |
| 1642 | { |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1643 | GST_LOG_OBJECT(sink, "get preroll buffer:%p 2nd time, goto ret", buffer); |
xuesong.jiang | ebd1835 | 2021-12-28 17:13:22 +0800 | [diff] [blame] | 1644 | sink_priv->preroll_buffer = NULL; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1645 | goto ret; |
xuesong.jiang | ebd1835 | 2021-12-28 17:13:22 +0800 | [diff] [blame] | 1646 | } |
| 1647 | if (G_UNLIKELY(((GstBaseSink *)sink)->need_preroll)) |
| 1648 | { |
| 1649 | GST_LOG_OBJECT(sink, "get preroll buffer 1st time, buf:%p", buffer); |
| 1650 | sink_priv->preroll_buffer = buffer; |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1651 | } |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 1652 | |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1653 | GST_INFO_OBJECT(sink, "sink->enable_decoded_buffer_signal:%d", |
| 1654 | sink->enable_decoded_buffer_signal); |
| 1655 | |
| 1656 | if (sink->enable_decoded_buffer_signal) |
| 1657 | { |
| 1658 | if (!gst_aml_video_sink_check_buf(sink, buffer)) |
| 1659 | { |
| 1660 | GST_ERROR_OBJECT(sink, "buf out of segment return"); |
| 1661 | goto ret; |
| 1662 | } |
| 1663 | |
| 1664 | if (!gst_aml_video_sink_show_vr_frame(sink,buffer)) |
| 1665 | { |
| 1666 | GST_ERROR_OBJECT(sink, "can't play vr360 file!"); |
| 1667 | goto ret; |
| 1668 | } |
| 1669 | sink->queued++; |
| 1670 | sink->quit_eos_detect_thread = FALSE; |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 1671 | if (sink->detect_thread_handle == NULL ) |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1672 | { |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 1673 | GST_DEBUG_OBJECT(sink, "start detect thread"); |
| 1674 | sink->detect_thread_handle = g_thread_new("video_sink_detection", detection_thread, sink); |
hanghang.luo | 39bed67 | 2024-04-19 02:50:50 +0000 | [diff] [blame] | 1675 | } |
| 1676 | goto ret; |
| 1677 | } |
| 1678 | |
| 1679 | if (!gst_aml_video_sink_check_buf(sink, buffer)) |
| 1680 | { |
| 1681 | GST_ERROR_OBJECT(sink, "buf out of segment return"); |
| 1682 | goto ret; |
| 1683 | } |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1684 | |
xuesong.jiang | 5d2761f | 2022-05-05 11:43:21 +0800 | [diff] [blame] | 1685 | if (sink_priv->window_set.window_change) |
xuesong.jiang | 1a9c282 | 2022-04-24 11:35:07 +0800 | [diff] [blame] | 1686 | { |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1687 | RenderRect window_size = {sink_priv->window_set.x, sink_priv->window_set.y, sink_priv->window_set.w, sink_priv->window_set.h}; |
| 1688 | if (render_set_value(sink_priv->render_device_handle, KEY_WINDOW_SIZE, &window_size) == -1) |
| 1689 | { |
| 1690 | GST_ERROR_OBJECT(vsink, "tunnel lib: set window size error"); |
| 1691 | return FALSE; |
| 1692 | } |
| 1693 | sink_priv->window_set.window_change = FALSE; |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 1694 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1695 | GST_DEBUG_OBJECT(sink, "tunnel lib: set window size to %d,%d,%d,%d", |
| 1696 | sink_priv->window_set.x, |
| 1697 | sink_priv->window_set.y, |
| 1698 | sink_priv->window_set.w, |
| 1699 | sink_priv->window_set.h); |
xuesong.jiang | 1a9c282 | 2022-04-24 11:35:07 +0800 | [diff] [blame] | 1700 | } |
| 1701 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1702 | if (sink_priv->video_info_changed) |
| 1703 | { |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1704 | if (gst_render_set_params(vsink) == FALSE) |
| 1705 | { |
| 1706 | GST_ERROR_OBJECT(sink, "render lib: set params fail"); |
| 1707 | goto error; |
| 1708 | } |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1709 | sink_priv->video_info_changed = FALSE; |
| 1710 | } |
| 1711 | |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 1712 | if (sink->frame_rate_changed) { |
| 1713 | sink->frame_rate_changed = FALSE; |
| 1714 | RenderFraction frame_rate_fraction; |
| 1715 | frame_rate_fraction.num = sink->frame_rate_num; |
| 1716 | frame_rate_fraction.denom = sink->frame_rate_denom; |
sheng.liu | 639d474 | 2024-01-24 02:11:48 +0000 | [diff] [blame] | 1717 | render_set_value(sink_priv->render_device_handle, KEY_VIDEO_FRAME_RATE, &frame_rate_fraction); |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 1718 | } |
| 1719 | |
sheng.liu | 1a07969 | 2023-12-26 06:33:41 +0000 | [diff] [blame] | 1720 | if (sink->pixel_aspect_ratio_changed) |
| 1721 | { |
| 1722 | sink->pixel_aspect_ratio_changed = FALSE; |
| 1723 | render_set_value(sink_priv->render_device_handle, KEY_PIXEL_ASPECT_RATIO, &sink->pixel_aspect_ratio); |
| 1724 | } |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 1725 | if (sink->update_zorder) { |
| 1726 | sink->update_zorder = FALSE; |
| 1727 | render_set_value(sink_priv->render_device_handle, KEY_ZORDER, &sink->zorder); |
| 1728 | } |
fei.deng | 3a374e5 | 2024-10-29 17:04:42 +0800 | [diff] [blame] | 1729 | if (sink_priv->set_video_latency) { |
| 1730 | sink_priv->set_video_latency = FALSE; |
| 1731 | render_set_value(sink_priv->render_device_handle, KEY_MEDIASYNC_VIDEOLATENCY, &sink_priv->video_latency); |
| 1732 | } |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 1733 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1734 | tunnel_lib_buf_wrap = render_allocate_render_buffer_wrap(sink_priv->render_device_handle, BUFFER_FLAG_DMA_BUFFER); |
| 1735 | if (!tunnel_lib_buf_wrap) |
| 1736 | { |
| 1737 | GST_ERROR_OBJECT(sink, "render lib: alloc buffer wrap fail"); |
| 1738 | goto error; |
| 1739 | } |
hanghang.luo | b21ed19 | 2023-11-28 03:34:17 +0000 | [diff] [blame] | 1740 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1741 | if (!gst_aml_video_sink_tunnel_buf(sink, buffer, tunnel_lib_buf_wrap)) |
| 1742 | { |
| 1743 | GST_ERROR_OBJECT(sink, "construc render buffer fail"); |
| 1744 | goto error; |
| 1745 | } |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1746 | GST_OBJECT_UNLOCK(vsink); |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1747 | if (render_display_frame(sink_priv->render_device_handle, tunnel_lib_buf_wrap) == -1) |
| 1748 | { |
| 1749 | GST_ERROR_OBJECT(sink, "render lib: display frame fail"); |
hanghang.luo | b21ed19 | 2023-11-28 03:34:17 +0000 | [diff] [blame] | 1750 | return GST_FLOW_CUSTOM_ERROR_2; |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1751 | } |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1752 | |
hanghang.luo | b21ed19 | 2023-11-28 03:34:17 +0000 | [diff] [blame] | 1753 | GST_OBJECT_LOCK(vsink); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1754 | sink->queued++; |
hanghang.luo | b21ed19 | 2023-11-28 03:34:17 +0000 | [diff] [blame] | 1755 | if (sink_priv->is_flushing) |
| 1756 | { |
| 1757 | if (render_flush(sink_priv->render_device_handle) == 0) |
| 1758 | { |
| 1759 | GST_DEBUG_OBJECT(sink, "in flushing flow, release the buffer directly"); |
| 1760 | goto flushing; |
| 1761 | } |
| 1762 | else |
| 1763 | { |
| 1764 | GST_ERROR_OBJECT(sink, "render lib: flush error"); |
| 1765 | goto error; |
| 1766 | } |
| 1767 | } |
| 1768 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1769 | //gst_aml_video_sink_dump_stat(sink, GST_DUMP_STAT_FILENAME); |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 1770 | GST_DEBUG_OBJECT(sink, "GstBuffer:%p, pts: %" GST_TIME_FORMAT " queued ok, queued:%d", buffer, GST_TIME_ARGS(GST_BUFFER_PTS(buffer)), sink->queued); |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 1771 | sink->quit_eos_detect_thread = FALSE; |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 1772 | if (sink->detect_thread_handle == NULL ) |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1773 | { |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 1774 | GST_DEBUG_OBJECT(sink, "start detect thread"); |
| 1775 | sink->detect_thread_handle = g_thread_new("video_sink_detection", detection_thread, sink); |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1776 | } |
hanghang.luo | b21ed19 | 2023-11-28 03:34:17 +0000 | [diff] [blame] | 1777 | goto ret; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1778 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1779 | error: |
xuesong.jiang | eb46f67 | 2021-11-19 19:05:56 +0800 | [diff] [blame] | 1780 | GST_DEBUG_OBJECT(sink, "GstBuffer:%p queued error", buffer); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1781 | ret = GST_FLOW_CUSTOM_ERROR_2; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1782 | goto ret; |
| 1783 | flushing: |
| 1784 | GST_DEBUG_OBJECT(sink, "flushing when buf:%p", buffer); |
hanghang.luo | b21ed19 | 2023-11-28 03:34:17 +0000 | [diff] [blame] | 1785 | ret = GST_FLOW_FLUSHING; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1786 | goto ret; |
| 1787 | ret: |
| 1788 | GST_OBJECT_UNLOCK(vsink); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1789 | return ret; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1790 | } |
| 1791 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1792 | void gst_aml_video_sink_tag_event(GstAmlVideoSink *vsink, GstTagList *list ) |
| 1793 | { |
| 1794 | if (NULL == vsink || NULL == list) |
| 1795 | { |
| 1796 | return; |
| 1797 | } |
| 1798 | |
| 1799 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(vsink); |
| 1800 | gchar *rotation_tag = NULL; |
| 1801 | gint tagDegree = 0; |
| 1802 | ROTATION_DEGREE rotationDegree = WST_ROTATION_0; |
| 1803 | |
kaiqiang.xiang | e5044f2 | 2024-12-20 11:43:33 +0800 | [diff] [blame^] | 1804 | // dw=0 only AFBC, don't support rotation |
| 1805 | if ((!sink_priv->rot_enable_property) && (sink_priv->dw_mode != 0) && |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1806 | (gst_tag_list_get_string(list, GST_TAG_IMAGE_ORIENTATION, &rotation_tag))) |
| 1807 | { |
| 1808 | if (sscanf(rotation_tag, "rotate-%d", &tagDegree)) |
| 1809 | { |
| 1810 | rotationDegree = (ROTATION_DEGREE)(tagDegree/90); |
| 1811 | |
| 1812 | if (rotationDegree >= WST_ROTATION_0 && rotationDegree <= WST_ROTATION_270) |
| 1813 | { |
| 1814 | sink_priv->rot_changed = TRUE; |
| 1815 | sink_priv->rot_degree = rotationDegree; |
| 1816 | GST_DEBUG_OBJECT(vsink, "set rotation degree %d", rotationDegree); |
| 1817 | } |
| 1818 | } |
| 1819 | else if (sscanf(rotation_tag, "flip-rotate-%d", &tagDegree)) |
| 1820 | { |
| 1821 | // not support flip right now, need support later |
| 1822 | } |
| 1823 | } |
| 1824 | } |
| 1825 | |
xuesong.jiang | 22afe86 | 2022-11-09 16:27:33 +0800 | [diff] [blame] | 1826 | static gboolean gst_aml_video_sink_pad_event (GstBaseSink *basesink, GstEvent *event) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1827 | { |
| 1828 | gboolean result = TRUE; |
xuesong.jiang | 22afe86 | 2022-11-09 16:27:33 +0800 | [diff] [blame] | 1829 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(basesink); |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 1830 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1831 | |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 1832 | GST_DEBUG_OBJECT(sink, "received event %p %" GST_PTR_FORMAT, event, event); |
xuesong.jiang | 0ebc033 | 2022-07-05 10:58:02 +0800 | [diff] [blame] | 1833 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1834 | switch (GST_EVENT_TYPE(event)) |
| 1835 | { |
| 1836 | case GST_EVENT_FLUSH_START: |
| 1837 | { |
| 1838 | GST_INFO_OBJECT(sink, "flush start"); |
| 1839 | GST_OBJECT_LOCK(sink); |
| 1840 | sink_priv->is_flushing = TRUE; |
le.han | b62dfce | 2024-02-28 03:23:12 +0000 | [diff] [blame] | 1841 | render_set_value(sink_priv->render_device_handle, KEY_KEEP_LAST_FRAME_ON_FLUSH, &sink->keep_last_frame_on_flush); |
| 1842 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1843 | rotation_flush_buffer(sink); |
| 1844 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 1845 | if (render_flush(sink_priv->render_device_handle) == 0) |
| 1846 | { |
| 1847 | GST_INFO_OBJECT(sink, "recv flush start and set render lib flushing succ"); |
| 1848 | } |
xuesong.jiang | aed3094 | 2022-06-17 14:27:27 +0800 | [diff] [blame] | 1849 | GST_INFO_OBJECT(sink, "flush start done"); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1850 | GST_OBJECT_UNLOCK(sink); |
| 1851 | break; |
| 1852 | } |
| 1853 | case GST_EVENT_FLUSH_STOP: |
| 1854 | { |
| 1855 | GST_INFO_OBJECT(sink, "flush stop"); |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 1856 | GST_DEBUG_OBJECT(sink, "flushing need waitting display render all buf, queued:%d, rendered:%d, dropped:%d", |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 1857 | sink->queued, |
| 1858 | sink->rendered, |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 1859 | sink->dropped); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1860 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1861 | GST_OBJECT_LOCK(sink); |
xuesong.jiang | 28a8217 | 2022-04-28 15:05:46 +0800 | [diff] [blame] | 1862 | GST_INFO_OBJECT(sink, "flush all count num to zero"); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1863 | sink->queued = 0; |
| 1864 | sink->dequeued = 0; |
| 1865 | sink->rendered = 0; |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 1866 | sink->dropped = 0; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1867 | sink_priv->got_eos = FALSE; |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1868 | sink_priv->is_flushing = FALSE; |
xuesong.jiang | aed3094 | 2022-06-17 14:27:27 +0800 | [diff] [blame] | 1869 | GST_INFO_OBJECT(sink, "flush stop done"); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1870 | GST_OBJECT_UNLOCK(sink); |
| 1871 | break; |
| 1872 | } |
| 1873 | case GST_EVENT_SEGMENT: |
| 1874 | { |
| 1875 | GST_OBJECT_LOCK(sink); |
| 1876 | gst_event_copy_segment(event, &sink_priv->segment); |
| 1877 | GST_INFO_OBJECT(sink, "configured segment %" GST_SEGMENT_FORMAT, &sink_priv->segment); |
xuesong.jiang | aed3094 | 2022-06-17 14:27:27 +0800 | [diff] [blame] | 1878 | sink->last_displayed_buf_pts = sink_priv->segment.position; |
| 1879 | GST_INFO_OBJECT(sink, "update cur pos to %" GST_TIME_FORMAT, GST_TIME_ARGS(sink->last_displayed_buf_pts)); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1880 | GST_OBJECT_UNLOCK(sink); |
| 1881 | break; |
| 1882 | } |
sheng.liu | 5c98a4e | 2022-06-21 10:27:43 +0800 | [diff] [blame] | 1883 | case GST_EVENT_CUSTOM_DOWNSTREAM: |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 1884 | case GST_EVENT_CUSTOM_DOWNSTREAM_STICKY: |
sheng.liu | 5c98a4e | 2022-06-21 10:27:43 +0800 | [diff] [blame] | 1885 | { |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 1886 | if (gst_event_has_name(event, "IS_SVP")) |
sheng.liu | 5c98a4e | 2022-06-21 10:27:43 +0800 | [diff] [blame] | 1887 | { |
| 1888 | GST_OBJECT_LOCK(sink); |
| 1889 | GST_DEBUG_OBJECT(sink, "Got SVP Event"); |
| 1890 | sink->secure_mode = TRUE; |
| 1891 | GST_OBJECT_UNLOCK(sink); |
| 1892 | } |
hanghang.luo | c3ef985 | 2023-07-11 09:00:01 +0000 | [diff] [blame] | 1893 | |
xuesong.jiang | 16ae321 | 2022-07-12 15:32:10 +0800 | [diff] [blame] | 1894 | gst_event_unref(event); |
| 1895 | return result; |
xuesong.jiang | 0c1fb95 | 2022-06-24 21:20:16 +0800 | [diff] [blame] | 1896 | } |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1897 | case GST_EVENT_EOS: |
| 1898 | { |
| 1899 | GST_OBJECT_LOCK(sink); |
| 1900 | sink_priv->got_eos = TRUE; |
| 1901 | GST_OBJECT_UNLOCK(sink); |
| 1902 | |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1903 | //some frames aren't displayed,so don't pass this event to basesink |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 1904 | if (sink->queued > (sink->rendered + sink->dropped)) |
xuesong.jiang | 62ed50e | 2022-04-13 16:55:47 +0800 | [diff] [blame] | 1905 | { |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 1906 | GST_DEBUG_OBJECT(sink, "display render all buf, queued:%d, rendered:%d, dropped:%d", |
xuesong.jiang | 9ae8f88 | 2022-04-18 20:15:06 +0800 | [diff] [blame] | 1907 | sink->queued, |
| 1908 | sink->rendered, |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 1909 | sink->dropped); |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1910 | gst_event_unref(event); |
| 1911 | return result; |
xuesong.jiang | 62ed50e | 2022-04-13 16:55:47 +0800 | [diff] [blame] | 1912 | } |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 1913 | break; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 1914 | } |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 1915 | case GST_EVENT_TAG: |
| 1916 | { |
| 1917 | GstTagList *list = NULL; |
| 1918 | gst_event_parse_tag (event, &list); |
| 1919 | if (list) |
| 1920 | { |
| 1921 | gst_aml_video_sink_tag_event(sink, list); |
| 1922 | } |
| 1923 | break; |
| 1924 | } |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1925 | case GST_EVENT_CAPS: |
| 1926 | { |
| 1927 | GstCaps *caps; |
| 1928 | GstStructure *structure; |
| 1929 | gst_event_parse_caps(event, &caps); |
| 1930 | |
| 1931 | structure= gst_caps_get_structure(caps, 0); |
| 1932 | if (structure) |
| 1933 | { |
| 1934 | gint num, denom; |
| 1935 | if (gst_structure_get_fraction( structure, "framerate", &num, &denom )) |
| 1936 | { |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 1937 | GST_DEBUG_OBJECT(sink, "framerate num:%d,denom:%d",num,denom); |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1938 | if ( denom == 0 ) denom= 1; |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 1939 | sink->frame_rate= (double)num/(double)denom; |
| 1940 | if ( sink->frame_rate <= 0.0 ) |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1941 | { |
| 1942 | GST_DEBUG_OBJECT(sink, "caps have framerate of 0 - assume 60"); |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 1943 | sink->frame_rate= 60.0; |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1944 | } |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 1945 | if (sink->frame_rate_num != num || sink->frame_rate_denom != denom) { |
| 1946 | sink->frame_rate_num = num; |
| 1947 | sink->frame_rate_denom = denom; |
| 1948 | sink->frame_rate_changed = TRUE; |
| 1949 | } |
sheng.liu | 1a07969 | 2023-12-26 06:33:41 +0000 | [diff] [blame] | 1950 | |
| 1951 | if ( gst_structure_get_fraction( structure, "pixel-aspect-ratio", &num, &denom ) ) |
| 1952 | { |
| 1953 | if ( (num <= 0) || (denom <= 0)) |
| 1954 | { |
| 1955 | num = denom = 1; |
| 1956 | } |
| 1957 | sink->pixel_aspect_ratio = (double)num/(double)denom; |
| 1958 | sink->pixel_aspect_ratio_changed = TRUE; |
| 1959 | } |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 1960 | } |
| 1961 | } |
| 1962 | } break; |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1963 | default: |
| 1964 | { |
xuesong.jiang | 0ebc033 | 2022-07-05 10:58:02 +0800 | [diff] [blame] | 1965 | break; |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1966 | } |
| 1967 | } |
xuesong.jiang | 0ebc033 | 2022-07-05 10:58:02 +0800 | [diff] [blame] | 1968 | |
| 1969 | GST_DEBUG_OBJECT(sink, "pass to basesink"); |
| 1970 | result = GST_BASE_SINK_CLASS(parent_class)->event((GstBaseSink *)sink, event); |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 1971 | GST_DEBUG_OBJECT(sink, "done"); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 1972 | return result; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 1973 | } |
| 1974 | |
xuesong.jiang | 6903199 | 2022-06-09 19:30:35 +0800 | [diff] [blame] | 1975 | static gboolean gst_aml_video_sink_send_event(GstElement *element, GstEvent *event) |
| 1976 | { |
| 1977 | GstPad *pad = NULL; |
| 1978 | GstBaseSink *basesink = GST_BASE_SINK(element); |
| 1979 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(element); |
| 1980 | GstAmlVideoSinkClass *sink_class = GST_AML_VIDEO_SINK_GET_CLASS(sink); |
| 1981 | GstVideoSinkClass *sink_p_class = parent_class; |
| 1982 | GstBaseSinkClass *sink_pp_class = g_type_class_peek_parent(sink_p_class); |
| 1983 | gboolean result = TRUE; |
| 1984 | GstPadMode mode = GST_PAD_MODE_NONE; |
| 1985 | |
| 1986 | GST_DEBUG_OBJECT(sink, "amlvideosink_class:%p, videosink_class:%p, basesink_class:%p", sink_class, sink_p_class, sink_pp_class); |
| 1987 | GST_DEBUG_OBJECT(sink, "handling event %p %" GST_PTR_FORMAT, event, event); |
| 1988 | |
| 1989 | switch (GST_EVENT_TYPE(event)) |
| 1990 | { |
| 1991 | case GST_EVENT_SEEK: |
| 1992 | { |
| 1993 | GST_OBJECT_LOCK(element); |
| 1994 | /* get the pad and the scheduling mode */ |
| 1995 | pad = gst_object_ref(basesink->sinkpad); |
| 1996 | mode = basesink->pad_mode; |
| 1997 | GST_OBJECT_UNLOCK(element); |
| 1998 | |
| 1999 | if (mode == GST_PAD_MODE_PUSH) |
| 2000 | { |
| 2001 | GST_BASE_SINK_PREROLL_LOCK(basesink); |
| 2002 | if (GST_BASE_SINK(sink)->need_preroll && GST_BASE_SINK(sink)->have_preroll) |
| 2003 | { |
| 2004 | GST_DEBUG_OBJECT(sink, "reset preroll when recived seek event"); |
| 2005 | GST_BASE_SINK(sink)->need_preroll = FALSE; |
| 2006 | GST_BASE_SINK(sink)->have_preroll = FALSE; |
| 2007 | GST_BASE_SINK_PREROLL_SIGNAL(basesink); |
| 2008 | } |
| 2009 | GST_BASE_SINK_PREROLL_UNLOCK(basesink); |
| 2010 | } |
| 2011 | |
| 2012 | gst_object_unref(pad); |
| 2013 | break; |
| 2014 | } |
| 2015 | default: |
| 2016 | break; |
| 2017 | } |
| 2018 | |
| 2019 | if (GST_ELEMENT_CLASS(sink_pp_class)->send_event) |
| 2020 | { |
| 2021 | GST_DEBUG_OBJECT(sink, "use basesink class send event func handle event"); |
| 2022 | result = GST_ELEMENT_CLASS(sink_pp_class)->send_event(element, event); |
| 2023 | } |
| 2024 | else |
| 2025 | { |
| 2026 | GST_ERROR_OBJECT(sink, "can't find basesink send event func"); |
| 2027 | result = FALSE; |
| 2028 | } |
| 2029 | |
| 2030 | GST_DEBUG_OBJECT(sink, "handled event: %d", result); |
| 2031 | |
| 2032 | return result; |
| 2033 | } |
| 2034 | |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 2035 | /* private interface definition */ |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 2036 | static gboolean gst_aml_video_sink_check_buf(GstAmlVideoSink *sink, GstBuffer *buf) |
| 2037 | { |
| 2038 | gboolean ret = TRUE; |
| 2039 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
| 2040 | guint64 start, stop; |
| 2041 | guint64 cstart, cstop; |
| 2042 | GstSegment *segment; |
| 2043 | GstClockTime duration; |
| 2044 | |
| 2045 | /* Check for clipping */ |
| 2046 | start = GST_BUFFER_PTS(buf); |
| 2047 | duration = GST_BUFFER_DURATION(buf); |
| 2048 | stop = GST_CLOCK_TIME_NONE; |
| 2049 | |
| 2050 | if (GST_CLOCK_TIME_IS_VALID (start) && GST_CLOCK_TIME_IS_VALID (duration)) |
| 2051 | { |
| 2052 | stop = start + duration; |
| 2053 | } |
| 2054 | else if (GST_CLOCK_TIME_IS_VALID (start) && !GST_CLOCK_TIME_IS_VALID (duration)) |
| 2055 | { |
fei.deng | ab16ff1 | 2024-08-07 17:58:07 +0800 | [diff] [blame] | 2056 | if (start < sink_priv->segment.start) |
| 2057 | { |
| 2058 | ret = FALSE; |
| 2059 | goto drop; |
| 2060 | } |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 2061 | if (sink_priv->fps_n != 0) |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 2062 | { |
| 2063 | //TODO calc with framerate |
| 2064 | stop = start + 40 * GST_MSECOND; |
| 2065 | } |
| 2066 | else |
| 2067 | { |
| 2068 | /* If we don't clip away buffers that far before the segment we |
| 2069 | * can cause the pipeline to lockup. This can happen if audio is |
| 2070 | * properly clipped, and thus the audio sink does not preroll yet |
| 2071 | * but the video sink prerolls because we already outputted a |
| 2072 | * buffer here... and then queues run full. |
| 2073 | * |
| 2074 | * In the worst case we will clip one buffer too many here now if no |
| 2075 | * framerate is given, no buffer duration is given and the actual |
| 2076 | * framerate is lower than 25fps */ |
| 2077 | stop = start + 40 * GST_MSECOND; |
| 2078 | } |
| 2079 | } |
| 2080 | |
| 2081 | segment = &sink_priv->segment; |
| 2082 | GST_LOG_OBJECT(sink, "check buffer start: %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT "fps_n:%d, fps_d:%d", |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 2083 | GST_TIME_ARGS(start), GST_TIME_ARGS(stop), sink_priv->fps_n, sink_priv->fps_d); |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 2084 | if (gst_segment_clip(segment, GST_FORMAT_TIME, start, stop, &cstart, &cstop)) |
| 2085 | { |
| 2086 | GST_BUFFER_PTS(buf) = cstart; |
| 2087 | |
| 2088 | if (stop != GST_CLOCK_TIME_NONE && GST_CLOCK_TIME_IS_VALID(duration)) |
| 2089 | GST_BUFFER_DURATION(buf) = cstop - cstart; |
| 2090 | |
| 2091 | GST_LOG_OBJECT(sink, |
| 2092 | "accepting buffer inside segment: %" GST_TIME_FORMAT " %" GST_TIME_FORMAT " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT |
| 2093 | " time %" GST_TIME_FORMAT, |
| 2094 | GST_TIME_ARGS(cstart), |
| 2095 | GST_TIME_ARGS(cstop), |
| 2096 | GST_TIME_ARGS(segment->start), GST_TIME_ARGS(segment->stop), |
| 2097 | GST_TIME_ARGS(segment->time)); |
| 2098 | } |
| 2099 | else |
| 2100 | { |
| 2101 | GST_LOG_OBJECT(sink, |
| 2102 | "dropping buffer outside segment: %" GST_TIME_FORMAT |
| 2103 | " %" GST_TIME_FORMAT |
| 2104 | " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT |
| 2105 | " time %" GST_TIME_FORMAT, |
| 2106 | GST_TIME_ARGS(start), GST_TIME_ARGS(stop), |
| 2107 | GST_TIME_ARGS(segment->start), |
| 2108 | GST_TIME_ARGS(segment->stop), GST_TIME_ARGS(segment->time)); |
| 2109 | |
| 2110 | ret = FALSE; |
| 2111 | } |
fei.deng | ab16ff1 | 2024-08-07 17:58:07 +0800 | [diff] [blame] | 2112 | drop: |
xuesong.jiang | 8e09c74 | 2022-07-27 16:38:32 +0800 | [diff] [blame] | 2113 | return ret; |
| 2114 | } |
| 2115 | |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2116 | static void gst_aml_video_sink_reset_private(GstAmlVideoSink *sink) |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 2117 | { |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2118 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | a52aa5b | 2022-05-13 16:00:32 +0800 | [diff] [blame] | 2119 | #if GST_IMPORT_LGE_PROP |
| 2120 | if (sink_priv->lge_ctxt.app_type) |
| 2121 | g_free(sink_priv->lge_ctxt.app_type); |
| 2122 | if (sink_priv->lge_ctxt.res_info.coretype) |
| 2123 | g_free(sink_priv->lge_ctxt.res_info.coretype); |
| 2124 | #endif |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2125 | memset(sink_priv, 0, sizeof(GstAmlVideoSinkPrivate)); |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2126 | sink_priv->use_dmabuf = USE_DMABUF; |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2127 | sink_priv->mediasync_instanceid = -1; |
fei.deng | 978b242 | 2023-11-30 10:33:23 +0000 | [diff] [blame] | 2128 | sink_priv->show_first_frame_asap = FALSE; |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 2129 | sink_priv->emitUnderflowSignal = FALSE; |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2130 | if (sink_priv->reportInfos) { |
| 2131 | g_list_free(sink_priv->reportInfos); |
| 2132 | } |
| 2133 | sink_priv->reportInfos = NULL; |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 2134 | sink_priv->frame_step_on_preroll = FALSE; |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 2135 | |
| 2136 | sink_priv->format = GST_VIDEO_FORMAT_UNKNOWN; |
| 2137 | sink_priv->interlace = FALSE; |
| 2138 | sink_priv->dw_width = 0; |
| 2139 | sink_priv->dw_height = 0; |
| 2140 | sink_priv->src_width = 0; |
| 2141 | sink_priv->src_height = 0; |
| 2142 | sink_priv->dw_size = 0; |
le.han | 30f126e | 2024-10-09 02:42:55 +0000 | [diff] [blame] | 2143 | sink_priv->dw_mode = -1; |
| 2144 | sink_priv->stride = 0; |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 2145 | sink_priv->par_n = 0; |
| 2146 | sink_priv->par_d = 0; |
| 2147 | sink_priv->fps_n = 0; |
| 2148 | sink_priv->fps_d = 0; |
fei.deng | 3a374e5 | 2024-10-29 17:04:42 +0800 | [diff] [blame] | 2149 | sink_priv->video_latency = 0; |
| 2150 | sink_priv->set_video_latency = FALSE; |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2151 | sink_priv->rot_buffer = NULL; |
| 2152 | sink_priv->rot_degree = WST_ROTATION_0; |
| 2153 | sink_priv->rot_changed = FALSE; |
| 2154 | sink_priv->rot_enable_property = FALSE; |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 2155 | sink_priv->force_aspect_ratio = FALSE; |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2156 | } |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2157 | |
le.han | 9ff888d | 2024-09-09 03:04:31 +0000 | [diff] [blame] | 2158 | static void gst_set_report_info(void *userData, RenderMsgType type, int64_t pts, int64_t duration) |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2159 | { |
| 2160 | GstAmlVideoSink *sink = (GstAmlVideoSink *)userData; |
| 2161 | g_mutex_lock(&sink->report_info_lock); |
| 2162 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
| 2163 | ReportInfo *report_info = g_new(ReportInfo, 1); |
| 2164 | report_info->msg = type; |
| 2165 | report_info->info.pts = pts; |
| 2166 | report_info->info.duration = duration; |
| 2167 | sink_priv->reportInfos = g_list_append(sink_priv->reportInfos, report_info); |
| 2168 | GST_LOG_OBJECT(sink, "msg:%d pts:%lld duration:%lld", type, pts, duration); |
| 2169 | g_mutex_unlock(&sink->report_info_lock); |
| 2170 | } |
| 2171 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2172 | static gboolean is_rotation_buffer(void *userData, void* pbuf) |
| 2173 | { |
| 2174 | GstAmlVideoSink *sink = (GstAmlVideoSink *)userData; |
| 2175 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
| 2176 | |
| 2177 | // no rotation buffer |
| 2178 | if (!sink_priv->rot_buffer) |
| 2179 | { |
| 2180 | return FALSE; |
| 2181 | } |
| 2182 | |
| 2183 | ROTBuffer* rotation_buffer = (ROTBuffer*)pbuf; |
| 2184 | for (int i = 0; i < ROT_BUFFER_MAX; i++) |
| 2185 | { |
| 2186 | if (rotation_buffer == &sink_priv->rot_buffer[i]) |
| 2187 | { |
| 2188 | return TRUE; |
| 2189 | } |
| 2190 | } |
| 2191 | return FALSE; |
| 2192 | } |
| 2193 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2194 | static void gst_render_msg_callback(void *userData, RenderMsgType type, void *msg) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2195 | { |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2196 | GstAmlVideoSink *sink = (GstAmlVideoSink *)userData; |
fei.deng | 5673347 | 2024-09-19 20:12:43 +0800 | [diff] [blame] | 2197 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2198 | switch (type) |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2199 | { |
xuesong.jiang | 28a8217 | 2022-04-28 15:05:46 +0800 | [diff] [blame] | 2200 | case MSG_DROPED_BUFFER: |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 2201 | case MSG_DISPLAYED_BUFFER: |
| 2202 | { |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 2203 | RenderBuffer *tunnel_lib_buf_wrap = (RenderBuffer *)msg; |
| 2204 | RenderDmaBuffer *dmabuf = &tunnel_lib_buf_wrap->dma; |
xuesong.jiang | 28a8217 | 2022-04-28 15:05:46 +0800 | [diff] [blame] | 2205 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2206 | if (tunnel_lib_buf_wrap->priv) |
| 2207 | { |
| 2208 | sink->last_displayed_buf_pts = tunnel_lib_buf_wrap->pts; |
| 2209 | if (type == MSG_DROPED_BUFFER) |
| 2210 | { |
| 2211 | GST_LOG_OBJECT(sink, "get message: MSG_DROPED_BUFFER from tunnel lib"); |
| 2212 | sink->dropped++; |
| 2213 | gst_set_report_info(userData, type, tunnel_lib_buf_wrap->pts, 0); |
| 2214 | } |
| 2215 | else if (type == MSG_DISPLAYED_BUFFER) |
| 2216 | { |
| 2217 | GST_LOG_OBJECT(sink, "get message: MSG_DISPLAYED_BUFFER from tunnel lib"); |
| 2218 | sink->rendered++; |
| 2219 | if (sink_priv->frame_step_on_preroll && sink->video_playing == FALSE) { |
| 2220 | render_pause(sink_priv->render_device_handle); |
| 2221 | } |
| 2222 | } |
| 2223 | GST_DEBUG_OBJECT(sink, "buf:%p planeCnt:%d, plane[0].fd:%d, plane[1].fd:%d pts:%lld, buf stat | queued:%d, dequeued:%d, dropped:%d, rendered:%d", |
| 2224 | tunnel_lib_buf_wrap->priv, |
| 2225 | dmabuf->planeCnt, dmabuf->fd[0], dmabuf->fd[1], |
| 2226 | tunnel_lib_buf_wrap->priv ? tunnel_lib_buf_wrap->pts : -1, sink->queued, sink->dequeued, sink->dropped, sink->rendered); |
| 2227 | //gst_aml_video_sink_dump_stat(sink, GST_DUMP_STAT_FILENAME); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 2228 | } |
| 2229 | else |
| 2230 | { |
xuesong.jiang | 28a8217 | 2022-04-28 15:05:46 +0800 | [diff] [blame] | 2231 | GST_ERROR_OBJECT(sink, "tunnel lib: return void GstBuffer when MSG_DISPLAYED_BUFFER or MSG_DROPED_BUFFER"); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 2232 | } |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 2233 | break; |
| 2234 | } |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2235 | case MSG_RELEASE_BUFFER: |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2236 | { |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2237 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2238 | RenderBuffer *tunnel_lib_buf_wrap = (RenderBuffer *)msg; |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2239 | GST_LOG_OBJECT(sink, "get message: MSG_RELEASE_BUFFER from tunnel lib,%p, pts:%lld ns",tunnel_lib_buf_wrap->priv, tunnel_lib_buf_wrap->pts); |
| 2240 | if (tunnel_lib_buf_wrap->priv) |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2241 | { |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2242 | if (is_rotation_buffer(userData, tunnel_lib_buf_wrap->priv)) |
| 2243 | { |
| 2244 | ROTBuffer* rotation_buffer = (ROTBuffer*)tunnel_lib_buf_wrap->priv; |
| 2245 | rotation_buffer->used = FALSE; |
| 2246 | /*printf("release [%d][%d][%d][%d][%d]\n", sink_priv->rot_buffer[0].used, sink_priv->rot_buffer[1].used, |
| 2247 | sink_priv->rot_buffer[2].used, sink_priv->rot_buffer[3].used, sink_priv->rot_buffer[4].used);*/ |
| 2248 | } |
| 2249 | else |
| 2250 | { |
| 2251 | GstBuffer *buffer = (GstBuffer *)tunnel_lib_buf_wrap->priv; |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 2252 | GST_DEBUG_OBJECT(sink, "get message: MSG_RELEASE_BUFFER from tunnel lib, buffer:%p, from pool:%p", buffer, buffer->pool); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2253 | gst_buffer_unref(buffer); |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2254 | } |
| 2255 | sink->dequeued++; |
| 2256 | //gst_aml_video_sink_dump_stat(sink, GST_DUMP_STAT_FILENAME); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2257 | } |
| 2258 | else |
| 2259 | { |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2260 | GST_ERROR_OBJECT(sink, "tunnel lib: return void GstBuffer when MSG_RELEASE_BUFFER"); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2261 | } |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2262 | |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2263 | render_free_render_buffer_wrap(sink_priv->render_device_handle, tunnel_lib_buf_wrap); |
| 2264 | break; |
| 2265 | } |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2266 | case MSG_FIRST_FRAME: { |
| 2267 | GST_LOG_OBJECT(sink, "signal first frame"); |
| 2268 | g_signal_emit (G_OBJECT (sink), g_signals[SIGNAL_FIRSTFRAME], 0, 2, NULL); |
| 2269 | } break; |
| 2270 | case MSG_UNDER_FLOW: { |
fei.deng | 520f8cf | 2023-11-15 06:31:06 +0000 | [diff] [blame] | 2271 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 2272 | if (sink->video_playing && !sink_priv->got_eos) { |
fei.deng | 520f8cf | 2023-11-15 06:31:06 +0000 | [diff] [blame] | 2273 | GST_LOG_OBJECT(sink, "signal under flow"); |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 2274 | sink_priv->emitUnderflowSignal = TRUE; |
fei.deng | 520f8cf | 2023-11-15 06:31:06 +0000 | [diff] [blame] | 2275 | } |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2276 | } break; |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2277 | case MSG_FRAME_FREEZE: { |
| 2278 | FrameDisplayInfo *info = (FrameDisplayInfo *) msg; |
| 2279 | gst_set_report_info(userData, type, info->pts, info->duration); |
| 2280 | } break; |
| 2281 | case MSG_AV_RESYNC: { |
| 2282 | FrameDisplayInfo *info = (FrameDisplayInfo *) msg; |
| 2283 | gst_set_report_info(userData, type, info->pts, info->duration); |
| 2284 | } break; |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2285 | default: |
| 2286 | { |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2287 | GST_ERROR_OBJECT(sink, "tunnel lib: error message type:%d", type); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2288 | } |
| 2289 | } |
| 2290 | return; |
| 2291 | } |
| 2292 | |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2293 | static int gst_render_val_callback(void *userData, int key, void *value) |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2294 | { |
| 2295 | GstAmlVideoSink *vsink = (GstAmlVideoSink *)userData; |
| 2296 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(vsink); |
xuesong.jiang | 32d7828 | 2021-11-18 19:24:15 +0800 | [diff] [blame] | 2297 | int *val = (int *)value; |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2298 | gint ret = 0; |
xuesong.jiang | 8e8a58a | 2021-11-15 17:02:41 +0800 | [diff] [blame] | 2299 | switch (key) |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2300 | { |
xuesong.jiang | 75ef01c | 2021-12-09 17:08:52 +0800 | [diff] [blame] | 2301 | case KEY_MEDIASYNC_INSTANCE_ID: |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2302 | { |
| 2303 | if (gst_get_mediasync_instanceid(vsink)) |
| 2304 | { |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 2305 | int hasAudio = 1; |
xuesong.jiang | 8e8a58a | 2021-11-15 17:02:41 +0800 | [diff] [blame] | 2306 | *val = sink_priv->mediasync_instanceid; |
| 2307 | GST_DEBUG_OBJECT(vsink, "get mediasync instance id:%d", *val); |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2308 | render_set_value(sink_priv->render_device_handle, KEY_MEDIASYNC_SYNC_MODE, (void *)&vsink->avsync_mode); |
| 2309 | render_set_value(sink_priv->render_device_handle, KEY_MEDIASYNC_HAS_AUDIO, (void *)&hasAudio); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2310 | } |
| 2311 | else |
| 2312 | { |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2313 | int hasAudio = 0; |
| 2314 | vsink->avsync_mode = 0;// 0:v master, 1:a master |
| 2315 | render_set_value(sink_priv->render_device_handle, KEY_MEDIASYNC_SYNC_MODE, (void *)&vsink->avsync_mode); |
| 2316 | render_set_value(sink_priv->render_device_handle, KEY_MEDIASYNC_HAS_AUDIO, (void *)&hasAudio); |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 2317 | GST_ERROR_OBJECT(vsink, "can't get mediasync instance id, use vmaster"); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2318 | ret = -1; |
| 2319 | } |
| 2320 | break; |
| 2321 | } |
| 2322 | case KEY_VIDEO_FORMAT: |
| 2323 | { |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 2324 | *val = sink_priv->format; |
| 2325 | GST_DEBUG_OBJECT(vsink, "get video format:%d", *val); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2326 | break; |
| 2327 | } |
| 2328 | default: |
| 2329 | { |
| 2330 | GST_ERROR_OBJECT(vsink, "tunnel lib: error key type"); |
| 2331 | ret = -1; |
| 2332 | } |
| 2333 | } |
| 2334 | return ret; |
| 2335 | } |
| 2336 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2337 | static int get_rotation_buffer_idx(GstAmlVideoSink *vsink) |
| 2338 | { |
| 2339 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(vsink); |
| 2340 | |
| 2341 | if (sink_priv->rot_buffer) |
| 2342 | { |
| 2343 | for (int i = 0; i < ROT_BUFFER_MAX; i++) |
| 2344 | { |
| 2345 | if (!sink_priv->rot_buffer[i].used) |
| 2346 | { |
| 2347 | /*printf("ok [%d][%d][%d][%d][%d]\n", sink_priv->rot_buffer[0].used, sink_priv->rot_buffer[1].used, |
| 2348 | sink_priv->rot_buffer[2].used, sink_priv->rot_buffer[3].used, sink_priv->rot_buffer[4].used);*/ |
| 2349 | return i; |
| 2350 | } |
| 2351 | } |
| 2352 | /*printf("fail [%d][%d][%d][%d][%d]\n", sink_priv->rot_buffer[0].used, sink_priv->rot_buffer[1].used, |
| 2353 | sink_priv->rot_buffer[2].used, sink_priv->rot_buffer[3].used, sink_priv->rot_buffer[4].used);*/ |
| 2354 | } |
| 2355 | |
| 2356 | return -1; |
| 2357 | } |
| 2358 | |
| 2359 | static void set_video_reversal(GstAmlVideoSink *vsink) |
| 2360 | { |
| 2361 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(vsink); |
| 2362 | sink_priv->video_info_changed = TRUE; |
| 2363 | int degree = (sink_priv->rot_degree == WST_ROTATION_180 ? 180 : 0); |
| 2364 | if (render_set_value(sink_priv->render_device_handle, KEY_ROTATE_VIDEO, °ree) != -1) |
| 2365 | { |
| 2366 | GST_ERROR_OBJECT(vsink, "tunnel lib: set render video rotation success:%d", degree); |
| 2367 | sink_priv->rot_changed = FALSE; |
| 2368 | } |
| 2369 | else |
| 2370 | { |
| 2371 | GST_ERROR_OBJECT(vsink, "tunnel lib: set render video rotation failed:%d", degree); |
| 2372 | } |
| 2373 | } |
| 2374 | |
xuesong.jiang | 7c724a5 | 2021-10-22 17:18:58 +0800 | [diff] [blame] | 2375 | static gboolean gst_aml_video_sink_tunnel_buf(GstAmlVideoSink *vsink, GstBuffer *gst_buf, RenderBuffer *tunnel_lib_buf_wrap) |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2376 | { |
le.han | 30f126e | 2024-10-09 02:42:55 +0000 | [diff] [blame] | 2377 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(vsink); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2378 | // only support dma buf |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2379 | RenderDmaBuffer *dmabuf = &tunnel_lib_buf_wrap->dma; |
xuesong.jiang | 8e8a58a | 2021-11-15 17:02:41 +0800 | [diff] [blame] | 2380 | GstMemory *dma_mem = NULL; |
| 2381 | GstVideoMeta *vmeta = NULL; |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2382 | guint n_mem = 0; |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2383 | gboolean ret = TRUE; |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2384 | |
xuesong.jiang | eb46f67 | 2021-11-19 19:05:56 +0800 | [diff] [blame] | 2385 | if (gst_buf == NULL || tunnel_lib_buf_wrap == NULL || dmabuf == NULL) |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2386 | { |
| 2387 | GST_ERROR_OBJECT(vsink, "input params error"); |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2388 | ret = FALSE; |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2389 | goto error; |
| 2390 | } |
xuesong.jiang | 3e59343 | 2021-11-25 16:10:03 +0800 | [diff] [blame] | 2391 | gst_buffer_ref(gst_buf); |
xuesong.jiang | 8e8a58a | 2021-11-15 17:02:41 +0800 | [diff] [blame] | 2392 | n_mem = gst_buffer_n_memory(gst_buf); |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 2393 | vmeta = gst_buffer_get_video_meta(gst_buf); |
| 2394 | if (vmeta == NULL) |
xuesong.jiang | 8e8a58a | 2021-11-15 17:02:41 +0800 | [diff] [blame] | 2395 | { |
| 2396 | GST_ERROR_OBJECT(vsink, "not found video meta info"); |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2397 | ret = FALSE; |
xuesong.jiang | 8e8a58a | 2021-11-15 17:02:41 +0800 | [diff] [blame] | 2398 | goto error; |
| 2399 | } |
| 2400 | if (n_mem > RENDER_MAX_PLANES || vmeta->n_planes > RENDER_MAX_PLANES || n_mem != vmeta->n_planes) |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2401 | { |
| 2402 | GST_ERROR_OBJECT(vsink, "too many memorys in gst buffer"); |
| 2403 | goto error; |
| 2404 | } |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 2405 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2406 | // weston do rotation, set rotation 180 or 0 |
| 2407 | if (sink_priv->rot_changed) |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2408 | { |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2409 | set_video_reversal(vsink); |
| 2410 | } |
| 2411 | dmabuf->planeCnt = n_mem; |
| 2412 | if (sink_priv->rot_degree == WST_ROTATION_90 || sink_priv->rot_degree == WST_ROTATION_270) |
| 2413 | { |
| 2414 | // get output size, and align 32byte |
| 2415 | get_rotation_size(vmeta->height, vmeta->width, &dmabuf->width, &dmabuf->height); |
| 2416 | // create ROT buf |
| 2417 | if (!sink_priv->rot_buffer) |
| 2418 | { |
| 2419 | sink_priv->video_info_changed = TRUE; |
| 2420 | GST_ERROR_OBJECT(vsink, "planeCnt:%d, width:%d, height:%d", dmabuf->planeCnt, dmabuf->width, dmabuf->height); |
| 2421 | sink_priv->rot_buffer = rotation_buffer_setup(dmabuf->planeCnt, dmabuf->width, dmabuf->height, ROT_BUFFER_MAX); |
| 2422 | } |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2423 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2424 | // get ROT buf |
| 2425 | int index = get_rotation_buffer_idx(vsink); |
| 2426 | if (-1 == index) |
| 2427 | { |
| 2428 | GST_ERROR_OBJECT(vsink, "cant get rotation buffer"); |
| 2429 | vsink->dropped++; |
| 2430 | goto error; |
| 2431 | } |
| 2432 | // do transform |
| 2433 | if (GST_FLOW_OK == rotation_transform(sink_priv->pge2dinfo, gst_buf, &sink_priv->rot_buffer[index], sink_priv->rot_degree)) |
| 2434 | { |
| 2435 | sink_priv->rot_buffer[index].used = TRUE; |
| 2436 | } |
xuesong.jiang | 16983c9 | 2021-12-30 10:57:17 +0800 | [diff] [blame] | 2437 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2438 | // ROT buffer trans to RenderBuffer |
| 2439 | for (guint i = 0; i < dmabuf->planeCnt; i++) |
| 2440 | { |
xuesong.jiang | 8e8a58a | 2021-11-15 17:02:41 +0800 | [diff] [blame] | 2441 | dmabuf->handle[i] = 0; |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2442 | dmabuf->fd[i] = sink_priv->rot_buffer[index].gemBuf.fd[i]; |
| 2443 | if ( i == 0 ) |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2444 | { |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2445 | dmabuf->size[i] = sink_priv->rot_buffer[index].gemBuf.width * sink_priv->rot_buffer[index].gemBuf.height; |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2446 | } |
| 2447 | else |
| 2448 | { |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2449 | dmabuf->size[i] = sink_priv->rot_buffer[index].gemBuf.width * sink_priv->rot_buffer[index].gemBuf.height/2; |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2450 | } |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2451 | dmabuf->stride[i] = sink_priv->rot_buffer[index].gemBuf.stride[i]; |
| 2452 | dmabuf->offset[i] = sink_priv->rot_buffer[index].gemBuf.offset[i]; |
| 2453 | } |
| 2454 | tunnel_lib_buf_wrap->flag = BUFFER_FLAG_DMA_BUFFER; |
| 2455 | tunnel_lib_buf_wrap->priv = (void *)&sink_priv->rot_buffer[index]; |
| 2456 | tunnel_lib_buf_wrap->pts = GST_BUFFER_PTS(gst_buf); |
| 2457 | // unref gstbuf |
| 2458 | gst_buffer_unref(gst_buf); |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2459 | } |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2460 | else |
| 2461 | { |
| 2462 | dmabuf->width = vmeta->width; |
| 2463 | dmabuf->height = vmeta->height; |
| 2464 | if (sink_priv->dw_mode == 0) { |
| 2465 | dmabuf->width = sink_priv->src_width; |
| 2466 | dmabuf->height = sink_priv->src_height; |
| 2467 | } |
| 2468 | // gstbuffer trans to RenderBuffer |
| 2469 | for (guint i = 0; i < n_mem; i++) |
| 2470 | { |
| 2471 | gint dmafd; |
| 2472 | gsize size, offset, maxsize; |
| 2473 | dma_mem = gst_buffer_peek_memory(gst_buf, i); |
| 2474 | guint mem_idx = 0; |
| 2475 | guint length = 0; |
| 2476 | gsize skip = 0; |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 2477 | |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2478 | if (!gst_is_dmabuf_memory(dma_mem)) |
| 2479 | { |
| 2480 | GST_ERROR_OBJECT(vsink, "not support non-dma buf"); |
| 2481 | ret = FALSE; |
| 2482 | goto error; |
| 2483 | } |
| 2484 | size = gst_memory_get_sizes(dma_mem, &offset, &maxsize); |
| 2485 | GST_LOG_OBJECT(vsink, "get memory size:%d, offset:%d, maxsize:%d", size, offset, maxsize); |
| 2486 | |
| 2487 | dmafd = gst_dmabuf_memory_get_fd(dma_mem); |
| 2488 | dmabuf->handle[i] = 0; |
| 2489 | dmabuf->fd[i] = dmafd; |
| 2490 | dmabuf->size[i] = dma_mem->size; |
| 2491 | dmabuf->stride[i] = vmeta->stride[i]; |
| 2492 | if (sink_priv->dw_mode == 0) { |
| 2493 | dmabuf->stride[i] = sink_priv->stride; |
| 2494 | } |
| 2495 | if (gst_buffer_find_memory(gst_buf, vmeta->offset[i], 1, &mem_idx, &length, &skip) && mem_idx == i) |
| 2496 | { |
| 2497 | dmabuf->offset[i] = dma_mem->offset + skip; |
| 2498 | //GST_DEBUG_OBJECT(vsink, "get skip from buffer:%d, offset[%d]:%d", skip, i, dmabuf->offset[i]); |
| 2499 | } |
| 2500 | else |
| 2501 | { |
| 2502 | GST_ERROR_OBJECT(vsink, "get skip from buffer error"); |
| 2503 | } |
| 2504 | GST_LOG_OBJECT(vsink, "dma buffer layer:%d, handle:%d, fd:%d, size:%d, offset:%d, stride:%d", |
| 2505 | i, dmabuf->handle[i], dmabuf->fd[i], dmabuf->size[i], dmabuf->offset[i], dmabuf->stride[i]); |
| 2506 | } |
| 2507 | tunnel_lib_buf_wrap->flag = BUFFER_FLAG_DMA_BUFFER; |
| 2508 | tunnel_lib_buf_wrap->priv = (void *)gst_buf; |
| 2509 | tunnel_lib_buf_wrap->pts = GST_BUFFER_PTS(gst_buf); |
| 2510 | GST_LOG_OBJECT(vsink, "set tunnel lib buf priv:%p from pool:%p, pts:%lld", tunnel_lib_buf_wrap->priv, gst_buf->pool, tunnel_lib_buf_wrap->pts); |
| 2511 | } |
xuesong.jiang | e90be37 | 2021-10-21 11:29:57 +0800 | [diff] [blame] | 2512 | |
| 2513 | error: |
xuesong.jiang | f190e2a | 2021-11-22 20:26:00 +0800 | [diff] [blame] | 2514 | return ret; |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 2515 | } |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2516 | |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2517 | static gboolean gst_get_mediasync_instanceid(GstAmlVideoSink *vsink) |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2518 | { |
xuesong.jiang | 75ef01c | 2021-12-09 17:08:52 +0800 | [diff] [blame] | 2519 | GST_DEBUG_OBJECT(vsink, "trace in"); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2520 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(vsink); |
| 2521 | GstElement *asink = gst_aml_video_sink_find_audio_sink(vsink); |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 2522 | if (!asink) |
| 2523 | { |
| 2524 | GST_DEBUG_OBJECT(vsink, "pipeline don't have audio sink element"); |
| 2525 | return FALSE; |
| 2526 | } |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2527 | gboolean ret = TRUE; |
fei.deng | 2dee940 | 2023-05-06 08:21:21 +0000 | [diff] [blame] | 2528 | GParamSpec* spec = NULL; |
| 2529 | spec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(asink)), "avsync-session"); |
| 2530 | GST_DEBUG_OBJECT(vsink, "check amlhalasink has avsync-session property %p", spec); |
| 2531 | if (spec) |
| 2532 | g_object_get (G_OBJECT(asink), "avsync-session", &sink_priv->mediasync_instanceid, NULL); |
| 2533 | |
| 2534 | GST_DEBUG_OBJECT(vsink, "get mediasync instance id:%d, from amlhalasink:%p", sink_priv->mediasync_instanceid, asink); |
| 2535 | |
| 2536 | if (sink_priv->mediasync_instanceid == -1) |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2537 | { |
fei.deng | 2dee940 | 2023-05-06 08:21:21 +0000 | [diff] [blame] | 2538 | GST_ERROR_OBJECT(vsink, "audio sink: don't have valid mediasync instance id"); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2539 | ret = FALSE; |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2540 | } |
xuesong.jiang | 192316f | 2021-10-27 14:51:56 +0800 | [diff] [blame] | 2541 | gst_object_unref(asink); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2542 | return ret; |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2543 | } |
| 2544 | |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2545 | static GstElement *gst_aml_video_sink_find_audio_sink(GstAmlVideoSink *sink) |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2546 | { |
xuesong.jiang | 75ef01c | 2021-12-09 17:08:52 +0800 | [diff] [blame] | 2547 | GST_DEBUG_OBJECT(sink, "trace in"); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2548 | GstElement *audioSink = 0; |
| 2549 | GstElement *pipeline = 0; |
| 2550 | GstElement *element, *elementPrev = 0; |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2551 | |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2552 | element = GST_ELEMENT_CAST(sink); |
| 2553 | do |
| 2554 | { |
| 2555 | if (elementPrev) |
| 2556 | { |
| 2557 | gst_object_unref(elementPrev); |
| 2558 | } |
fei.deng | eb170e2 | 2023-11-08 04:24:19 +0000 | [diff] [blame] | 2559 | // TODO use this func will ref element,unref when done |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2560 | element = GST_ELEMENT_CAST(gst_element_get_parent(element)); |
| 2561 | if (element) |
| 2562 | { |
| 2563 | elementPrev = pipeline; |
| 2564 | pipeline = element; |
| 2565 | } |
| 2566 | } while (element != 0); |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2567 | |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2568 | if (pipeline) |
| 2569 | { |
| 2570 | GstIterator *iterElement = gst_bin_iterate_recurse(GST_BIN(pipeline)); |
| 2571 | if (iterElement) |
| 2572 | { |
| 2573 | GValue itemElement = G_VALUE_INIT; |
| 2574 | while (gst_iterator_next(iterElement, &itemElement) == GST_ITERATOR_OK) |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2575 | { |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2576 | element = (GstElement *)g_value_get_object(&itemElement); |
| 2577 | if (element && !GST_IS_BIN(element)) |
| 2578 | { |
| 2579 | int numSrcPads = 0; |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2580 | |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2581 | GstIterator *iterPad = gst_element_iterate_src_pads(element); |
| 2582 | if (iterPad) |
| 2583 | { |
| 2584 | GValue itemPad = G_VALUE_INIT; |
| 2585 | while (gst_iterator_next(iterPad, &itemPad) == GST_ITERATOR_OK) |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2586 | { |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2587 | GstPad *pad = (GstPad *)g_value_get_object(&itemPad); |
| 2588 | if (pad) |
| 2589 | { |
| 2590 | ++numSrcPads; |
| 2591 | } |
| 2592 | g_value_reset(&itemPad); |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2593 | } |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2594 | gst_iterator_free(iterPad); |
| 2595 | } |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2596 | |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2597 | if (numSrcPads == 0) |
| 2598 | { |
| 2599 | GstElementClass *ec = GST_ELEMENT_GET_CLASS(element); |
| 2600 | if (ec) |
| 2601 | { |
| 2602 | const gchar *meta = gst_element_class_get_metadata(ec, GST_ELEMENT_METADATA_KLASS); |
| 2603 | if (meta && strstr(meta, "Sink") && strstr(meta, "Audio")) |
| 2604 | { |
| 2605 | audioSink = (GstElement *)gst_object_ref(element); |
| 2606 | gchar *name = gst_element_get_name(element); |
| 2607 | if (name) |
| 2608 | { |
| 2609 | GST_DEBUG("detected audio sink: name (%s)", name); |
| 2610 | g_free(name); |
| 2611 | } |
| 2612 | g_value_reset(&itemElement); |
| 2613 | break; |
| 2614 | } |
| 2615 | } |
| 2616 | } |
| 2617 | } |
| 2618 | g_value_reset(&itemElement); |
| 2619 | } |
| 2620 | gst_iterator_free(iterElement); |
| 2621 | } |
| 2622 | |
| 2623 | gst_object_unref(pipeline); |
| 2624 | } |
xuesong.jiang | 4a832aa | 2022-01-06 16:44:26 +0800 | [diff] [blame] | 2625 | GST_DEBUG_OBJECT(sink, "trace out get audioSink:%p", audioSink); |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2626 | return audioSink; |
| 2627 | } |
| 2628 | |
| 2629 | static gboolean gst_render_set_params(GstVideoSink *vsink) |
| 2630 | { |
| 2631 | GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(vsink); |
| 2632 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
xuesong.jiang | bb769f0 | 2022-05-17 15:04:40 +0800 | [diff] [blame] | 2633 | int tunnelmode = 0; // 1 for tunnel mode; 0 for non-tunnel mode |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2634 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 2635 | RenderFrameSize frame_size = {sink_priv->src_width, sink_priv->src_height}; |
kaiqiang.xiang | d8184ff | 2024-10-09 14:35:02 +0800 | [diff] [blame] | 2636 | if ((sink_priv->rot_degree == WST_ROTATION_90 || sink_priv->rot_degree == WST_ROTATION_270) && sink_priv->rot_buffer) |
| 2637 | { |
| 2638 | frame_size.width = sink_priv->rot_buffer[0].gemBuf.width; |
| 2639 | frame_size.height = sink_priv->rot_buffer[0].gemBuf.height; |
| 2640 | } |
| 2641 | |
bo.xiao | 611b8e4 | 2024-07-18 11:33:46 +0800 | [diff] [blame] | 2642 | GstVideoFormat format = sink_priv->format; |
fei.deng | bdb18e5 | 2023-08-16 06:42:34 +0000 | [diff] [blame] | 2643 | |
| 2644 | if (render_set_value(sink_priv->render_device_handle, KEY_MEDIASYNC_TUNNEL_MODE, (void *)&tunnelmode) == -1) |
| 2645 | { |
| 2646 | GST_ERROR_OBJECT(vsink, "tunnel lib: set tunnelmode error"); |
| 2647 | return FALSE; |
| 2648 | } |
| 2649 | if (render_set_value(sink_priv->render_device_handle, KEY_FRAME_SIZE, &frame_size) == -1) |
| 2650 | { |
| 2651 | GST_ERROR_OBJECT(vsink, "tunnel lib: set frame size error"); |
| 2652 | return FALSE; |
| 2653 | } |
| 2654 | if (render_set_value(sink_priv->render_device_handle, KEY_VIDEO_FORMAT, &format) == -1) |
| 2655 | { |
| 2656 | GST_ERROR_OBJECT(vsink, "tunnel lib: set video format error"); |
| 2657 | return FALSE; |
| 2658 | } |
xuesong.jiang | 32d7828 | 2021-11-18 19:24:15 +0800 | [diff] [blame] | 2659 | |
xuesong.jiang | 50a0f93 | 2021-11-15 15:18:51 +0800 | [diff] [blame] | 2660 | return TRUE; |
xuesong.jiang | b4c09b5 | 2021-10-26 20:18:35 +0800 | [diff] [blame] | 2661 | } |
| 2662 | |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2663 | static gpointer detection_thread(gpointer data) |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 2664 | { |
| 2665 | GstAmlVideoSink *sink = (GstAmlVideoSink *)data; |
| 2666 | GstAmlVideoSinkPrivate *sink_priv = GST_AML_VIDEO_SINK_GET_PRIVATE(sink); |
| 2667 | int eosCountDown; |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 2668 | double frameRate = (sink->frame_rate > 0.0 ? sink->frame_rate : 30.0); |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2669 | GST_DEBUG("detection_thread: enter"); |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 2670 | |
| 2671 | eosCountDown = 2; |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 2672 | while (!sink->quit_eos_detect_thread ) |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 2673 | { |
fei.deng | 68c6334 | 2023-12-05 07:37:33 +0000 | [diff] [blame] | 2674 | usleep(1000000/frameRate); |
| 2675 | if (sink->video_playing && sink_priv->emitUnderflowSignal) { |
| 2676 | sink_priv->emitUnderflowSignal = FALSE; |
| 2677 | g_signal_emit (G_OBJECT (sink), g_signals[SIGNAL_UNDERFLOW], 0, 0, NULL); |
| 2678 | } |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2679 | g_mutex_lock(&sink->report_info_lock); |
| 2680 | if (sink->video_playing && (sink_priv->reportInfos != NULL)) { |
| 2681 | GList *l; |
| 2682 | for (l = sink_priv->reportInfos; l != NULL; l = l->next) { |
| 2683 | ReportInfo *report_info = l->data; |
| 2684 | if (report_info->msg == MSG_FRAME_FREEZE) |
| 2685 | { |
| 2686 | g_signal_emit (G_OBJECT (sink), g_signals[SIGNAL_FRAMEFREEZE], 0, report_info->info.pts, report_info->info.duration, NULL); |
| 2687 | } |
| 2688 | else if (report_info->msg == MSG_AV_RESYNC) |
| 2689 | { |
| 2690 | g_signal_emit (G_OBJECT (sink), g_signals[SIGNAL_RESYNC], 0, report_info->info.pts, report_info->info.duration, NULL); |
| 2691 | } |
| 2692 | else if (report_info->msg == MSG_DROPED_BUFFER) |
| 2693 | { |
| 2694 | g_signal_emit (G_OBJECT (sink), g_signals[SIGNAL_FRAMEDROP], 0, report_info->info.pts, NULL); |
| 2695 | } |
| 2696 | GST_DEBUG("emit FREEZE/RESYNC/DROP signal:%d, pts:%lld, duration:%lld", report_info->msg, report_info->info.pts, report_info->info.duration); |
| 2697 | g_free(report_info); |
| 2698 | } |
| 2699 | g_list_free(sink_priv->reportInfos); |
| 2700 | sink_priv->reportInfos = NULL; |
| 2701 | } |
| 2702 | g_mutex_unlock(&sink->report_info_lock); |
fei.deng | 2f46214 | 2023-05-24 03:07:29 +0000 | [diff] [blame] | 2703 | if (sink->video_playing && sink_priv->got_eos) |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 2704 | { |
fei.deng | 053f407 | 2024-11-20 19:05:43 +0800 | [diff] [blame] | 2705 | if (sink->queued <= sink->rendered + sink->dropped) |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 2706 | { |
| 2707 | --eosCountDown; |
| 2708 | if ( eosCountDown == 0 ) |
| 2709 | { |
| 2710 | GST_DEBUG("EOS detected"); |
| 2711 | GstBaseSink *bs; |
| 2712 | bs= GST_BASE_SINK(sink); |
| 2713 | GST_BASE_SINK_PREROLL_LOCK(bs); |
| 2714 | GST_DEBUG("EOS: need_preroll %d have_preroll %d", bs->need_preroll, bs->have_preroll); |
Le Han | 5534b5a | 2024-07-25 02:35:18 -0700 | [diff] [blame] | 2715 | if ( bs->need_preroll ) |
| 2716 | { |
| 2717 | GstState cur, nxt, pend; |
| 2718 | /* complete preroll and commit state */ |
| 2719 | GST_DEBUG("EOS signal preroll\n"); |
| 2720 | bs->need_preroll= FALSE; |
| 2721 | bs->have_preroll= TRUE; |
| 2722 | GST_OBJECT_LOCK(bs); |
| 2723 | cur= GST_STATE(bs); |
| 2724 | nxt= GST_STATE_NEXT(bs); |
| 2725 | GST_STATE(bs)= pend= GST_STATE_PENDING(bs); |
| 2726 | GST_STATE_NEXT(bs)= GST_STATE_PENDING(bs)= GST_STATE_VOID_PENDING; |
| 2727 | GST_STATE_RETURN(bs)= GST_STATE_CHANGE_SUCCESS; |
| 2728 | GST_OBJECT_UNLOCK(bs); |
| 2729 | GST_DEBUG("EOS posting state change: curr(%s) next(%s) pending(%s)", |
| 2730 | gst_element_state_get_name(cur), |
| 2731 | gst_element_state_get_name(nxt), |
| 2732 | gst_element_state_get_name(pend)); |
| 2733 | gst_element_post_message(GST_ELEMENT_CAST(bs), gst_message_new_state_changed(GST_OBJECT_CAST(bs), cur, nxt, pend)); |
| 2734 | GST_DEBUG("EOS posting async done"); |
| 2735 | gst_element_post_message(GST_ELEMENT_CAST(bs), gst_message_new_async_done(GST_OBJECT_CAST(bs), GST_CLOCK_TIME_NONE)); |
| 2736 | GST_STATE_BROADCAST(bs) |
| 2737 | } |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 2738 | GST_BASE_SINK_PREROLL_UNLOCK(bs); |
| 2739 | GST_DEBUG("EOS: calling eos detected: need_preroll %d have_preroll %d", bs->need_preroll, bs->have_preroll); |
| 2740 | gst_element_post_message (GST_ELEMENT_CAST(sink), gst_message_new_eos(GST_OBJECT_CAST(sink))); |
| 2741 | GST_DEBUG("EOS: done calling eos detected,posted eos msg, need_preroll %d have_preroll %d", bs->need_preroll, bs->have_preroll); |
| 2742 | break; |
| 2743 | } |
| 2744 | } |
| 2745 | else |
| 2746 | { |
| 2747 | eosCountDown = 2; |
| 2748 | } |
| 2749 | } |
| 2750 | } |
| 2751 | |
fei.deng | bcd880e | 2023-06-19 02:19:26 +0000 | [diff] [blame] | 2752 | if (!sink->quit_eos_detect_thread) |
| 2753 | { |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2754 | g_thread_unref( sink->detect_thread_handle ); |
| 2755 | sink->detect_thread_handle= NULL; |
fei.deng | bcd880e | 2023-06-19 02:19:26 +0000 | [diff] [blame] | 2756 | } |
le.han | 7bb29b6 | 2024-08-07 03:17:09 +0000 | [diff] [blame] | 2757 | GST_DEBUG("detection_thread: exit"); |
fei.deng | 10e3d50 | 2023-05-10 06:52:46 +0000 | [diff] [blame] | 2758 | return NULL; |
| 2759 | } |
| 2760 | |
fei.deng | ab16ff1 | 2024-08-07 17:58:07 +0800 | [diff] [blame] | 2761 | #if 0 |
xuesong.jiang | 5d2761f | 2022-05-05 11:43:21 +0800 | [diff] [blame] | 2762 | static void gst_aml_video_sink_dump_stat(GstAmlVideoSink *sink, const gchar *file_name) |
| 2763 | { |
| 2764 | const gchar *dump_dir = NULL; |
| 2765 | gchar *full_file_name = NULL; |
| 2766 | FILE *out = NULL; |
| 2767 | |
| 2768 | dump_dir = g_getenv("GST_DEBUG_DUMP_AMLVIDEOSINK_STAT_DIR"); |
| 2769 | if (G_LIKELY(dump_dir == NULL)) |
| 2770 | return; |
| 2771 | |
| 2772 | if (!file_name) |
| 2773 | { |
| 2774 | file_name = "unnamed"; |
| 2775 | } |
| 2776 | |
| 2777 | full_file_name = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.stat", dump_dir, file_name); |
| 2778 | |
| 2779 | if ((out = fopen(full_file_name, "w"))) |
| 2780 | { |
| 2781 | gchar *stat_info; |
fei.deng | 6fdfab7 | 2024-08-05 16:54:58 +0800 | [diff] [blame] | 2782 | stat_info = g_strdup_printf("Stat:%d | Q:%d, Dq:%d, Render:%d, Drop:%d\n", GST_STATE(sink), sink->queued, sink->dequeued, sink->rendered, sink->dropped); |
xuesong.jiang | 5d2761f | 2022-05-05 11:43:21 +0800 | [diff] [blame] | 2783 | fputs(stat_info, out); |
| 2784 | g_free(stat_info); |
| 2785 | fclose(out); |
| 2786 | GST_INFO("wrote amlvideosink stat to : '%s' succ", full_file_name); |
| 2787 | } |
| 2788 | else |
| 2789 | { |
| 2790 | GST_WARNING("Failed to open file '%s' for writing: %s", full_file_name, g_strerror(errno)); |
| 2791 | } |
| 2792 | g_free(full_file_name); |
| 2793 | } |
fei.deng | ab16ff1 | 2024-08-07 17:58:07 +0800 | [diff] [blame] | 2794 | #endif |
xuesong.jiang | 5d2761f | 2022-05-05 11:43:21 +0800 | [diff] [blame] | 2795 | |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 2796 | /* plugin init */ |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2797 | static gboolean plugin_init(GstPlugin *plugin) |
| 2798 | { |
xuesong.jiang | 1700bab | 2021-11-17 17:11:11 +0800 | [diff] [blame] | 2799 | GST_DEBUG_CATEGORY_INIT(gst_aml_video_sink_debug, "amlvideosink", 0, |
| 2800 | " aml video sink"); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 2801 | |
xuesong.jiang | f0ebebe | 2021-12-24 09:41:15 +0800 | [diff] [blame] | 2802 | gint rank = 1; |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 2803 | const char *rank_env = getenv("GST_AML_VIDEO_SINK_RANK"); |
| 2804 | if (rank_env) |
| 2805 | { |
| 2806 | rank = atoi(rank_env); |
| 2807 | } |
xuesong.jiang | f0ebebe | 2021-12-24 09:41:15 +0800 | [diff] [blame] | 2808 | |
| 2809 | return gst_element_register(plugin, "amlvideosink", rank, |
xuesong.jiang | d91230d | 2021-10-20 15:51:10 +0800 | [diff] [blame] | 2810 | GST_TYPE_AML_VIDEO_SINK); |
xuesong.jiang | 1801e17 | 2021-10-11 10:56:41 +0800 | [diff] [blame] | 2811 | } |
| 2812 | |
xuesong.jiang | 5c0d1b8 | 2021-11-16 19:30:56 +0800 | [diff] [blame] | 2813 | #ifndef VERSION |
| 2814 | #define VERSION "0.1.0" |
| 2815 | #endif |
| 2816 | #ifndef PACKAGE |
| 2817 | #define PACKAGE "aml_package" |
| 2818 | #endif |
| 2819 | #ifndef PACKAGE_NAME |
| 2820 | #define PACKAGE_NAME "aml_media" |
| 2821 | #endif |
| 2822 | #ifndef GST_PACKAGE_ORIGIN |
| 2823 | #define GST_PACKAGE_ORIGIN "http://amlogic.com" |
| 2824 | #endif |
| 2825 | // GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, amlvideosink, |
| 2826 | // "aml Video Sink", plugin_init, VERSION, "LGPL", |
| 2827 | // "gst-plugin-video-sink", "") |
xuesong.jiang | 7ec9f8f | 2022-03-14 15:03:04 +0800 | [diff] [blame] | 2828 | GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, |
| 2829 | GST_VERSION_MINOR, |
| 2830 | amlvideosink, |
| 2831 | "Amlogic plugin for video decoding/rendering", |
| 2832 | plugin_init, VERSION, "LGPL", PACKAGE_NAME, GST_PACKAGE_ORIGIN) |