expand.c
来自「linux下的MPEG1」· C语言 代码 · 共 456 行 · 第 1/2 页
C
456 行
this->enable_automatic_shift = param->enable_automatic_shift; this->overlay_y_offset = param->overlay_y_offset; this->aspect = param->aspect; this->centre_cut_out_mode = param->centre_cut_out_mode; return 1;}static int expand_get_parameters(xine_post_t *this_gen, void *param_gen){ post_expand_t *this = (post_expand_t *)this_gen; expand_parameters_t *param = (expand_parameters_t *)param_gen; param->enable_automatic_shift = this->enable_automatic_shift; param->overlay_y_offset = this->overlay_y_offset; param->aspect = this->aspect; param->centre_cut_out_mode = this->centre_cut_out_mode; return 1;}static char *expand_get_help(void) { return _("The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars " "on the top and bottom of the frame. This allows us to shift overlays " "down into the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" );}static int is_pixel_black(vo_frame_t *frame, int x, int y){ int Y = 0x00, Cr = 0x00, Cb = 0x00; if (x < 0) x = 0; if (x >= frame->width) x = frame->width - 1; if (y < 0) y = 0; if (y >= frame->height) y = frame->height - 1; switch (frame->format) { case XINE_IMGFMT_YV12: Y = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x); Cr = *(frame->base[ 1 ] + frame->pitches[ 1 ] * y / 2 + x / 2); Cb = *(frame->base[ 2 ] + frame->pitches[ 2 ] * y / 2 + x / 2); break; case XINE_IMGFMT_YUY2: Y = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 0); x &= ~1; Cr = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 1); Cb = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 3); break; } return (Y == 0x10 && Cr == 0x80 && Cb == 0x80);}static int expand_draw(vo_frame_t *frame, xine_stream_t *stream){ post_video_port_t *port = (post_video_port_t *)frame->port; post_expand_t *this = (post_expand_t *)port->post; int skip; if (this->centre_cut_out_mode && !frame->bad_frame) { /* expected area of inner 4:3 image */ int centre_width = frame->width * (9 * 4) / (16 * 3); int centre_left = (frame->width - centre_width ) / 2; /* centre point for detecting a black frame */ int centre_x = frame->width / 2; int centre_y = frame->height / 2; /* ignore a black frame as it could lead to wrong results */ if (!is_pixel_black(frame, centre_x, centre_y)) { /* coordinates for testing black border near the centre area */ int test_left = centre_left - 16; int test_right = centre_left + 16 + centre_width; /* enable cropping when these pixels are black */ this->cropping_active = is_pixel_black(frame, test_left, centre_y) && is_pixel_black(frame, test_right, centre_y); } /* crop frame */ if (this->centre_cut_out_mode && this->cropping_active) { frame->crop_left += centre_left; frame->crop_right += centre_left; /* get_frame() allocated an extra high frame */ frame->crop_top += (frame->next->height - frame->height) / 2; frame->crop_bottom += (frame->next->height - frame->height) / 2; } } frame->ratio = this->aspect; _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); return skip;}static vo_frame_t *expand_get_frame(xine_video_port_t *port_gen, uint32_t width, uint32_t height, double ratio, int format, int flags){ post_video_port_t *port = (post_video_port_t *)port_gen; post_expand_t *this = (post_expand_t *)port->post; vo_frame_t *frame; uint32_t new_height, top_bar_height; int i, end; _x_post_rewire(&this->post); if (ratio <= 0.0) ratio = (double)width / (double)height; /* Calculate height of expanded frame */ new_height = (double)height * ratio / this->aspect; new_height = (new_height + 1) & ~1; top_bar_height = (new_height - height) / 2; top_bar_height = (top_bar_height + 1) & ~1; this->top_bar_height = top_bar_height; if (new_height > height && (format == XINE_IMGFMT_YV12 || format == XINE_IMGFMT_YUY2)) { frame = port->original_port->get_frame(port->original_port, width, new_height, this->aspect, format, flags); _x_post_inc_usage(port); frame = _x_post_intercept_video_frame(frame, port); /* paint black bars in the top and bottom of the frame and hide these * from the decoders by modifying the pointers to and * the size of the drawing area */ frame->height = height; frame->ratio = ratio; switch (format) { case XINE_IMGFMT_YV12: /* paint top bar */ memset(frame->base[0], 0, frame->pitches[0] * top_bar_height ); memset(frame->base[1], 128, frame->pitches[1] * top_bar_height / 2); memset(frame->base[2], 128, frame->pitches[2] * top_bar_height / 2); /* paint bottom bar */ memset(frame->base[0] + frame->pitches[0] * (top_bar_height + height) , 0, frame->pitches[0] * (new_height - top_bar_height - height) ); memset(frame->base[1] + frame->pitches[1] * (top_bar_height + height) / 2, 128, frame->pitches[1] * (new_height - top_bar_height - height) / 2); memset(frame->base[2] + frame->pitches[2] * (top_bar_height + height) / 2, 128, frame->pitches[2] * (new_height - top_bar_height - height) / 2); /* modify drawing area */ frame->base[0] += frame->pitches[0] * top_bar_height; frame->base[1] += frame->pitches[1] * top_bar_height / 2; frame->base[2] += frame->pitches[2] * top_bar_height / 2; break; case XINE_IMGFMT_YUY2: /* paint top bar */ end = frame->pitches[0] * top_bar_height; for (i = 0; i < end; i += 2) { frame->base[0][i] = 0; frame->base[0][i+1] = 128; } /* paint bottom bar */ end = frame->pitches[0] * new_height; for (i = frame->pitches[0] * (top_bar_height + height); i < end; i += 2) { frame->base[0][i] = 0; frame->base[0][i+1] = 128; } /* modify drawing area */ frame->base[0] += frame->pitches[0] * top_bar_height; } } else { frame = port->original_port->get_frame(port->original_port, width, height, ratio, format, flags); /* no need to intercept this one, we are not going to do anything with it */ } return frame;}static int expand_intercept_ovl(post_video_port_t *port){ post_expand_t *this = (post_expand_t *)port->post; if (this->centre_cut_out_mode && this->cropping_active) return 0; /* we always intercept overlay manager */ return 1;}static int32_t expand_overlay_add_event(video_overlay_manager_t *this_gen, void *event_gen){ video_overlay_event_t *event = (video_overlay_event_t *)event_gen; post_video_port_t *port = _x_post_ovl_manager_to_port(this_gen); post_expand_t *this = (post_expand_t *)port->post; if (event->event_type == OVERLAY_EVENT_SHOW) { switch (event->object.object_type) { case 0: /* regular subtitle */ if (this->enable_automatic_shift) event->object.overlay->y += 2 * this->top_bar_height; else event->object.overlay->y += this->overlay_y_offset; break; case 1: /* menu overlay */ event->object.overlay->y += this->top_bar_height; } } return port->original_manager->add_event(port->original_manager, event_gen);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?