@@ -29,9 +29,12 @@ AllwinnerV4L2Display::AllwinnerV4L2Display(int udp_port,
2929 uint32_t mode_vrefresh)
3030 : m_port(udp_port),
3131 m_h265(h265),
32- m_mode_width(mode_width ? mode_width : 1280 ),
33- m_mode_height(mode_height ? mode_height : 720 ),
34- m_mode_vrefresh(mode_vrefresh ? mode_vrefresh : 60 ) {
32+ m_stream_width(mode_width ? mode_width : 1280 ),
33+ m_stream_height(mode_height ? mode_height : 720 ),
34+ m_stream_vrefresh(mode_vrefresh ? mode_vrefresh : 60 ),
35+ m_display_width(mode_width),
36+ m_display_height(mode_height),
37+ m_display_vrefresh(mode_vrefresh) {
3538 if (m_port < 0 ) {
3639 m_input_mode = InputMode::StdIn;
3740 m_input_fd = STDIN_FILENO;
@@ -68,6 +71,7 @@ bool AllwinnerV4L2Display::start() {
6871 stop ();
6972 return false ;
7073 }
74+ m_modeset_initialized = false ;
7175 m_running = true ;
7276 m_thread = std::thread (&AllwinnerV4L2Display::decode_loop, this );
7377 return true ;
@@ -79,6 +83,7 @@ void AllwinnerV4L2Display::stop() {
7983 if (m_thread.joinable ())
8084 m_thread.join ();
8185 }
86+ m_modeset_initialized = false ;
8287
8388 if (m_sock >= 0 && m_input_mode == InputMode::UDP) {
8489 close (m_sock);
@@ -94,6 +99,10 @@ void AllwinnerV4L2Display::stop() {
9499 }
95100 if (m_drm_fd >= 0 ) {
96101 if (m_drm_prepared) {
102+ if (m_output.video_request ) {
103+ drmModeAtomicFree (m_output.video_request );
104+ m_output.video_request = nullptr ;
105+ }
97106 modeset_cleanup (m_drm_fd, &m_output);
98107 m_drm_prepared = false ;
99108 }
@@ -138,9 +147,9 @@ bool AllwinnerV4L2Display::setup_drm() {
138147 }
139148 if (modeset_prepare (m_drm_fd,
140149 &m_output,
141- m_mode_width ,
142- m_mode_height ,
143- m_mode_vrefresh ,
150+ m_display_width ,
151+ m_display_height ,
152+ m_display_vrefresh ,
144153 DRM_FORMAT_NV12,
145154 MODESET_PLANE_TYPE_PRIMARY) < 0 ) {
146155 return false ;
@@ -159,8 +168,8 @@ bool AllwinnerV4L2Display::setup_v4l2() {
159168 struct v4l2_format fmt;
160169 memset (&fmt, 0 , sizeof (fmt));
161170 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
162- fmt.fmt .pix_mp .width = m_mode_width ;
163- fmt.fmt .pix_mp .height = m_mode_height ;
171+ fmt.fmt .pix_mp .width = m_stream_width ;
172+ fmt.fmt .pix_mp .height = m_stream_height ;
164173 fmt.fmt .pix_mp .pixelformat =
165174 m_h265 ? V4L2_PIX_FMT_HEVC_SLICE : V4L2_PIX_FMT_H264_SLICE;
166175 fmt.fmt .pix_mp .num_planes = 1 ;
@@ -171,14 +180,16 @@ bool AllwinnerV4L2Display::setup_v4l2() {
171180
172181 memset (&fmt, 0 , sizeof (fmt));
173182 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
174- fmt.fmt .pix_mp .width = m_mode_width ;
175- fmt.fmt .pix_mp .height = m_mode_height ;
183+ fmt.fmt .pix_mp .width = m_stream_width ;
184+ fmt.fmt .pix_mp .height = m_stream_height ;
176185 fmt.fmt .pix_mp .pixelformat = V4L2_PIX_FMT_NV12M;
177186 fmt.fmt .pix_mp .num_planes = 2 ;
178187 if (ioctl (m_v4l2_fd, VIDIOC_S_FMT, &fmt) < 0 ) {
179188 perror (" S_FMT capture" );
180189 return false ;
181190 }
191+ m_stream_width = fmt.fmt .pix_mp .width ;
192+ m_stream_height = fmt.fmt .pix_mp .height ;
182193
183194 struct v4l2_requestbuffers req;
184195 memset (&req, 0 , sizeof (req));
@@ -267,7 +278,7 @@ bool AllwinnerV4L2Display::setup_v4l2() {
267278 fmt.fmt .pix_mp .plane_fmt [1 ].bytesperline , 0 , 0 };
268279 uint32_t offsets[4 ] = {planes[0 ].data_offset , planes[1 ].data_offset , 0 , 0 };
269280 uint32_t fb_id = 0 ;
270- if (drmModeAddFB2 (m_drm_fd, m_mode_width, m_mode_height , DRM_FORMAT_NV12,
281+ if (drmModeAddFB2 (m_drm_fd, m_stream_width, m_stream_height , DRM_FORMAT_NV12,
271282 handles, pitches, offsets, &fb_id, 0 ) != 0 ) {
272283 perror (" AddFB2" );
273284 close (prime_fd);
@@ -343,7 +354,26 @@ void AllwinnerV4L2Display::decode_loop() {
343354 cbuf.m .planes = cplanes;
344355 if (ioctl (m_v4l2_fd, VIDIOC_DQBUF, &cbuf) == 0 ) {
345356 int fb_id = m_capture_fbs[cbuf.index ];
346- extra_modeset_set_fb (m_drm_fd, &m_output, &m_output.video_plane , fb_id);
357+ bool submit_via_set_fb = true ;
358+ if (!m_modeset_initialized && m_output.video_request ) {
359+ int ret = modeset_perform_modeset (m_drm_fd,
360+ &m_output,
361+ m_output.video_request ,
362+ &m_output.video_plane ,
363+ fb_id,
364+ static_cast <int >(m_stream_width),
365+ static_cast <int >(m_stream_height),
366+ 0 );
367+ if (ret == 0 ) {
368+ m_modeset_initialized = true ;
369+ submit_via_set_fb = false ;
370+ } else {
371+ std::cerr << " Failed to perform initial modeset for Cedar display path." << std::endl;
372+ }
373+ }
374+ if (submit_via_set_fb) {
375+ extra_modeset_set_fb (m_drm_fd, &m_output, &m_output.video_plane , fb_id);
376+ }
347377 ioctl (m_v4l2_fd, VIDIOC_QBUF, &cbuf);
348378 }
349379
0 commit comments