[Ffmpeg-devel] /dev/fb video out hook

Marc Hoffman mmh
Mon Mar 26 03:57:54 CEST 2007


If anyone is interested here is a nice video hook function I have been
using.  I guess if there is interest I can can clean the API so that
an argument can be passed to select how to present pixels to the video
output device via libswscale.

If this is a repost sorry, I just upgraded my emailer to
fetchmail+emacs kind of like back to the future for me.


===File ~/ffmpeg/ffmpeg-svn/vhook/voutfb.c==================
/*
 * Video Out /dev/fb Video Hook
 * Copyright (c) 2007 Marc Hoffman
 *
 * This video hook provides a useful video encode preview function for
 * embeded devices which have dev/fb support.
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
#include <stdio.h>
#include <sys/types.h>
#include <linux/fb.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <bits/bfin_sram.h>

#include "framehook.h"
#include "swscale.h"

static int sws_flags = SWS_BICUBIC;

typedef struct {
  int dummy;

  // This vhook first converts frame to RGB ...
  struct SwsContext *toRGB_convert_ctx;

  int devfb;
  int sz;
  unsigned char *screen_ptr;
  AVPicture *dpy;

} ContextInfo;

void Release(void *ctx)
{
    ContextInfo *ci;
    ci = (ContextInfo *) ctx;

    if (ctx) {
      munmap (ci->screen_ptr, ci->sz);
      close (ci->devfb);
      av_free (ci->dpy);
      if (ci->toRGB_convert_ctx)
	sws_freeContext(ci->toRGB_convert_ctx);
      av_free(ctx);
    }
}

static 
AVPicture *oscreen (ContextInfo *ci)
{
  AVPicture *dpy;
  char * device = "/dev/fb0";
  struct fb_var_screeninfo screeninfo;
  int screen_fd;
  unsigned char * screen_ptr;
  int screen_width;
  int screen_height;
  int bits_per_pixel;
  int sz;
  screen_fd = open(device, O_RDWR);
  
  if (screen_fd == -1) {
    perror("Unable to open frame buffer device /dev/fb0");
    exit(0);
  }
  
  if (ioctl(screen_fd, FBIOGET_VSCREENINFO, &screeninfo)==-1) {
    perror("Unable to retrieve framebuffer information");
    exit(0);
  }
  screen_width = screeninfo.xres_virtual;
  screen_height = screeninfo.yres_virtual;
  bits_per_pixel = screeninfo.bits_per_pixel;
  
  //  printf ("w:%d h:%d bits:%d\n", screen_width, screen_height, bits_per_pixel);
  sz = screen_height * screen_width * (bits_per_pixel/ 8);
  screen_ptr = mmap(0, sz, 
		    PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, screen_fd, 0);
  
  if (screen_ptr==MAP_FAILED) {
    perror("Unable to mmap frame buffer\n");
  }

  //  memset (screen_ptr, 0, screen_width*screen_height*bits_per_pixel/2);
  dpy = av_mallocz (sizeof(AVPicture));
  dpy->data[0]     = screen_ptr;
  dpy->linesize[0] = screen_width*2;
  ci->sz = sz;
  ci->screen_ptr = screen_ptr;
  ci->devfb = screen_fd;
  ci->screen_ptr = screen_ptr;

  return dpy;
}

int Configure(void **ctxp, int argc, char *argv[])
{
    ContextInfo *ci;
    
    *ctxp = av_mallocz(sizeof(ContextInfo));
    ci = (ContextInfo *) *ctxp;
    ci->dpy = oscreen(ci);
    return 0;
}

void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width, int height, int64_t pts)
{
    ContextInfo *ci = (ContextInfo *) ctx;
    AVPicture *dpy = ci->dpy;

    if (ci->toRGB_convert_ctx == 0)
      ci->toRGB_convert_ctx = sws_getCachedContext(ci->toRGB_convert_ctx,
						   width, height, pix_fmt,
						   width, height, PIX_FMT_RGB565,
						   sws_flags, NULL, NULL, NULL);
    

    if (ci->toRGB_convert_ctx == NULL) {
      av_log(NULL, AV_LOG_ERROR,
	     "Cannot initialize the toRGB conversion context\n");
      exit(1);
    }

    sws_scale(ci->toRGB_convert_ctx,
	      picture->data, picture->linesize, 0, height,
	      dpy->data, dpy->linesize);

}

============================================================




More information about the ffmpeg-devel mailing list