bcm2835-codec: SOURCE_CHANGE queued after last_buffer_dequeued, decoder stops without error

Ouverte
#7,674 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
32/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
c

Piste de recherche

Start from handle_fmt_changed() in the bcm2835-codec driver: it sets vq->last_buffer_dequeued before queue_res_chg_event(), so a v4l2_m2m_poll landing between the two writes reports EPOLLIN without EPOLLPRI and the decoder exits via GST_V4L2_FLOW_LAST_BUFFER. The proposed fix reorders the event before the flag and adds wake_up(&vq->done_wq); validate it against v4l2_m2m_poll and gst_v4l2_object_poll. Done means no silent stop across many looped starts on bcm2835 hardware with debug=1. Note the reporter is already testing this and will open a PR, so coordinate before starting.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Pi 4 Model B Rev 1.5 4 GB, kernel 6.18.39-v8 (raspberrypi/linux 8307cc8d), GStreamer 1.26.11, playbin3 → v4l2h264dec → glimagesink under sway. H.264 High 4.1 1920x1080 25 fps + AAC, MP4 over HTTPS.

Our player loops a fixed playlist: the same images and the same two MP4 files, hundreds of times a day. At each start of the H.264 decoder, the firmware reports Format changed to 1920x1088 with an unchanged format (Format was 1920x1088). Most starts play fine. 1 start in 40 to 300 stops and never resumes: no bus error, the pipeline never prerolls, the screen stays on the last frame until a restart. The file and the firmware event stay the same, so we looked for a timing race. We see the freeze on 6 display units and reproduce it on a test unit with a different screen.

Sequence (bcm2835_codec debug=1, GST_DEBUG v4l2*:5):

  • capture STREAMON (bcm2835_codec_start_streaming: type: 9)
  • 18 to 28 ms later, handle_fmt_changed: Format changed to 1920x1088 and, in the same ms, gst_v4l2_video_dec_loop: Leaving output thread: custom-success
  • no Sending EOS event; the decoder loop never dequeues the SOURCE_CHANGE event
  • on one more start, a flush dequeued the event 1 s later and playback recovered: 2 hits in 86 starts

Cause

  • handle_fmt_changed() sets vq->last_buffer_dequeued = true, then calls queue_res_chg_event().
  • v4l2_m2m_poll reports EPOLLIN from the flag under done_lock, and EPOLLPRI from the event under fh_lock. A poll between the two writes returns EPOLLIN without EPOLLPRI.
  • gst_v4l2_object_poll checks POLLPRI first. Without it, the pool calls DQBUF, gets EPIPE and returns GST_V4L2_FLOW_LAST_BUFFER. v4l2videodec then leaves its output thread and posts no error.
  • During start-up, each returned input buffer wakes the capture poller, every millisecond or so, which keeps the window busy.

Proposed fix: queue the event first, then set the flag and wake the capture queue pollers.

+	/* A poll that sees the LAST state must also see the event */
+	queue_res_chg_event(ctx);
+
 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
-	if (vq->streaming)
+	if (vq->streaming) {
 		vq->last_buffer_dequeued = true;
-
-	queue_res_chg_event(ctx);
+		wake_up(&vq->done_wq);
+	}

We're testing it now and will open a PR once it holds.

Related: #5059 shows the same start-up Format changed with an unchanged format. It's the same trigger and a different bug; neither fix covers the other.

Langage dominant
C
Étoiles
13.3k
Forks
5.5k
Merge moyen
1 j 9 h
PR mergées (30 j)
17

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de raspberrypi/linux

Toutes les issues de raspberrypi/linux

Issues similaires

Plus d'issues C

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.