Chinaunix首页 | 论坛 | 博客
  • 博客访问: 537128
  • 博文数量: 70
  • 博客积分: 3162
  • 博客等级: 中校
  • 技术积分: 850
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-23 13:30
文章分类
文章存档

2013年(1)

2012年(4)

2011年(1)

2010年(7)

2009年(9)

2008年(20)

2007年(3)

2006年(25)

分类: LINUX

2008-12-04 11:06:42

swfdec使用x11和sdl输出,上次改用framebuffer和oss输出,这样简单,这次来整理下
/*ao_oss.h*/
#ifndef _AO_OSS_H_
#define _AO_OSS_H_
#include
#include
typedef  struct audio_dev_t{
    long samplerate;
    long channels;
    long format;
    int fd;
    char dev_name[16];
}AUDIO_DEV,*PAUDIO_DEV;
int open_audio(PAUDIO_DEV paudio_dev);
int close_audio(PAUDIO_DEV paudio_dev);
#endif
/*ao_oss.c*/
#include
#include
#include
#include
#include
#include
#include "ao_oss.h"
#define PATH_DEV_DSP "/dev/dsp"
int open_audio(PAUDIO_DEV paudio_dev)
{
    int result;
    if ( ( paudio_dev->fd = open ( paudio_dev->dev_name, O_RDWR ) ) < 0 ) {
        fprintf (stderr, " Can't open sound device!\n");
        return -1;
    }
    result = ioctl (paudio_dev->fd, SNDCTL_DSP_SPEED, &(paudio_dev->samplerate));
    if ( result == -1 ) {
        perror("ioctl sample format");
        return -1;
    }
    result = ioctl (paudio_dev->fd, SNDCTL_DSP_CHANNELS, &(paudio_dev->channels));
    if ( result == -1 ) {
        perror("ioctl sample format");
        return -1;
    }
    //format = AFMT_S16_BE;
    //format = AFMT_S16_LE;
    result = ioctl(paudio_dev->fd, SNDCTL_DSP_SETFMT, &(paudio_dev->format));
    if ( result == -1 ) {
        perror("ioctl sample format");
        return -1;
    }
    fprintf (stderr, "setup audio args,speed:%ld, channels:%ld, format:%ld\n",paudio_dev->samplerate,paudio_dev->channels,paudio_dev->format);
    return 0;
}
int close_audio(PAUDIO_DEV paudio_dev)
{
    close(paudio_dev->fd);
}
/*vo_fbdev.h*/
#ifndef _VO_FBDEV_H_
#define _VO_FBDEV_H_
#include
typedef struct fbdev{
    int fb;
    unsigned long fb_mem_offset;
    unsigned long fb_mem;
    struct fb_fix_screeninfo fb_fix;
    struct fb_var_screeninfo fb_var;
    char dev[20];
} FBDEV, *PFBDEV;
int fb_open(PFBDEV pFbdev);
int fb_close(PFBDEV pFbdev);
int get_display_depth(PFBDEV pFbdev);
void fb_memset(void *addr, int c, size_t len);
#endif
/*vo_fbdev.c*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "vo_fbdev.h"
#define TRUE        1
#define FALSE       0
#define MAX(x,y)        ((x)>(y)?(x):(y))
#define MIN(x,y)        ((x)<(y)?(x):(y))
int fb_open(PFBDEV pFbdev)
{
    pFbdev->fb = open(pFbdev->dev, O_RDWR);
    if(pFbdev->fb < 0)
    {
        printf("Error opening %s: %m. Check kernel config\n", pFbdev->dev);
        return FALSE;
    }
    if (-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var)))
    {
        printf("ioctl FBIOGET_VSCREENINFO\n");
        return FALSE;
    }
    if (-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix)))
    {
        printf("ioctl FBIOGET_FSCREENINFO\n");
        return FALSE;
    }
    pFbdev->fb_mem_offset = (unsigned long)(pFbdev->fb_fix.smem_start) & (~PAGE_MASK);
    pFbdev->fb_mem = (unsigned long int)mmap(NULL, pFbdev->fb_fix.smem_len + pFbdev->fb_mem_offset, PROT_READ | PROT_WRITE, MAP_SHARED, pFbdev->fb, 0);
    printf("---screen width:%d,screen height:%d,depth:%d-----\n",pFbdev->fb_var.xres, pFbdev->fb_var.yres, pFbdev->fb_var.bits_per_pixel);
    if (-1L == (long) pFbdev->fb_mem)
    {
        printf("mmap error! mem:%d offset:%d\n", pFbdev->fb_mem, pFbdev->fb_mem_offset);
        return FALSE;
    }
    return TRUE;
}
int fb_close(PFBDEV pFbdev)
{
    close(pFbdev->fb);
    pFbdev->fb=-1;
}
int get_display_depth(PFBDEV pFbdev)
{
    if(pFbdev->fb<=0)
    {
        printf("fb device not open, open it first\n");
        return FALSE;
    }
    return pFbdev->fb_var.bits_per_pixel;
}
void fb_memset (void *addr, int c, size_t len)
{
    memset(addr, c, len);
}
#if 0
int main()
{
    FBDEV fbdev;
    memset(&fbdev, 0, sizeof(FBDEV));
    strcpy(fbdev.dev, "/dev/fb0");
    if(fb_open(&fbdev)==FALSE)
    {
        printf("open frame. buffer error\n");
        return;
    }
    fb_memset(fbdev.fb_mem + fbdev.fb_mem_offset, 1, fbdev.fb_fix.smem_len);
    fb_close(&fbdev);
    return 0;
}
#endif
/*swf_play.c*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
//#include
//#include
#include "spp.h"
#include "vo_fbdev.h"
#include "ao_oss.h"
//#define DEBUG(...) fprintf(stderr,__VA_ARGS__)
#define DEBUG(...)
#define ENABLE_AUDIO 1
typedef struct _Packet Packet;
struct _Packet
{
  int code;
  int length;
  void *data;
};
static Packet *packet_get (int fd);
static void packet_free (Packet * packet);
static void packet_write (int fd, int code, int len, const char *s);
static gboolean render_idle_audio (gpointer data);
static gboolean render_idle_noaudio (gpointer data);
static void do_help (void);
static void do_safe (int standalone);
//static void new_window (void);
static void sound_setup (void);
/* vars */
static gboolean go = TRUE;
static int render_time;
static SwfdecDecoder *s;
//static SDL_Surface *sdl_screen;
static int width;
static int height;
static gboolean enable_sound = TRUE;
static gboolean noskip = FALSE;
static gboolean slow = FALSE;
static gboolean safe = FALSE;
static gboolean hidden = FALSE;
//static unsigned long xid;
static double rate;
static int interval;
static GList *sound_buffers;
static int sound_bytes;
static unsigned char *sound_buf;
static FBDEV fbdev;
static AUDIO_DEV audiodev;
int
main (int argc, char *argv[])
{
  int c;
  int index;
  static struct option options[] = {
    {"help", 0, NULL, 'h'},
    {"xid", 1, NULL, 'x'},
    {"no-sound", 0, NULL, 's'},
    {"plugin", 0, NULL, 'p'},
    {"slow", 0, NULL, 'o'},
    {"safe", 0, NULL, 'f'},
    {0},
  };
  int ret;
  int standalone = TRUE;
  int rendering = FALSE;
  int starting = FALSE;
  Packet *packet;
  int fd = 0;
  int send_fd = 1;
  DEBUG ("swf_play: starting player\n");
  while (1) {
    c = getopt_long (argc, argv, "sx:p", options, &index);
    if (c == -1)
      break;
    switch (c) {
      case 's':
        enable_sound = FALSE;
        break;
      case 'x':
        //setenv ("SDL_WINDOWID", optarg, 1);
        //xid = strtol (optarg, NULL, 0);
        break;
      case 'p':
        standalone = FALSE;
        break;
      case 'o':
        slow = TRUE;
        break;
      case 'f':
        safe = TRUE;
        break;
      case 'h':
      default:
        do_help ();
        break;
    }
  }
  if (standalone) {
    if (optind != argc - 1)
      do_help ();
  } else {
    if (optind != argc)
      do_help ();
  }
//  SDL_Init (SDL_INIT_NOPARACHUTE | SDL_INIT_AUDIO | SDL_INIT_VIDEO |
 //     SDL_INIT_TIMER);
  /* SDL thinks it's smart by overriding SIGINT.  It's not */
  signal (SIGINT, SIG_DFL);
 // SDL_EventState (SDL_ACTIVEEVENT, SDL_ENABLE);
 // if (safe) {
 //   do_safe(standalone);
 // }
  s = swfdec_decoder_new ();
  if (standalone) {
    char *contents;
    gsize length;
    ret = g_file_get_contents (argv[optind], &contents, &length, NULL);
    if (!ret) {
      DEBUG ("error reading file\n");
      exit (1);
    }
    swfdec_decoder_add_data (s, contents, length);
    swfdec_decoder_eof (s);
    ret = swfdec_decoder_parse (s);
    if (ret == SWF_ERROR) {
      DEBUG ("error while parsing\n");
      exit (1);
    }
    starting = TRUE;
  }
  while (1) {
//    SDL_Event event;
    int did_something = FALSE;
    if (!standalone) {
      packet = packet_get (fd);
      if (packet) {
        switch (packet->code) {
          case SPP_EXIT:
            exit (0);
            break;
          case SPP_DATA:
            swfdec_decoder_add_data (s, packet->data, packet->length);
            packet->data = NULL;
            break;
          case SPP_EOF:
            swfdec_decoder_eof (s);
            starting = TRUE;
            break;
          case SPP_SIZE:
            width = ((int *) packet->data)[0];
            height = ((int *) packet->data)[1];
            swfdec_decoder_set_image_size (s, width, height);
           // new_window ();
            break;
          default:
            /* ignore it */
            break;
        }
        packet_free (packet);
        did_something = TRUE;
      }
    }
#if 0
    //if (standalone) {
      if (SDL_PollEvent (&event)) {
        did_something = TRUE;
        DEBUG ("event %d\n", event.type);
        switch (event.type) {
          case SDL_VIDEORESIZE:
            width = event.resize.w;
            height = event.resize.h;
            swfdec_decoder_set_image_size (s, width, height);
            new_window ();
            break;
          case SDL_MOUSEMOTION:
            swfdec_decoder_set_mouse (s, event.motion.x, event.motion.y,
                event.motion.state);
            break;
          case SDL_MOUSEBUTTONDOWN:
          case SDL_MOUSEBUTTONUP:
            swfdec_decoder_set_mouse (s, event.button.x, event.button.y,
                event.button.state);
            break;
          case SDL_ACTIVEEVENT:
            if (event.active.state & SDL_APPMOUSEFOCUS) {
              if (event.active.gain == 0) {
                swfdec_decoder_set_mouse (s, -1, -1, 0);
              }
            }
            if (event.active.state & SDL_APPACTIVE) {
              hidden = !event.active.gain;
            }
            break;
          default:
            break;
        }
      }
    //}
#endif
    if (starting) {
      ret = swfdec_decoder_parse (s);
      DEBUG ("parse ret = %d\n", ret);
      ret = swfdec_decoder_parse (s);
      DEBUG ("parse ret = %d\n", ret);
      ret = swfdec_decoder_parse (s);
      DEBUG ("parse ret = %d\n", ret);
      ret = swfdec_decoder_parse (s);
      DEBUG ("parse ret = %d\n", ret);
      swfdec_decoder_get_rate (s, &rate);
      interval = 1000.0 / rate;
      swfdec_decoder_get_image_size (s, &width, &height);
      DEBUG ("size %dx%d\n", width, height);
//      new_window ();
      memset(&fbdev, 0, sizeof(FBDEV));
      strcpy(fbdev.dev, "/dev/fb0");
      if(fb_open(&fbdev)==FALSE)
      {
          printf("open frame. buffer error\n");
          return;
      }
      fb_memset(fbdev.fb_mem + fbdev.fb_mem_offset, 1, fbdev.fb_fix.smem_len);
#ifdef ENABLE_AUDIO
      if (enable_sound)
        sound_setup ();
#endif
      render_time = 0;
      starting = FALSE;
      rendering = TRUE;
      did_something = TRUE;
    }
    if (rendering) {
      //int now = SDL_GetTicks ();
      struct timeval tv;
      int now;
      gettimeofday(&tv, NULL);
      now = tv.tv_sec*1000+tv.tv_usec/1000;
      if (now >= render_time) {
        char *url;
#ifdef ENABLE_AUDIO
        if (enable_sound) {
          render_idle_audio (NULL);
        } else
#endif
        {
          render_idle_noaudio (NULL);
        }
        did_something = TRUE;
        url = swfdec_decoder_get_url (s);
        if (url) {
          DEBUG ("sending URL packet\n");
          packet_write (send_fd, SPP_GO_TO_URL, strlen(url), url);
          g_free (url);
        }
      }
    }
    if (!did_something) {
      usleep (10000);
    }
  }
  exit (0);
}
static void
do_help (void)
{
  g_print ("swf_play [--xid|-x XID] [--no-sound|-s] [--slow] file.swf\n");
  g_print ("swf_play [--xid|-x XID] [--no-sound|-s] [--slow] [--plugin|-p]\n");
  g_print ("swf_play [--help]\n");
  exit (1);
}
#if 0
static void
do_safe (int standalone)
{
  Packet *packet;
  int fd = 0;
  width = 100;
  height = 100;
  new_window ();
  SDL_FillRect (sdl_screen, NULL, 0x80808000);
  SDL_UpdateRect (sdl_screen, 0, 0, width, height);
  while (1) {
    int did_something = FALSE;
    SDL_Event event;
    if (!standalone) {
      packet = packet_get (fd);
      if (packet) {
        switch (packet->code) {
          case SPP_EXIT:
            exit (0);
            break;
          case SPP_DATA:
            swfdec_decoder_add_data (s, packet->data, packet->length);
            packet->data = NULL;
            break;
          case SPP_EOF:
            swfdec_decoder_eof (s);
            //starting = TRUE;
            break;
          case SPP_SIZE:
            width = ((int *) packet->data)[0];
            height = ((int *) packet->data)[1];
            new_window ();
            SDL_FillRect (sdl_screen, NULL, 0x80808000);
            SDL_UpdateRect (sdl_screen, 0, 0, width, height);
            break;
          default:
            /* ignore it */
            break;
        }
        packet_free (packet);
        did_something = TRUE;
      }
    }
    if (SDL_PollEvent (&event)) {
      did_something = TRUE;
      switch (event.type) {
        case SDL_VIDEORESIZE:
          width = event.resize.w;
          height = event.resize.h;
          new_window ();
          SDL_FillRect (sdl_screen, NULL, 0x80808000);
          SDL_UpdateRect (sdl_screen, 0, 0, width, height);
          break;
        case SDL_MOUSEMOTION:
          swfdec_decoder_set_mouse (s, event.motion.x, event.motion.y,
              event.motion.state);
          break;
        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
          swfdec_decoder_set_mouse (s, event.button.x, event.button.y,
              event.button.state);
          break;
        default:
          break;
      }
    }
    if (!did_something) {
      usleep (10000);
    }
  }
}
#endif
#if 0
static void
new_window (void)
{
  sdl_screen = SDL_SetVideoMode (width, height, 32, SDL_SWSURFACE|SDL_RESIZABLE);
  if (sdl_screen == NULL) {
    DEBUG ("SDL_SetVideoMode failed\n");
  }
}
#endif
#ifdef ENABLE_AUDIO
/*static void
fill_audio (void *udata, Uint8 * stream, int len)
{
  GList *g;
  SwfdecBuffer *buffer;
  int n;
  int offset = 0;
  while (1) {
    g = g_list_first (sound_buffers);
    if (!g)
      break;
    buffer = (SwfdecBuffer *) g->data;
    if (buffer->length < len - offset) {
      n = buffer->length;
      memcpy (sound_buf + offset, buffer->data, n);
      swfdec_buffer_unref (buffer);
      sound_buffers = g_list_delete_link (sound_buffers, g);
    } else {
      SwfdecBuffer *subbuffer;
      n = len - offset;
      memcpy (sound_buf + offset, buffer->data, n);
      subbuffer = swfdec_buffer_new_subbuffer (buffer, n, buffer->length - n);
      g->data = subbuffer;
      swfdec_buffer_unref (buffer);
    }
    sound_bytes -= n;
    offset += n;
    if (offset >= len)
      break;
  }
  if (offset < len) {
    memset (sound_buf + offset, 0, len - offset);
  }
  SDL_MixAudio (stream, sound_buf, len, SDL_MIX_MAXVOLUME);
}*/
static void
sound_setup (void)
{
  strcpy(audiodev.dev_name, "/dev/dsp");
  if (slow) {
    audiodev.samplerate = 22050;
  }else{
    audiodev.samplerate = 44100;
  }
#if G_BYTE_ORDER == 4321
  audiodev.format = AFMT_S16_BE;
#else
  audiodev.format = AFMT_S16_LE;
#endif
  audiodev.channels = 2;
  //wanted.samples = 1024;
  //wanted.callback = fill_audio;
  //wanted.userdata = NULL;
  //sound_buf = malloc (1024 * 2 * 2);
  if (open_audio (&audiodev) < 0) {
    DEBUG ("Couldn't open audio, disabling\n");
    enable_sound = FALSE;
  }
  //SDL_PauseAudio (0);
}
static gboolean
render_idle_audio (gpointer data)
{
  SwfdecBuffer *video_buffer;
  SwfdecBuffer *audio_buffer;
  gboolean ret;
#if 0
  if (hidden) {
      struct timeval tv;
      int now;
      gettimeofday(&tv, NULL);
      now = tv.tv_sec*1000+tv.tv_usec/1000;
   // int now = SDL_GetTicks ();
    render_time = now + 10;
    return FALSE;
  }
  if (sound_bytes >= 40000) {
      struct timeval tv;
      int now;
      gettimeofday(&tv, NULL);
      now = tv.tv_sec*1000+tv.tv_usec/1000;
    //int now = SDL_GetTicks ();
    render_time = now + 10;
    return FALSE;
  }
#endif
  ret = swfdec_render_iterate (s);
  if (!ret) {
    go = FALSE;
    return FALSE;
  }
  audio_buffer = swfdec_render_get_audio (s);
  if (audio_buffer == NULL) {
    /* error */
    go = FALSE;
  }
//  sound_buffers = g_list_append (sound_buffers, audio_buffer);
  sound_bytes += audio_buffer->length;
  ret = write(audiodev.fd, audio_buffer->data, audio_buffer->length);
  //close_audio(&audiodev);
#if 0
  if (slow) {
    swfdec_buffer_ref (audio_buffer);
    sound_buffers = g_list_append (sound_buffers, audio_buffer);
    sound_bytes += audio_buffer->length;
  }
#endif
  if (sound_bytes > 20000 || noskip) {
    video_buffer = swfdec_render_get_image (s);
  } else {
    video_buffer = NULL;
    DEBUG ("video_buffer == NULL\n");
  }
  if (video_buffer) {
    int ret;
    //SDL_Surface *surface;
    int i;
    if (video_buffer->length != width * height * 4) {
      DEBUG ("video buffer wrong size (%d should be %d)\n",
          video_buffer->length, width * height * 4);
    }
#if G_BYTE_ORDER == 4321
#define RED_MASK 0x0000ff00
#define GREEN_MASK 0x00ff0000
#define BLUE_MASK 0xff000000
#define ALPHA_MASK 0x000000ff
#else
#define RED_MASK 0x00ff0000
#define GREEN_MASK 0x0000ff00
#define BLUE_MASK 0x000000ff
#define ALPHA_MASK 0xff000000
#endif
   /* surface = SDL_CreateRGBSurfaceFrom (video_buffer->data, width,
        height, 32, width * 4, RED_MASK, GREEN_MASK, BLUE_MASK, ALPHA_MASK);
    SDL_SetAlpha (surface, 0, SDL_ALPHA_OPAQUE);
    ret = SDL_BlitSurface (surface, NULL, sdl_screen, NULL);
    if (ret < 0) {
      DEBUG ("SDL_BlitSurface failed\n");
    }
    SDL_UpdateRect (sdl_screen, 0, 0, width, height);
    */
    for(i=0; i        memcpy(fbdev.fb_mem + fbdev.fb_mem_offset+i*fbdev.fb_var.xres*4, video_buffer->data+i*width*4,width*4);
    }
    swfdec_buffer_unref (video_buffer);
//    SDL_FreeSurface (surface);
  }
阅读(1773) | 评论(0) | 转发(0) |
0

上一篇:jpeg6b直接解码yuv

下一篇:yvu9_to_yuv422

给主人留下些什么吧!~~