xine_goom.c

来自「linux下的MPEG1」· C语言 代码 · 共 606 行 · 第 1/2 页

C
606
字号
/* * Copyright (C) 2000-2004 the xine project *  * This file is part of xine, a free video player. *  * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * xine 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 General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA * * $Id: xine_goom.c,v 1.65 2007/02/20 00:58:51 dgp85 Exp $ * * GOOM post plugin. * * first version by Mark Thomas * ported to post plugin architecture by Miguel Freitas * real work by goom author, JC Hoelt <jeko@free.fr>. */#include <stdio.h>#include <stdlib.h>#include <time.h>#define LOG_MODULE "goom"#define LOG_VERBOSE/*#define LOG*/#include "config.h"#include "xine_internal.h"#include "xineutils.h"#include "post.h"#include "goom.h"#define NUMSAMPLES  512 /* hardcoded into goom api */#define FPS          14#define GOOM_WIDTH  320#define GOOM_HEIGHT 240/* colorspace conversion methods */static const char const * goom_csc_methods[]={  "Fast but not photorealistic",  "Slow but looks better",  NULL};typedef struct post_plugin_goom_s post_plugin_goom_t;typedef struct post_class_goom_s post_class_goom_t;struct post_class_goom_s {  post_class_t class;  post_plugin_goom_t *ip;  xine_t             *xine;};struct post_plugin_goom_s {  post_plugin_t post;  /* private data */  xine_video_port_t *vo_port;  post_out_t         video_output;    post_class_goom_t *class;    /* private metronom for syncing the video */  metronom_t        *metronom;    /* goom context */  PluginInfo        *goom;    int data_idx;   gint16 data [2][NUMSAMPLES];  audio_buffer_t buf;   /* dummy buffer just to hold a copy of audio data */    int channels;  int sample_rate;  int samples_per_frame;  int width, height;  int width_back, height_back;  double ratio;  int fps;  int csc_method;  int do_samples_skip; /* true = skipping samples, false reading samples*/  int left_to_read; /* data to read before switching modes*/  yuv_planes_t yuv;    /* frame skipping */  int skip_frame;};/* plugin class initialization function */static void *goom_init_plugin(xine_t *xine, void *);/* plugin catalog information */static const post_info_t goom_special_info = {   XINE_POST_TYPE_AUDIO_VISUALIZATION};const plugin_info_t xine_plugin_info[] EXPORTED = {  /* type, API, "name", version, special_info, init_function */    { PLUGIN_POST | PLUGIN_MUST_PRELOAD, 9, "goom", XINE_VERSION_CODE, &goom_special_info, &goom_init_plugin },  { PLUGIN_NONE, 0, "", 0, NULL, NULL }};/* plugin class functions */static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs,					 xine_audio_port_t **audio_target,					 xine_video_port_t **video_target);static char          *goom_get_identifier(post_class_t *class_gen);static char          *goom_get_description(post_class_t *class_gen);static void           goom_class_dispose(post_class_t *class_gen);/* plugin instance functions */static void           goom_dispose(post_plugin_t *this_gen);/* rewire function */static int            goom_rewire_video(xine_post_out_t *output, void *data);static int goom_port_open(xine_audio_port_t *this, xine_stream_t *stream,		   uint32_t bits, uint32_t rate, int mode);static void goom_port_close(xine_audio_port_t *this, xine_stream_t *stream );static void goom_port_put_buffer (xine_audio_port_t *this, audio_buffer_t *buf, xine_stream_t *stream);static void fps_changed_cb(void *data, xine_cfg_entry_t *cfg) {  post_class_goom_t *class = (post_class_goom_t*) data;    if(class->ip) {    post_plugin_goom_t *this = class->ip;    if (cfg->num_value < 1)      cfg->num_value = 1;    this->fps = cfg->num_value;    if(this->sample_rate)      this->samples_per_frame = this->sample_rate / this->fps;  }}static void width_changed_cb(void *data, xine_cfg_entry_t *cfg) {  post_class_goom_t *class = (post_class_goom_t*) data;    if(class->ip) {    post_plugin_goom_t *this = class->ip;    this->width = cfg->num_value;  }}static void height_changed_cb(void *data, xine_cfg_entry_t *cfg) {  post_class_goom_t *class = (post_class_goom_t*) data;    if(class->ip) {    post_plugin_goom_t *this = class->ip;    this->height = cfg->num_value;  }}static void csc_method_changed_cb(void *data, xine_cfg_entry_t *cfg) {  post_class_goom_t *class = (post_class_goom_t*) data;    if(class->ip) {    post_plugin_goom_t *this = class->ip;    this->csc_method = cfg->num_value;  }}static void *goom_init_plugin(xine_t *xine, void *data){  post_class_goom_t *this = (post_class_goom_t *)xine_xmalloc(sizeof(post_class_goom_t));  config_values_t   *cfg;  if (!this)    return NULL;    this->class.open_plugin     = goom_open_plugin;  this->class.get_identifier  = goom_get_identifier;  this->class.get_description = goom_get_description;  this->class.dispose         = goom_class_dispose;  this->ip                    = NULL;  this->xine                  = xine;    cfg = xine->config;  cfg->register_num (cfg, "effects.goom.fps", FPS,                                 _("frames per second to generate"),                                 _("With more frames per second, the animation will get "				   "smoother and faster, but will also require more CPU power."),				 10, fps_changed_cb, this);  cfg->register_num (cfg, "effects.goom.width", GOOM_WIDTH,                                   _("goom image width"),				   _("The width in pixels of the image to be generated."),                                   10, width_changed_cb, this);    cfg->register_num (cfg, "effects.goom.height", GOOM_HEIGHT,                                    _("goom image height"),				    _("The height in pixels of the image to be generated."),                                    10, height_changed_cb, this);    cfg->register_enum (cfg, "effects.goom.csc_method", 0,                           goom_csc_methods,                           _("colorspace conversion method"),                           _("You can choose the colorspace conversion method used by goom.\n"			     "The available selections should be self-explaining."),			   20, csc_method_changed_cb, this);  return &this->class;}static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs,					 xine_audio_port_t **audio_target,					 xine_video_port_t **video_target){  post_plugin_goom_t *this  = (post_plugin_goom_t *)xine_xmalloc(sizeof(post_plugin_goom_t));  post_class_goom_t  *class = (post_class_goom_t*) class_gen;  post_in_t          *input;  post_out_t         *output;  post_out_t         *outputv;  post_audio_port_t  *port;  xine_cfg_entry_t    fps_entry, width_entry, height_entry, csc_method_entry;  if (!this || !video_target || !video_target[0] || !audio_target || !audio_target[0]) {    free(this);    return NULL;  }    _x_post_init(&this->post, 1, 0);    /*   * Lookup config entries.   */  this->class = class;  class->ip   = this;  this->vo_port = video_target[0];    this->metronom = _x_metronom_init(1, 0, class->xine);  lprintf("goom_open_plugin\n");  if(xine_config_lookup_entry(class->xine, "effects.goom.fps",                              &fps_entry))     fps_changed_cb(class, &fps_entry);  if(xine_config_lookup_entry(class->xine, "effects.goom.width",                              &width_entry))     width_changed_cb(class, &width_entry);  if(xine_config_lookup_entry(class->xine, "effects.goom.height",                              &height_entry))     height_changed_cb(class, &height_entry);  if(xine_config_lookup_entry(class->xine, "effects.goom.csc_method",                              &csc_method_entry))     csc_method_changed_cb(class, &csc_method_entry);  this->width_back  = this->width;  this->height_back = this->height;  srand((unsigned int)time((time_t *)NULL));  this->goom = goom_init (this->width_back, this->height_back);  this->ratio = (double)this->width_back/(double)this->height_back;  this->buf.mem = NULL;  this->buf.mem_size = 0;    port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output);  port->new_port.open       = goom_port_open;  port->new_port.close      = goom_port_close;  port->new_port.put_buffer = goom_port_put_buffer;    outputv                  = &this->video_output;  outputv->xine_out.name   = "generated video";  outputv->xine_out.type   = XINE_POST_DATA_VIDEO;  outputv->xine_out.data   = (xine_video_port_t **)&this->vo_port;  outputv->xine_out.rewire = goom_rewire_video;  outputv->post            = &this->post;  xine_list_push_back(this->post.output, outputv);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?