[FFmpeg-devel] Fwd: framebuffer device demuxer
Stefano Sabatini
stefano.sabatini-lala
Thu Feb 10 13:19:53 CET 2011
Updated work in progress.
On date Sunday 2011-01-30 16:36:38 +0000, M?ns Rullg?rd encoded:
> Stefano Sabatini <stefano.sabatini-lala at poste.it> writes:
[...]
> > + if (avctx->flags & AVFMT_FLAG_NONBLOCK)
> > + flags |= O_NONBLOCK;
>
> Come to think of it, O_NONBLOCK doesn't make sense on fbdev. AFAICT
> it is ignored by the drivers.
I suppose you checked the sources. Anyway I suppose it's safe to set
it anyway.
[...]
> > + fb->data = mmap(NULL, fb_fixinfo.line_length * (fb_varinfo.yoffset + fb_varinfo.yres),
> > + PROT_READ, MAP_SHARED, fb->fd, 0);
> > + if (fb->data == MAP_FAILED) {
> > + ret = AVERROR(errno);
> > + av_log(avctx, AV_LOG_ERROR, "Error in mmap(): %s\n", strerror(errno));
> > + goto fail;
> > + }
> > +
> > + fb->visible_data = fb->data +
> > + (fb_varinfo.xoffset + fb_fixinfo.line_length * fb_varinfo.yoffset) * bytes_per_pixel;
>
> You should mmap the entire framebuffer memory (as and query the current
> display offset in read_packet(). Yes, I know you said it wasn't ready.
Done this way.
Data is mapped with:
fbdev->data = mmap(NULL, fbdev->fixinfo.smem_len, PROT_READ, MAP_SHARED, fbdev->fd, 0);
and visible data position updated in read_packet.
I'm supposing the resolution doesn't change while grabbing.
On the other hand I can't really understand the meaning of
fbdev->varinfo.xres_virtual against fixinfo.line_length (fbdev docs
suck and the various implementations I checked are inconsistent).
What I'm doing for computing the visible data:
pin = fbdev->data + fbdev->bytes_per_pixel *
(fbdev->varinfo.xoffset + fbdev->varinfo.yoffset * fbdev->varinfo.xres_virtual);
which is possibly wrong.
[...]
> > +static int linuxfb_read_packet(AVFormatContext *avctx, AVPacket *pkt)
> > +{
> > + FrameBufferContext *fb = avctx->priv_data;
> > + int64_t curtime, delay;
> > + struct timespec ts;
> > + int i, ret;
> > + uint8_t *pin, *pout;
> > +
> > + if (fb->time_frame == AV_NOPTS_VALUE)
> > + fb->time_frame = av_gettime();
> > +
> > + /* wait based on the frame rate */
> > + while (1) {
> > + curtime = av_gettime();
> > + delay = fb->time_frame - curtime;
> > +#ifdef DEBUG
> > + av_log(avctx, AV_LOG_DEBUG,
> > + "time_frame:%"PRId64" curtime:%"PRId64" delay:%"PRId64"\n",
> > + fb->time_frame, curtime, delay);
> > +#endif
>
> av_dlog()
Fixed.
> > + if (delay <= 0) {
> > + fb->time_frame += INT64_C(1000000) * av_q2d(fb->time_base);
> > + break;
> > + }
> > + if (avctx->flags & AVFMT_FLAG_NONBLOCK)
> > + return AVERROR(EAGAIN);
> > + ts.tv_sec = delay / 1000000;
> > + ts.tv_nsec = (delay % 1000000) * 1000;
> > + nanosleep(&ts, NULL);
> > + }
>
> This loop is weird. The correct way is something like this:
>
> ts = delay; /* details omitted */
> while (nanosleep(&ts, &ts) && errno == EINTR);
I kept the same logic for now.
Other minor fixes: name changed again, linuxfb -> fbdev (fbdev is the
official name), some documentation update.
--
FFmpeg = Frenzy and Faithless Moronic Portable Evil Geisha
More information about the ffmpeg-devel
mailing list