croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
Originally committed as revision 888 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
d3b3efe368
commit
ab6d194a38
87
ffmpeg.c
87
ffmpeg.c
@ -79,6 +79,10 @@ static AVInputFormat *file_iformat;
|
|||||||
static AVOutputFormat *file_oformat;
|
static AVOutputFormat *file_oformat;
|
||||||
static int frame_width = 160;
|
static int frame_width = 160;
|
||||||
static int frame_height = 128;
|
static int frame_height = 128;
|
||||||
|
static int frame_topBand = 0;
|
||||||
|
static int frame_bottomBand = 0;
|
||||||
|
static int frame_leftBand = 0;
|
||||||
|
static int frame_rightBand = 0;
|
||||||
static int frame_rate = 25 * FRAME_RATE_BASE;
|
static int frame_rate = 25 * FRAME_RATE_BASE;
|
||||||
static int video_bit_rate = 200*1000;
|
static int video_bit_rate = 200*1000;
|
||||||
static int video_bit_rate_tolerance = 4000*1000;
|
static int video_bit_rate_tolerance = 4000*1000;
|
||||||
@ -821,9 +825,11 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
ost->pict_tmp.linesize[1] = codec->width / 2;
|
ost->pict_tmp.linesize[1] = codec->width / 2;
|
||||||
ost->pict_tmp.linesize[2] = codec->width / 2;
|
ost->pict_tmp.linesize[2] = codec->width / 2;
|
||||||
|
|
||||||
ost->img_resample_ctx = img_resample_init(
|
ost->img_resample_ctx = img_resample_full_init(
|
||||||
ost->st->codec.width, ost->st->codec.height,
|
ost->st->codec.width, ost->st->codec.height,
|
||||||
ist->st->codec.width, ist->st->codec.height);
|
ist->st->codec.width, ist->st->codec.height,
|
||||||
|
frame_topBand, frame_bottomBand,
|
||||||
|
frame_leftBand, frame_rightBand);
|
||||||
}
|
}
|
||||||
ost->encoding_needed = 1;
|
ost->encoding_needed = 1;
|
||||||
ist->decoding_needed = 1;
|
ist->decoding_needed = 1;
|
||||||
@ -1382,6 +1388,79 @@ void opt_frame_rate(const char *arg)
|
|||||||
frame_rate = (int)(strtod(arg, 0) * FRAME_RATE_BASE);
|
frame_rate = (int)(strtod(arg, 0) * FRAME_RATE_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void opt_frame_crop_top(const char *arg)
|
||||||
|
{
|
||||||
|
frame_topBand = atoi(arg);
|
||||||
|
if (frame_topBand < 0) {
|
||||||
|
fprintf(stderr, "Incorrect top crop size\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((frame_topBand % 2) != 0) {
|
||||||
|
fprintf(stderr, "Top crop size must be a multiple of 2\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((frame_topBand) >= frame_height){
|
||||||
|
fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
frame_height -= frame_topBand;
|
||||||
|
}
|
||||||
|
|
||||||
|
void opt_frame_crop_bottom(const char *arg)
|
||||||
|
{
|
||||||
|
frame_bottomBand = atoi(arg);
|
||||||
|
if (frame_bottomBand < 0) {
|
||||||
|
fprintf(stderr, "Incorrect bottom crop size\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((frame_bottomBand % 2) != 0) {
|
||||||
|
fprintf(stderr, "Bottom crop size must be a multiple of 2\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((frame_bottomBand) >= frame_height){
|
||||||
|
fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
frame_height -= frame_bottomBand;
|
||||||
|
}
|
||||||
|
|
||||||
|
void opt_frame_crop_left(const char *arg)
|
||||||
|
{
|
||||||
|
frame_leftBand = atoi(arg);
|
||||||
|
if (frame_leftBand < 0) {
|
||||||
|
fprintf(stderr, "Incorrect left crop size\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((frame_leftBand % 2) != 0) {
|
||||||
|
fprintf(stderr, "Left crop size must be a multiple of 2\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((frame_leftBand) >= frame_width){
|
||||||
|
fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
frame_width -= frame_leftBand;
|
||||||
|
}
|
||||||
|
|
||||||
|
void opt_frame_crop_right(const char *arg)
|
||||||
|
{
|
||||||
|
frame_rightBand = atoi(arg);
|
||||||
|
if (frame_rightBand < 0) {
|
||||||
|
fprintf(stderr, "Incorrect right crop size\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((frame_rightBand % 2) != 0) {
|
||||||
|
fprintf(stderr, "Right crop size must be a multiple of 2\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((frame_rightBand) >= frame_width){
|
||||||
|
fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
frame_width -= frame_rightBand;
|
||||||
|
}
|
||||||
|
|
||||||
void opt_frame_size(const char *arg)
|
void opt_frame_size(const char *arg)
|
||||||
{
|
{
|
||||||
parse_image_size(&frame_width, &frame_height, arg);
|
parse_image_size(&frame_width, &frame_height, arg);
|
||||||
@ -2135,6 +2214,10 @@ const OptionDef options[] = {
|
|||||||
{ "b", HAS_ARG, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
|
{ "b", HAS_ARG, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
|
||||||
{ "r", HAS_ARG, {(void*)opt_frame_rate}, "set frame rate (in Hz)", "rate" },
|
{ "r", HAS_ARG, {(void*)opt_frame_rate}, "set frame rate (in Hz)", "rate" },
|
||||||
{ "s", HAS_ARG, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
|
{ "s", HAS_ARG, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
|
||||||
|
{ "croptop", HAS_ARG, {(void*)opt_frame_crop_top}, "set top crop band size (in pixels)", "size" },
|
||||||
|
{ "cropbottom", HAS_ARG, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" },
|
||||||
|
{ "cropleft", HAS_ARG, {(void*)opt_frame_crop_left}, "set left crop band size (in pixels)", "size" },
|
||||||
|
{ "cropright", HAS_ARG, {(void*)opt_frame_crop_right}, "set right crop band size (in pixels)", "size" },
|
||||||
{ "g", HAS_ARG | OPT_EXPERT, {(void*)opt_gop_size}, "set the group of picture size", "gop_size" },
|
{ "g", HAS_ARG | OPT_EXPERT, {(void*)opt_gop_size}, "set the group of picture size", "gop_size" },
|
||||||
{ "intra", OPT_BOOL | OPT_EXPERT, {(void*)&intra_only}, "use only intra frames"},
|
{ "intra", OPT_BOOL | OPT_EXPERT, {(void*)&intra_only}, "use only intra frames"},
|
||||||
{ "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
|
{ "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
|
||||||
|
@ -463,6 +463,12 @@ typedef struct ImgReSampleContext ImgReSampleContext;
|
|||||||
|
|
||||||
ImgReSampleContext *img_resample_init(int output_width, int output_height,
|
ImgReSampleContext *img_resample_init(int output_width, int output_height,
|
||||||
int input_width, int input_height);
|
int input_width, int input_height);
|
||||||
|
|
||||||
|
ImgReSampleContext *img_resample_full_init(int owidth, int oheight,
|
||||||
|
int iwidth, int iheight,
|
||||||
|
int topBand, int bottomBand,
|
||||||
|
int leftBand, int rightBand);
|
||||||
|
|
||||||
void img_resample(ImgReSampleContext *s,
|
void img_resample(ImgReSampleContext *s,
|
||||||
AVPicture *output, AVPicture *input);
|
AVPicture *output, AVPicture *input);
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#define NB_PHASES (1 << PHASE_BITS)
|
#define NB_PHASES (1 << PHASE_BITS)
|
||||||
#define NB_TAPS 4
|
#define NB_TAPS 4
|
||||||
#define FCENTER 1 /* index of the center of the filter */
|
#define FCENTER 1 /* index of the center of the filter */
|
||||||
|
//#define TEST 1 /* Test it */
|
||||||
|
|
||||||
#define POS_FRAC_BITS 16
|
#define POS_FRAC_BITS 16
|
||||||
#define POS_FRAC (1 << POS_FRAC_BITS)
|
#define POS_FRAC (1 << POS_FRAC_BITS)
|
||||||
@ -39,7 +40,7 @@
|
|||||||
#define LINE_BUF_HEIGHT (NB_TAPS * 4)
|
#define LINE_BUF_HEIGHT (NB_TAPS * 4)
|
||||||
|
|
||||||
struct ImgReSampleContext {
|
struct ImgReSampleContext {
|
||||||
int iwidth, iheight, owidth, oheight;
|
int iwidth, iheight, owidth, oheight, topBand, bottomBand, leftBand, rightBand;
|
||||||
int h_incr, v_incr;
|
int h_incr, v_incr;
|
||||||
INT16 h_filters[NB_PHASES][NB_TAPS] __align8; /* horizontal filters */
|
INT16 h_filters[NB_PHASES][NB_TAPS] __align8; /* horizontal filters */
|
||||||
INT16 v_filters[NB_PHASES][NB_TAPS] __align8; /* vertical filters */
|
INT16 v_filters[NB_PHASES][NB_TAPS] __align8; /* vertical filters */
|
||||||
@ -353,8 +354,8 @@ static void component_resample(ImgReSampleContext *s,
|
|||||||
if (++ring_y >= LINE_BUF_HEIGHT + NB_TAPS)
|
if (++ring_y >= LINE_BUF_HEIGHT + NB_TAPS)
|
||||||
ring_y = NB_TAPS;
|
ring_y = NB_TAPS;
|
||||||
last_src_y++;
|
last_src_y++;
|
||||||
/* handle limit conditions : replicate line (slighly
|
/* handle limit conditions : replicate line (slightly
|
||||||
inefficient because we filter multiple times */
|
inefficient because we filter multiple times) */
|
||||||
y1 = last_src_y;
|
y1 = last_src_y;
|
||||||
if (y1 < 0) {
|
if (y1 < 0) {
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
@ -427,6 +428,14 @@ static void build_filter(INT16 *filter, float factor)
|
|||||||
|
|
||||||
ImgReSampleContext *img_resample_init(int owidth, int oheight,
|
ImgReSampleContext *img_resample_init(int owidth, int oheight,
|
||||||
int iwidth, int iheight)
|
int iwidth, int iheight)
|
||||||
|
{
|
||||||
|
return img_resample_full_init(owidth, oheight, iwidth, iheight, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImgReSampleContext *img_resample_full_init(int owidth, int oheight,
|
||||||
|
int iwidth, int iheight,
|
||||||
|
int topBand, int bottomBand,
|
||||||
|
int leftBand, int rightBand)
|
||||||
{
|
{
|
||||||
ImgReSampleContext *s;
|
ImgReSampleContext *s;
|
||||||
|
|
||||||
@ -441,12 +450,16 @@ ImgReSampleContext *img_resample_init(int owidth, int oheight,
|
|||||||
s->oheight = oheight;
|
s->oheight = oheight;
|
||||||
s->iwidth = iwidth;
|
s->iwidth = iwidth;
|
||||||
s->iheight = iheight;
|
s->iheight = iheight;
|
||||||
|
s->topBand = topBand;
|
||||||
|
s->bottomBand = bottomBand;
|
||||||
|
s->leftBand = leftBand;
|
||||||
|
s->rightBand = rightBand;
|
||||||
|
|
||||||
s->h_incr = (iwidth * POS_FRAC) / owidth;
|
s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / owidth;
|
||||||
s->v_incr = (iheight * POS_FRAC) / oheight;
|
s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / oheight;
|
||||||
|
|
||||||
build_filter(&s->h_filters[0][0], (float)owidth / (float)iwidth);
|
build_filter(&s->h_filters[0][0], (float) owidth / (float) (iwidth - leftBand - rightBand));
|
||||||
build_filter(&s->v_filters[0][0], (float)oheight / (float)iheight);
|
build_filter(&s->v_filters[0][0], (float) oheight / (float) (iheight - topBand - bottomBand));
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
fail:
|
fail:
|
||||||
@ -463,8 +476,9 @@ void img_resample(ImgReSampleContext *s,
|
|||||||
shift = (i == 0) ? 0 : 1;
|
shift = (i == 0) ? 0 : 1;
|
||||||
component_resample(s, output->data[i], output->linesize[i],
|
component_resample(s, output->data[i], output->linesize[i],
|
||||||
s->owidth >> shift, s->oheight >> shift,
|
s->owidth >> shift, s->oheight >> shift,
|
||||||
input->data[i], input->linesize[i],
|
input->data[i] + (input->linesize[i] * (s->topBand >> shift)) + (s->leftBand >> shift),
|
||||||
s->iwidth >> shift, s->iheight >> shift);
|
input->linesize[i], ((s->iwidth - s->leftBand - s->rightBand) >> shift),
|
||||||
|
(s->iheight - s->topBand - s->bottomBand) >> shift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,6 +498,13 @@ void *av_mallocz(int size)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void av_free(void *ptr)
|
||||||
|
{
|
||||||
|
/* XXX: this test should not be needed on most libcs */
|
||||||
|
if (ptr)
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* input */
|
/* input */
|
||||||
#define XSIZE 256
|
#define XSIZE 256
|
||||||
#define YSIZE 256
|
#define YSIZE 256
|
||||||
@ -569,19 +590,19 @@ int main(int argc, char **argv)
|
|||||||
} else {
|
} else {
|
||||||
v = ((x + y - XSIZE) * 255) / XSIZE;
|
v = ((x + y - XSIZE) * 255) / XSIZE;
|
||||||
}
|
}
|
||||||
img[y * XSIZE + x] = v;
|
img[(YSIZE - y) * XSIZE + (XSIZE - x)] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
save_pgm("/tmp/in.pgm", img, XSIZE, YSIZE);
|
save_pgm("/tmp/in.pgm", img, XSIZE, YSIZE);
|
||||||
for(i=0;i<sizeof(factors)/sizeof(float);i++) {
|
for(i=0;i<sizeof(factors)/sizeof(float);i++) {
|
||||||
fact = factors[i];
|
fact = factors[i];
|
||||||
xsize = (int)(XSIZE * fact);
|
xsize = (int)(XSIZE * fact);
|
||||||
ysize = (int)(YSIZE * fact);
|
ysize = (int)((YSIZE - 100) * fact);
|
||||||
s = img_resample_init(xsize, ysize, XSIZE, YSIZE);
|
s = img_resample_full_init(xsize, ysize, XSIZE, YSIZE, 50 ,50);
|
||||||
printf("Factor=%0.2f\n", fact);
|
printf("Factor=%0.2f\n", fact);
|
||||||
dump_filter(&s->h_filters[0][0]);
|
dump_filter(&s->h_filters[0][0]);
|
||||||
component_resample(s, img1, xsize, xsize, ysize,
|
component_resample(s, img1, xsize, xsize, ysize,
|
||||||
img, XSIZE, XSIZE, YSIZE);
|
img + 50 * XSIZE, XSIZE, XSIZE, YSIZE - 100);
|
||||||
img_resample_close(s);
|
img_resample_close(s);
|
||||||
|
|
||||||
sprintf(buf, "/tmp/out%d.pgm", i);
|
sprintf(buf, "/tmp/out%d.pgm", i);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user