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 + -
显示快捷键?