xine_goom.c

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

C
606
字号
    this->post.xine_post.audio_input[0] = &port->new_port;  this->post.dispose = goom_dispose;  return &this->post;}static char *goom_get_identifier(post_class_t *class_gen){  return "goom";}static char *goom_get_description(post_class_t *class_gen){  return "What a GOOM";}static void goom_class_dispose(post_class_t *class_gen){  post_class_goom_t  *this = (post_class_goom_t*) class_gen;  this->xine->config->unregister_callback(this->xine->config,		  			  "effects.goom.fps");  this->xine->config->unregister_callback(this->xine->config,		  			  "effects.goom.width");  this->xine->config->unregister_callback(this->xine->config,		  			  "effects.goom.height");  this->xine->config->unregister_callback(this->xine->config,		  			  "effects.goom.csc_method");  free(class_gen);}static void goom_dispose(post_plugin_t *this_gen){  post_plugin_goom_t *this   = (post_plugin_goom_t *)this_gen;  if (_x_post_dispose(this_gen)) {    this->class->ip = NULL;    goom_close(this->goom);    this->metronom->exit(this->metronom);    if(this->buf.mem)      free(this->buf.mem);    free(this);  }}static int goom_rewire_video(xine_post_out_t *output_gen, void *data){  post_out_t *output = (post_out_t *)output_gen;  xine_video_port_t *old_port = *(xine_video_port_t **)output_gen->data;  xine_video_port_t *new_port = (xine_video_port_t *)data;  post_plugin_goom_t *this = (post_plugin_goom_t *)output->post;    if (!data)    return 0;  /* register our stream at the new output port */  old_port->close(old_port, XINE_ANON_STREAM);  (new_port->open) (new_port, XINE_ANON_STREAM);  /* reconnect ourselves */  this->vo_port = new_port;  return 1;}static int goom_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,		   uint32_t bits, uint32_t rate, int mode) {  post_audio_port_t  *port = (post_audio_port_t *)port_gen;  post_plugin_goom_t *this = (post_plugin_goom_t *)port->post;  _x_post_rewire(&this->post);  _x_post_inc_usage(port);    port->stream = stream;  port->bits = bits;  port->rate = rate;  port->mode = mode;    this->channels = _x_ao_mode2channels(mode);  this->sample_rate = rate;  this->samples_per_frame = rate / this->fps;  this->data_idx = 0;  init_yuv_planes(&this->yuv, this->width, this->height);  this->skip_frame = 0;  this->do_samples_skip = 0;  this->left_to_read = NUMSAMPLES;    (this->vo_port->open) (this->vo_port, XINE_ANON_STREAM);  this->metronom->set_master(this->metronom, stream->metronom);  return (port->original_port->open) (port->original_port, stream, bits, rate, mode );}static void goom_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) {  post_audio_port_t  *port = (post_audio_port_t *)port_gen;  post_plugin_goom_t *this = (post_plugin_goom_t *)port->post;  free_yuv_planes(&this->yuv);  port->stream = NULL;    this->vo_port->close(this->vo_port, XINE_ANON_STREAM);  this->metronom->set_master(this->metronom, NULL);   port->original_port->close(port->original_port, stream );    _x_post_dec_usage(port);}static void goom_port_put_buffer (xine_audio_port_t *port_gen,                              audio_buffer_t *buf, xine_stream_t *stream) {    post_audio_port_t  *port = (post_audio_port_t *)port_gen;  post_plugin_goom_t *this = (post_plugin_goom_t *)port->post;  vo_frame_t         *frame;  uint8_t *goom_frame, *goom_frame_end;  int16_t *data;  int8_t *data8;  int64_t pts = buf->vpts;  int i, j;  uint8_t *dest_ptr;  int width, height;  int current_sample = 0;    /* make a copy of buf data for private use */  if( this->buf.mem_size < buf->mem_size ) {    this->buf.mem = realloc(this->buf.mem, buf->mem_size);    this->buf.mem_size = buf->mem_size;  }  memcpy(this->buf.mem, buf->mem,          buf->num_frames*this->channels*((port->bits == 8)?1:2));  this->buf.num_frames = buf->num_frames;    /* pass data to original port */  port->original_port->put_buffer(port->original_port, buf, stream);      /* we must not use original data anymore, it should have already being moved   * to the fifo of free audio buffers. just use our private copy instead.   */  buf = &this->buf;   j = (this->channels >= 2) ? 1 : 0;  while (current_sample < buf->num_frames) {    if (this->do_samples_skip) {    if (current_sample + this->left_to_read > buf->num_frames) {      this->left_to_read -= (buf->num_frames-current_sample);      break;    } else {      current_sample+=this->left_to_read;      this->left_to_read = NUMSAMPLES;      this->do_samples_skip = 0;          }  } else {    if( port->bits == 8 ) {      data8 = (int8_t *)buf->mem;      data8 += current_sample * this->channels;        /* scale 8 bit data to 16 bits and convert to signed as well */      for ( i=current_sample ; this->data_idx < NUMSAMPLES && i < buf->num_frames;        i++, this->data_idx++,data8 += this->channels) {        this->data[0][this->data_idx] = ((int16_t)data8[0] << 8) - 0x8000;        this->data[1][this->data_idx] = ((int16_t)data8[j] << 8) - 0x8000;      }    } else {      data = buf->mem;      data += current_sample * this->channels;      for ( i=current_sample ; this->data_idx < NUMSAMPLES && i < buf->num_frames;        i++, this->data_idx++,data += this->channels) {        this->data[0][this->data_idx] = data[0];        this->data[1][this->data_idx] = data[j];      }    }    if (this->data_idx < NUMSAMPLES) {      this->left_to_read = NUMSAMPLES - this->data_idx;      break;    } else {      _x_assert(this->data_idx == NUMSAMPLES);      this->data_idx = 0;      if (this->samples_per_frame > NUMSAMPLES) {        current_sample += NUMSAMPLES;        this->do_samples_skip = 1;        this->left_to_read = this->samples_per_frame - NUMSAMPLES;      } else {        current_sample += this->samples_per_frame;        this->left_to_read = NUMSAMPLES;      }      frame = this->vo_port->get_frame (this->vo_port, this->width_back, this->height_back,                this->ratio, XINE_IMGFMT_YUY2,                VO_BOTH_FIELDS);            frame->extra_info->invalid = 1;            frame->duration = 90000 * this->samples_per_frame / this->sample_rate;      frame->pts = pts;      this->metronom->got_video_frame(this->metronom, frame);            if (!this->skip_frame) {        /* Try to be fast */        goom_frame = (uint8_t *)goom_update (this->goom, this->data, 0, 0, NULL, NULL);        dest_ptr = frame -> base[0];        goom_frame_end = goom_frame + 4 * (this->width_back * this->height_back);        if ((this->csc_method == 1) &&             (xine_mm_accel() & MM_ACCEL_X86_MMX)) {          int plane_ptr = 0;          while (goom_frame < goom_frame_end) {            uint8_t r, g, b;                  /* don't take endianness into account since MMX is only available             * on Intel processors */            b = *goom_frame; goom_frame++;            g = *goom_frame; goom_frame++;            r = *goom_frame; goom_frame += 2;            this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b);            this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b);            this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b);            plane_ptr++;          }          yuv444_to_yuy2(&this->yuv, frame->base[0], frame->pitches[0]);        } else {          while (goom_frame < goom_frame_end) {            uint8_t r1, g1, b1, r2, g2, b2;#ifdef __BIG_ENDIAN__            goom_frame ++;            r1 = *goom_frame; goom_frame++;            g1 = *goom_frame; goom_frame++;            b1 = *goom_frame; goom_frame += 2;            r2 = *goom_frame; goom_frame++;            g2 = *goom_frame; goom_frame++;            b2 = *goom_frame; goom_frame++;#else            b1 = *goom_frame; goom_frame++;            g1 = *goom_frame; goom_frame++;            r1 = *goom_frame; goom_frame += 2;            b2 = *goom_frame; goom_frame++;            g2 = *goom_frame; goom_frame++;            r2 = *goom_frame; goom_frame += 2;#endif                  *dest_ptr = COMPUTE_Y(r1, g1, b1);            dest_ptr++;            *dest_ptr = COMPUTE_U(r1, g1, b1);            dest_ptr++;            *dest_ptr = COMPUTE_Y(r2, g2, b2);            dest_ptr++;            *dest_ptr = COMPUTE_V(r2, g2, b2);            dest_ptr++;          }        }        this->skip_frame = frame->draw(frame, XINE_ANON_STREAM);      } else {        frame->bad_frame = 1;        frame->draw(frame, XINE_ANON_STREAM);        _x_assert(this->skip_frame>0);        this->skip_frame--;      }      frame->free(frame);            width  = this->width;      height = this->height;      if ((width != this->width_back) || (height != this->height_back)) {        goom_close(this->goom);        this->goom = goom_init (this->width, this->height);        this->width_back = width;        this->height_back = height;        this->ratio = (double)width/(double)height;        free_yuv_planes(&this->yuv);        init_yuv_planes(&this->yuv, this->width, this->height);      }    }  }  }}

⌨️ 快捷键说明

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