From: Nicolas Dufresne <nicolas@ndufresne.ca>
To: Hans Verkuil <hverkuil@xs4all.nl>,
Dave Stevenson <dave.stevenson@raspberrypi.org>
Cc: Stefan Wahren <wahrenst@gmx.net>, Eric Anholt <eric@anholt.net>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
"moderated list:BROADCOM BCM2835 ARM ARCHITECTURE"
<linux-rpi-kernel@lists.infradead.org>,
linux-arm-kernel@lists.infradead.org, devel@driverdev.osuosl.org,
LMML <linux-media@vger.kernel.org>
Subject: Re: [PATCH 01/31] staging: bcm2835-camera: Ensure H264 header bytes get a sensible timestamp
Date: Fri, 28 Jun 2019 10:35:33 -0400 [thread overview]
Message-ID: <a26691644df987aa93523be388646f89d9f468da.camel@ndufresne.ca> (raw)
In-Reply-To: <df6c4e8e-9182-f629-2bd7-a36b5697f382@xs4all.nl>
[-- Attachment #1: Type: text/plain, Size: 9564 bytes --]
Le vendredi 28 juin 2019 à 16:08 +0200, Hans Verkuil a écrit :
> On 6/28/19 4:00 PM, Nicolas Dufresne wrote:
> > Le vendredi 28 juin 2019 à 11:10 +0100, Dave Stevenson a écrit :
> > > Hi Nicolas
> > >
> > > On Thu, 27 Jun 2019 at 20:55, Nicolas Dufresne <nicolas@ndufresne.ca> wrote:
> > > > Hi Dave,
> > > >
> > > > Le jeudi 27 juin 2019 à 20:55 +0200, Stefan Wahren a écrit :
> > > > > From: Dave Stevenson <dave.stevenson@raspberrypi.org>
> > > > >
> > > > > H264 header come from VC with 0 timestamps, which means they get a
> > > > > strange timestamp when processed with VC/kernel start times,
> > > > > particularly if used with the inline header option.
> > > > > Remember the last frame timestamp and use that if set, or otherwise
> > > > > use the kernel start time.
> > > >
> > > > Normally H264 headers are considered to be part of the following frame.
> > > > Giving it the timestamp of the previous frame will likely confuse some
> > > > userspace and cause an off-by-one in timestamp. I understand this is a
> > > > workaround, but am wondering if this can be improved.
> > >
> > > Sorry, slight ambiguity in how I'm reading your comment.
> > >
> > > Are you saying that the header bytes want to be in the same buffer as
> > > the following frame?
> > > I thought this had also been discussed in the V4L2 stateful codec API
> > > threads along with how many encoded frames were allowed in a single
> > > V4L2 buffer. I certainly hadn't seen a statement about the header
> > > bytes being combined with the next frame.
> > > If the behaviour required by V4L2 is that header bytes and following
> > > frame are in the same buffer, then that is relatively easy to achieve
> > > in the firmware. This workaround can remain for older firmware as it
> > > will never trigger if the firmware has combined the frames.
> >
> > The frame alignment is a requirement specific to the stateful codec
> > API.
>
> Is it? I don't remember it being specified anywhere explicitly.
> Here is the latest text:
>
> https://hverkuil.home.xs4all.nl/codec-api/uapi/v4l/dev-encoder.html
>
> I'll start a new thread about this, since this really needs to be
> clarified.
Ok, let's clarify this, but before we start, a quick reminder that this
is what userspace assumes already, so breaking this will cause
regressions all over.
>
> Regards,
>
> Hans
>
> Stateful codec must interpret _H264 format as being one full frame
> > per buffer (1 AU in progressive, and 1 to 2 AU in interlaced), the
> > first frame should include SPS/PPS and any other prefix NALs. You may
> > follow this rule in your capture driver if you want to make it possible
> > to zero-copy the encoded frames from the capture to the decoder.
> > Though, userspace will still have to parse as there is no indication
> > for capture devices of the H264 alignment being used (that imply 1
> > frame latency). Boris is working on a control for stateless CODEC to
> > control if we are running in full-frame or per slices. I do hope this
> > control will be extended later to allow cameras and decoders to signal
> > their alignment, or simply to allow enabling low-latency modes
> > supported by CODA and ZynMP firmwares.
> >
> > > Or are you saying that the header bytes remain in their own buffer,
> > > but the timestamp wants to be the same as the next frame? That is
> > > harder to achieve in the firmware, but could probably be done in the
> > > kernel driver by holding on to the header bytes frame until the next
> > > buffer had been received, at which point the timestamp can be copied
> > > across. Possible, but just needs slightly careful handling to ensure
> > > we don't lose buffers accidentally.
> >
> > So this isn't specified by V4L2 itself. So instead I rely on H264 and
> > MPEG TS specification to advance this. This is also the interpretation
> > we have of timestamp in GStreamer (ffmpeg uses out-of-band headers with
> > full frame AVC, so this does not apply).
> >
> > So H264 AUD, SPS, PPS, SEI and other prefix NAL are considered to be
> > the start of a frame. With this interpretation in mind, accumulating
> > them is considered zero-latency. This basically means that if they are
> > to have a timestamp, they would share that timestamp with all the
> > slices of the same frame. In GStreamer, we have the notion of no
> > timestamp, so in such a case we'd leave the timestamp empty and our
> > parsers would pick the first valid timestamp that formed the full frame
> > as being the frame timestamp (it's a bit buggier then that, but that's
> > what it's suppose to do).
> >
> > On top of that, if you don't have any meaningful alignment in your H264
> > stream, the MPEG TS format states that the timestamp of a buffer should
> > be the timestamp of the first NAL starting within this buffer, or the
> > timestamp of the current NAL if there is not NAL start.
> >
> > By respecting these standards you ensure that latency aware application
> > can work with your driver without causing delays, or worst, having to
> > deal with artificially late frames.
> >
> > I hope this clarify and helps understand my request for "unhacking" the
> > headers timestamps. I had assumed the timestamp came from the driver
> > (instead of from the firmware), sorry if that caused confusion. If
> > merging full frames is easier, I think I would opt for that as it's
> > beneficial to performance when combined with other full frame APIs.
> >
> > Nicolas
> >
> > > Dave
> > >
> > > > > Link: https://github.com/raspberrypi/linux/issues/1836
> > > > > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
> > > > > ---
> > > > > .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 14 ++++++++++++--
> > > > > .../staging/vc04_services/bcm2835-camera/bcm2835-camera.h | 2 ++
> > > > > 2 files changed, 14 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> > > > > index dce6e6d..0c04815 100644
> > > > > --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> > > > > +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> > > > > @@ -359,7 +359,9 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
> > > > > }
> > > > > } else {
> > > > > if (dev->capture.frame_count) {
> > > > > - if (dev->capture.vc_start_timestamp != -1 && pts) {
> > > > > + if (dev->capture.vc_start_timestamp != -1) {
> > > > > + buf->vb.vb2_buf.timestamp = ktime_get_ns();
> > > > > + } else if (pts) {
> > > > > ktime_t timestamp;
> > > > > s64 runtime_us = pts -
> > > > > dev->capture.vc_start_timestamp;
> > > > > @@ -372,8 +374,15 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
> > > > > ktime_to_ns(timestamp));
> > > > > buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp);
> > > > > } else {
> > > > > - buf->vb.vb2_buf.timestamp = ktime_get_ns();
> > > > > + if (dev->capture.last_timestamp) {
> > > > > + buf->vb.vb2_buf.timestamp =
> > > > > + dev->capture.last_timestamp;
> > > > > + } else {
> > > > > + buf->vb.vb2_buf.timestamp =
> > > > > + ktime_to_ns(dev->capture.kernel_start_ts);
> > > > > + }
> > > > > }
> > > > > + dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp;
> > > > >
> > > > > vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length);
> > > > > vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
> > > > > @@ -541,6 +550,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
> > > > > dev->capture.vc_start_timestamp, parameter_size);
> > > > >
> > > > > dev->capture.kernel_start_ts = ktime_get();
> > > > > + dev->capture.last_timestamp = 0;
> > > > >
> > > > > /* enable the camera port */
> > > > > dev->capture.port->cb_ctx = dev;
> > > > > diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
> > > > > index 2b5679e..09273b0 100644
> > > > > --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
> > > > > +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
> > > > > @@ -90,6 +90,8 @@ struct bm2835_mmal_dev {
> > > > > s64 vc_start_timestamp;
> > > > > /* Kernel start timestamp for streaming */
> > > > > ktime_t kernel_start_ts;
> > > > > + /* Timestamp of last frame */
> > > > > + u64 last_timestamp;
> > > > >
> > > > > struct vchiq_mmal_port *port; /* port being used for capture */
> > > > > /* camera port being used for capture */
> > > > > --
> > > > > 2.7.4
> > > > >
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
next prev parent reply other threads:[~2019-06-28 14:35 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-27 18:55 [PATCH 00/31] staging: bcm2835-camera: Improvements Stefan Wahren
2019-06-27 18:55 ` [PATCH 01/31] staging: bcm2835-camera: Ensure H264 header bytes get a sensible timestamp Stefan Wahren
2019-06-27 19:55 ` Nicolas Dufresne
2019-06-28 10:10 ` Dave Stevenson
2019-06-28 14:00 ` Nicolas Dufresne
2019-06-28 14:08 ` Hans Verkuil
2019-06-28 14:35 ` Nicolas Dufresne [this message]
2019-06-28 7:28 ` Dan Carpenter
2019-06-27 18:55 ` [PATCH 02/31] staging: bcm2835-camera: Check the error for REPEAT_SEQ_HEADER Stefan Wahren
2019-06-27 18:56 ` [PATCH 03/31] staging: bcm2835-camera: Replace spinlock protecting context_map with mutex Stefan Wahren
2019-06-27 18:56 ` [PATCH 04/31] staging: bcm2835-camera: Do not bulk receive from service thread Stefan Wahren
2019-06-27 18:56 ` [PATCH 05/31] staging: bcm2835-camera: Correctly denote key frames in encoded data Stefan Wahren
2019-06-27 18:56 ` [PATCH 06/31] staging: bcm2835-camera: Return early on errors Stefan Wahren
2019-06-28 7:38 ` Dan Carpenter
2019-06-27 18:56 ` [PATCH 07/31] staging: bcm2835-camera: Remove dead email addresses Stefan Wahren
2019-06-27 18:56 ` [PATCH 08/31] staging: bcm2835-camera: Fix comment style violations Stefan Wahren
2019-06-27 18:56 ` [PATCH 09/31] staging: bcm2835-camera: Fix spacing around operators Stefan Wahren
2019-06-27 18:56 ` [PATCH 10/31] staging: bcm2835-camera: Reduce length of enum names Stefan Wahren
2019-06-27 18:56 ` [PATCH 11/31] staging: bcm2835-camera: Fix multiple line dereference errors Stefan Wahren
2019-06-27 18:56 ` [PATCH 12/31] staging: bcm2835-camera: Fix brace style issues Stefan Wahren
2019-06-27 18:56 ` [PATCH 13/31] staging: bcm2835-camera: Fix missing lines between items Stefan Wahren
2019-06-27 18:56 ` [PATCH 14/31] staging: bcm2835-camera: Fix open parenthesis alignment Stefan Wahren
2019-06-27 18:56 ` [PATCH 15/31] staging: bcm2835-camera: Ensure all buffers are returned on disable Stefan Wahren
2019-06-27 18:56 ` [PATCH 16/31] staging: bcm2835-camera: Remove check of the number of buffers supplied Stefan Wahren
2019-06-27 18:56 ` [PATCH 17/31] staging: bcm2835-camera: Handle empty EOS buffers whilst streaming Stefan Wahren
2019-06-27 18:56 ` [PATCH 18/31] staging: bcm2835-camera: Set sequence number correctly Stefan Wahren
2019-06-27 18:56 ` [PATCH 19/31] staging: bcm2835-camera: Ensure timestamps never go backwards Stefan Wahren
2019-06-27 20:01 ` Nicolas Dufresne
2019-06-28 8:06 ` [PATCH 00/31] staging: bcm2835-camera: Improvements Hans Verkuil
2019-06-28 10:39 ` Dave Stevenson
2019-06-28 10:56 ` Hans Verkuil
2019-06-28 16:57 ` Stefan Wahren
2019-06-28 17:29 ` Dave Stevenson
2019-06-29 10:27 ` Stefan Wahren
2019-06-28 13:13 ` Hans Verkuil
2019-06-28 13:18 ` Mauro Carvalho Chehab
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a26691644df987aa93523be388646f89d9f468da.camel@ndufresne.ca \
--to=nicolas@ndufresne.ca \
--cc=dave.stevenson@raspberrypi.org \
--cc=devel@driverdev.osuosl.org \
--cc=eric@anholt.net \
--cc=gregkh@linuxfoundation.org \
--cc=hverkuil@xs4all.nl \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-rpi-kernel@lists.infradead.org \
--cc=mchehab@kernel.org \
--cc=wahrenst@gmx.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).