[Mplayer-cvslog] CVS: main mencoder.c,1.99,1.100 cfg-mencoder.h,1.29,1.30
Fredrik Kuivinen CVS
ksorim at mplayer.dev.hu
Sat Mar 23 14:13:15 CET 2002
Update of /cvsroot/mplayer/main
In directory mplayer:/var/tmp.root/cvs-serv31880
Modified Files:
mencoder.c cfg-mencoder.h
Log Message:
Support for cropping in mencoder. New options:
-x0, -y0: upper-left corner of rectangle to be cut out
-xsize, -ysize: Size of rectangle to cut out
Cropping is done before scaling.
Index: mencoder.c
===================================================================
RCS file: /cvsroot/mplayer/main/mencoder.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -r1.99 -r1.100
--- mencoder.c 20 Mar 2002 15:38:13 -0000 1.99
+++ mencoder.c 23 Mar 2002 13:13:12 -0000 1.100
@@ -97,7 +97,7 @@
#endif
#include <inttypes.h>
-#include "../postproc/swscale.h"
+#include "postproc/swscale.h"
#include "fastmemcpy.h"
@@ -208,9 +208,11 @@
int lame_param_ratio=-1; // unset
#endif
-static int scale_srcW=0;
-static int scale_srcH=0;
static int vo_w=0, vo_h=0;
+static int crop_width, crop_height, crop_x0 = 0, crop_y0 = 0;
+static int input_pitch, input_bpp;
+static SwsContext* swsContext = NULL;
+
//-------------------------- config stuff:
m_config_t* mconfig;
@@ -226,6 +228,7 @@
static int parse_end_at(struct config *conf, const char* param);
static uint8_t* flip_upside_down(uint8_t* dst, const uint8_t* src, int width, int height);
+static int bits_per_pixel(uint32_t fmt);
#include "get_path.c"
@@ -269,34 +272,71 @@
static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h, int x0,int y0){
int y;
// printf("draw_slice %dx%d %d;%d\n",w,h,x0,y0);
- if(scale_srcW || scale_srcH)
+
+ if(y0 + h < crop_y0)
+ return 0;
+
+ if(y0 > crop_height + crop_y0)
+ return 0;
+
+ if(x0 + w < crop_x0)
+ return 0;
+
+ if(x0 > crop_width + crop_x0)
+ return 0;
+
+ if(y0 < crop_y0) {
+ src[0] += stride[0]*(crop_y0 - y0);
+ src[1] += stride[1]*(crop_y0 - y0)/2;
+ src[2] += stride[2]*(crop_y0 - y0)/2;
+ h -= crop_y0 - y0;
+ y0 = crop_y0;
+ }
+
+ if(x0 < crop_x0) {
+ src[0] += crop_x0 - x0;
+ src[1] += (crop_x0 - x0)/2;
+ src[2] += (crop_x0 - x0)/2;
+ w -= crop_x0 - x0;
+ x0 = crop_x0;
+ }
+
+ if(y0 + h > crop_y0 + crop_height)
+ h = crop_y0 + crop_height - y0;
+
+ if(x0 + w > crop_x0 + crop_width)
+ w = crop_x0 + crop_width - x0;
+
+ if(swsContext)
{
uint8_t* dstPtr[3]= {
- vo_image,
- vo_image + vo_w*vo_h*5/4,
- vo_image + vo_w*vo_h};
- SwScale_YV12slice(src, stride, y0, h, dstPtr, vo_w, 12, scale_srcW, scale_srcH, vo_w, vo_h);
+ vo_image,
+ vo_image + vo_w*vo_h*5/4,
+ vo_image + vo_w*vo_h};
+ int dstStride[3] = {vo_w, vo_w/2, vo_w/2};
+
+ swsContext->swScale(swsContext, src, stride, y0 - crop_y0, h, dstPtr, dstStride);
}
else
{
// copy Y:
- for(y=0;y<h;y++){
- unsigned char* s=src[0]+stride[0]*y;
- unsigned char* d=vo_image+vo_w*(y0+y)+x0;
+ for(y = 0; y < h; y++){
+ unsigned char* s = src[0] + stride[0]*y;
+ unsigned char* d = vo_image + vo_w*(y0 - crop_y0 + y);
memcpy(d,s,w);
}
x0>>=1;y0>>=1;
w>>=1;h>>=1;
// copy U:
- for(y=0;y<h;y++){
- unsigned char* s=src[2]+stride[2]*y;
- unsigned char* d=vo_image+vo_w*vo_h+(vo_w>>1)*(y0+y)+x0;
+ for(y = 0; y < h; y++){
+ unsigned char* s = src[2] + stride[2]*y;
+ unsigned char* d = vo_image + vo_w*vo_h + (vo_w>>1)*(y0 - crop_y0/2 + y);
memcpy(d,s,w);
}
// copy V:
- for(y=0;y<h;y++){
- unsigned char* s=src[1]+stride[1]*y;
- unsigned char* d=vo_image+vo_w*vo_h+vo_w*vo_h/4+(vo_w>>1)*(y0+y)+x0;
+ for(y = 0; y < h; y++){
+ unsigned char* s = src[1] + stride[1]*y;
+ unsigned char* d = vo_image + vo_w*vo_h + vo_w*vo_h/4 + (vo_w>>1)*(y0 - crop_y0/2 + y);
memcpy(d,s,w);
}
} // !swscaler
@@ -304,10 +344,25 @@
}
static uint32_t draw_frame(uint8_t *src[]){
+ int y;
// printf("This function shouldn't be called - report bug!\n");
// later: add YUY2->YV12 conversion here!
- vo_image_ptr=src[0];
- return(0);
+
+ if(swsContext) {
+ uint8_t* src_img = *src + crop_y0*input_pitch + crop_x0*input_bpp/8;
+ int dstStride = vo_w * input_bpp/8;
+
+ swsContext->swScale(swsContext, &src_img, &input_pitch, 0, crop_height,
+ &vo_image_ptr, &dstStride);
+ }
+ else {
+ for(y = crop_y0; y < crop_height + crop_y0; y++)
+ memcpy(&vo_image_ptr[(y - crop_y0)*crop_width*input_bpp/8],
+ src[0] + y*input_pitch + crop_x0*input_bpp/8,
+ crop_width*input_bpp/8);
+ }
+
+ return(0);
}
static int query_format(unsigned int out_fmt){
@@ -633,30 +688,41 @@
//sh_video->outfmtidx=i; // FIXME!!!!!!!!!!!!!!!!!!!
-if((out_fmt==IMGFMT_YV12 || out_fmt==IMGFMT_IYUV || out_fmt==IMGFMT_I420) &&
- (vo_w!=0 || vo_h!=0))
-{
- scale_srcW= sh_video->disp_w;
- scale_srcH= sh_video->disp_h;
- if(!vo_w) vo_w=sh_video->disp_w;
- if(!vo_h) vo_h=sh_video->disp_h;
-}
-else
-{
- vo_w=sh_video->disp_w;
- vo_h=sh_video->disp_h;
-}
+ if(!crop_width)
+ crop_width = sh_video->disp_w - crop_x0;
+ if(!crop_height)
+ crop_height = sh_video->disp_h - crop_y0;
+
+ if(crop_width + crop_x0 > sh_video->disp_w ||
+ crop_height + crop_y0 > sh_video->disp_h) {
+ printf("Fatal error: x0 + xsize (or y0 + ysize) is larger than the movie.\n");
+ return 1;
+ }
-if(out_fmt==IMGFMT_YV12 || out_fmt==IMGFMT_I420 || out_fmt==IMGFMT_IYUV){
- vo_image=malloc(vo_w*vo_h*3/2);
- vo_image_ptr=vo_image;
-}
+ if(crop_x0 >= sh_video->disp_w ||
+ crop_y0 >= sh_video->disp_h) {
+ printf("Fatal error: You tried to crop away more than the entire movie!\n");
+ return 1;
+ }
+
+ printf("x0: %d y0: %d crop_width: %d crop_height: %d\n", crop_x0, crop_y0, crop_width, crop_height);
+
+ if(!vo_w) vo_w = crop_width;
+ if(!vo_h) vo_h = crop_height;
-if (IMGFMT_IS_BGR(out_fmt))
- vo_image_ptr = vo_image = malloc(vo_w*vo_h*IMGFMT_BGR_DEPTH(out_fmt)/8);
+ if(vo_w != crop_width || vo_h != crop_height)
+ {
+ swsContext = getSwsContextFromCmdLine(crop_width, crop_height, out_fmt, vo_w, vo_h, out_fmt);
-if (IMGFMT_IS_RGB(out_fmt))
- vo_image_ptr = vo_image = malloc(vo_w*vo_h*IMGFMT_RGB_DEPTH(out_fmt)/8);
+ if(!swsContext) {
+ printf("Fatal error: Initialization of software scaler faild.\n");
+ return 1;
+ }
+ }
+
+ input_bpp = bits_per_pixel(out_fmt);
+ vo_image_ptr = vo_image = malloc(vo_w*vo_h*input_bpp/8);
+ input_pitch = sh_video->disp_w*input_bpp/8;
} // if(out_video_codec)
@@ -700,7 +766,6 @@
// set up video encoder:
-SwScale_Init();
#ifdef USE_DVDREAD
vo_spudec=spudec_new_scaled(stream->type==STREAMTYPE_DVD?((dvd_priv_t *)(stream->priv))->cur_pgc->palette:NULL,
@@ -772,8 +837,8 @@
case VCODEC_RAWRGB:
mux_v->bih=malloc(sizeof(BITMAPINFOHEADER));
mux_v->bih->biSize=sizeof(BITMAPINFOHEADER);
- mux_v->bih->biWidth=sh_video->disp_w;
- mux_v->bih->biHeight=sh_video->disp_h;
+ mux_v->bih->biWidth=vo_w;
+ mux_v->bih->biHeight=vo_h;
mux_v->bih->biCompression=0;
mux_v->bih->biPlanes=1;
@@ -1484,8 +1549,8 @@
vo_w*3, vo_h);
}
else {
- yuv2rgb(raw_rgb_buffer, vo_image_ptr, vo_image_ptr + vo_w*vo_h*5/4,
- vo_image_ptr + vo_w*vo_h, vo_w, vo_h, vo_w*24/8, vo_w, vo_w/2);
+ yuv2rgb(raw_rgb_buffer, vo_image_ptr, vo_image_ptr + vo_w*vo_h,
+ vo_image_ptr + vo_w*vo_h*5/4, vo_w, vo_h, vo_w*24/8, vo_w, vo_w/2);
mux_v->buffer = flip_upside_down(raw_rgb_buffer, raw_rgb_buffer,
vo_w*3, vo_h);
}
@@ -1795,4 +1860,29 @@
free(tmp);
return dst;
+}
+
+/* Bits per pixel for format fmt. Not depth */
+static int bits_per_pixel(uint32_t fmt)
+{
+ if(IMGFMT_IS_RGB(fmt)) {
+ if(IMGFMT_RGB_DEPTH(fmt) == 15)
+ return 16;
+ else
+ return IMGFMT_RGB_DEPTH(fmt);
+ }
+ else if(IMGFMT_IS_BGR(fmt)) {
+ if(IMGFMT_BGR_DEPTH(fmt) == 15)
+ return 16;
+ else
+ return IMGFMT_BGR_DEPTH(fmt);
+ }
+ else if(fmt==IMGFMT_YV12 || fmt==IMGFMT_I420 || fmt==IMGFMT_IYUV)
+ return 12;
+ else if(fmt == IMGFMT_YUY2 || fmt == IMGFMT_UYVY)
+ return 16;
+ else {
+ fprintf(stderr, "Error: bits_per_pixel: Unknown imgfmt: %s\n", vo_format_name(fmt));
+ return 0;
+ }
}
Index: cfg-mencoder.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-mencoder.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- cfg-mencoder.h 22 Mar 2002 04:14:43 -0000 1.29
+++ cfg-mencoder.h 23 Mar 2002 13:13:12 -0000 1.30
@@ -112,6 +112,12 @@
{"x", &vo_w, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
{"y", &vo_h, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
+ {"x0", &crop_x0, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
+ {"y0", &crop_y0, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
+
+ {"xsize", &crop_width, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
+ {"ysize", &crop_height, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
+
{"mp3file", &mp3_filename, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"ac3file", &ac3_filename, CONF_TYPE_STRING, 0, 0, 0, NULL},
More information about the MPlayer-cvslog
mailing list