[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