Commit 1ff93ffc authored by Todd Kirby's avatar Todd Kirby Committed by Michael Niedermayer

padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)

Originally committed as revision 2982 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 929a0c41
...@@ -234,6 +234,18 @@ set bottom crop band size (in pixels) ...@@ -234,6 +234,18 @@ set bottom crop band size (in pixels)
set left crop band size (in pixels) set left crop band size (in pixels)
@item -cropright size @item -cropright size
set right crop band size (in pixels) set right crop band size (in pixels)
@item -padtop size
set top pad band size (in pixels)
@item -padbottom size
set bottom pad band size (in pixels)
@item -padleft size
set left pad band size (in pixels)
@item -padright size
set right pad band size (in pixels)
@item -padcolor color
set right pad band size (hex). The value for pad color is expressed
as a six digit hexidecimal number where the first two digits represent red,
middle two digits green and last two digits blue. Defaults to 000000 (black)
@item -vn @item -vn
disable video recording disable video recording
@item -bt tolerance @item -bt tolerance
......
...@@ -72,6 +72,11 @@ static int frame_width = 160; ...@@ -72,6 +72,11 @@ static int frame_width = 160;
static int frame_height = 128; static int frame_height = 128;
static float frame_aspect_ratio = 0; static float frame_aspect_ratio = 0;
static enum PixelFormat frame_pix_fmt = PIX_FMT_YUV420P; static enum PixelFormat frame_pix_fmt = PIX_FMT_YUV420P;
static int frame_padtop = 0;
static int frame_padbottom = 0;
static int frame_padleft = 0;
static int frame_padright = 0;
static int padcolor[3] = {16,128,128}; /* default to black */
static int frame_topBand = 0; static int frame_topBand = 0;
static int frame_bottomBand = 0; static int frame_bottomBand = 0;
static int frame_leftBand = 0; static int frame_leftBand = 0;
...@@ -222,6 +227,12 @@ typedef struct AVOutputStream { ...@@ -222,6 +227,12 @@ typedef struct AVOutputStream {
int topBand; /* cropping area sizes */ int topBand; /* cropping area sizes */
int leftBand; int leftBand;
int video_pad; /* video_resample and video_pad are mutually exclusive */
int padtop; /* padding area sizes */
int padbottom;
int padleft;
int padright;
/* audio only */ /* audio only */
int audio_resample; int audio_resample;
ReSampleContext *resample; /* for audio resampling */ ReSampleContext *resample; /* for audio resampling */
...@@ -497,6 +508,40 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void ...@@ -497,6 +508,40 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void
/* we begin to correct av delay at this threshold */ /* we begin to correct av delay at this threshold */
#define AV_DELAY_MAX 0.100 #define AV_DELAY_MAX 0.100
/* Expects img to be yuv420 */
static void fill_pad_region(AVPicture* img, int height, int width,
int padtop, int padbottom, int padleft, int padright, int *color) {
int i, y, shift;
uint8_t *optr;
for (i = 0; i < 3; i++) {
shift = (i == 0) ? 0 : 1;
if (padtop || padleft) {
memset(img->data[i], color[i], (((img->linesize[i] * padtop) +
padleft) >> shift));
}
if (padleft || padright) {
optr = img->data[i] + (img->linesize[i] * (padtop >> shift)) +
(img->linesize[i] - (padright >> shift));
for (y = 0; y < ((height - (padtop + padbottom)) >> shift); y++) {
memset(optr, color[i], (padleft + padright) >> shift);
optr += img->linesize[i];
}
}
if (padbottom) {
optr = img->data[i] + (img->linesize[i] * ((height - padbottom) >> shift));
memset(optr, color[i], ((img->linesize[i] * padbottom) >> shift));
}
}
}
static void do_video_out(AVFormatContext *s, static void do_video_out(AVFormatContext *s,
AVOutputStream *ost, AVOutputStream *ost,
AVInputStream *ist, AVInputStream *ist,
...@@ -579,7 +624,8 @@ static void do_video_out(AVFormatContext *s, ...@@ -579,7 +624,8 @@ static void do_video_out(AVFormatContext *s,
return; return;
/* convert pixel format if needed */ /* convert pixel format if needed */
target_pixfmt = ost->video_resample ? PIX_FMT_YUV420P : enc->pix_fmt; target_pixfmt = ost->video_resample || ost->video_pad
? PIX_FMT_YUV420P : enc->pix_fmt;
if (dec->pix_fmt != target_pixfmt) { if (dec->pix_fmt != target_pixfmt) {
int size; int size;
...@@ -601,12 +647,19 @@ static void do_video_out(AVFormatContext *s, ...@@ -601,12 +647,19 @@ static void do_video_out(AVFormatContext *s,
formatted_picture = (AVPicture *)in_picture; formatted_picture = (AVPicture *)in_picture;
} }
/* XXX: resampling could be done before raw format convertion in /* XXX: resampling could be done before raw format conversion in
some cases to go faster */ some cases to go faster */
/* XXX: only works for YUV420P */ /* XXX: only works for YUV420P */
if (ost->video_resample) { if (ost->video_resample) {
final_picture = &ost->pict_tmp; final_picture = &ost->pict_tmp;
img_resample(ost->img_resample_ctx, final_picture, formatted_picture); img_resample(ost->img_resample_ctx, final_picture, formatted_picture);
if (ost->padtop || ost->padbottom || ost->padleft || ost->padright) {
fill_pad_region(final_picture, enc->height, enc->width,
ost->padtop, ost->padbottom, ost->padleft, ost->padright,
padcolor);
}
if (enc->pix_fmt != PIX_FMT_YUV420P) { if (enc->pix_fmt != PIX_FMT_YUV420P) {
int size; int size;
...@@ -642,6 +695,51 @@ static void do_video_out(AVFormatContext *s, ...@@ -642,6 +695,51 @@ static void do_video_out(AVFormatContext *s,
picture_crop_temp.linesize[1] = formatted_picture->linesize[1]; picture_crop_temp.linesize[1] = formatted_picture->linesize[1];
picture_crop_temp.linesize[2] = formatted_picture->linesize[2]; picture_crop_temp.linesize[2] = formatted_picture->linesize[2];
final_picture = &picture_crop_temp; final_picture = &picture_crop_temp;
} else if (ost->video_pad) {
final_picture = &ost->pict_tmp;
for (i = 0; i < 3; i++) {
uint8_t *optr, *iptr;
int shift = (i == 0) ? 0 : 1;
int y, yheight;
/* set offset to start writing image into */
optr = final_picture->data[i] + (((final_picture->linesize[i] *
ost->padtop) + ost->padleft) >> shift);
iptr = formatted_picture->data[i];
yheight = (enc->height - ost->padtop - ost->padbottom) >> shift;
for (y = 0; y < yheight; y++) {
/* copy unpadded image row into padded image row */
memcpy(optr, iptr, formatted_picture->linesize[i]);
optr += final_picture->linesize[i];
iptr += formatted_picture->linesize[i];
}
}
fill_pad_region(final_picture, enc->height, enc->width,
ost->padtop, ost->padbottom, ost->padleft, ost->padright,
padcolor);
if (enc->pix_fmt != PIX_FMT_YUV420P) {
int size;
av_free(buf);
/* create temporary picture */
size = avpicture_get_size(enc->pix_fmt, enc->width, enc->height);
buf = av_malloc(size);
if (!buf)
return;
final_picture = &picture_format_temp;
avpicture_fill(final_picture, buf, enc->pix_fmt, enc->width, enc->height);
if (img_convert(final_picture, enc->pix_fmt,
&ost->pict_tmp, PIX_FMT_YUV420P,
enc->width, enc->height) < 0) {
fprintf(stderr, "pixel format conversion not handled\n");
goto the_end;
}
}
} else { } else {
final_picture = formatted_picture; final_picture = formatted_picture;
} }
...@@ -1267,10 +1365,15 @@ static int av_encode(AVFormatContext **output_files, ...@@ -1267,10 +1365,15 @@ static int av_encode(AVFormatContext **output_files,
frame_topBand == 0 && frame_topBand == 0 &&
frame_bottomBand == 0 && frame_bottomBand == 0 &&
frame_leftBand == 0 && frame_leftBand == 0 &&
frame_rightBand == 0) frame_rightBand == 0 &&
frame_padtop == 0 &&
frame_padbottom == 0 &&
frame_padleft == 0 &&
frame_padright == 0)
{ {
ost->video_resample = 0; ost->video_resample = 0;
ost->video_crop = 0; ost->video_crop = 0;
ost->video_pad = 0;
} else if ((codec->width == icodec->width - } else if ((codec->width == icodec->width -
(frame_leftBand + frame_rightBand)) && (frame_leftBand + frame_rightBand)) &&
(codec->height == icodec->height - (codec->height == icodec->height -
...@@ -1280,6 +1383,20 @@ static int av_encode(AVFormatContext **output_files, ...@@ -1280,6 +1383,20 @@ static int av_encode(AVFormatContext **output_files,
ost->video_crop = 1; ost->video_crop = 1;
ost->topBand = frame_topBand; ost->topBand = frame_topBand;
ost->leftBand = frame_leftBand; ost->leftBand = frame_leftBand;
} else if ((codec->width == icodec->width +
(frame_padleft + frame_padright)) &&
(codec->height == icodec->height +
(frame_padtop + frame_padbottom))) {
ost->video_resample = 0;
ost->video_crop = 0;
ost->video_pad = 1;
ost->padtop = frame_padtop;
ost->padleft = frame_padleft;
ost->padbottom = frame_padbottom;
ost->padright = frame_padright;
if( avpicture_alloc( &ost->pict_tmp, PIX_FMT_YUV420P,
codec->width, codec->height ) )
goto fail;
} else { } else {
ost->video_resample = 1; ost->video_resample = 1;
ost->video_crop = 0; // cropping is handled as part of resample ost->video_crop = 0; // cropping is handled as part of resample
...@@ -1291,7 +1408,15 @@ static int av_encode(AVFormatContext **output_files, ...@@ -1291,7 +1408,15 @@ static int av_encode(AVFormatContext **output_files,
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_topBand, frame_bottomBand,
frame_leftBand, frame_rightBand); frame_leftBand, frame_rightBand,
frame_padtop, frame_padbottom,
frame_padleft, frame_padright);
ost->padtop = frame_padtop;
ost->padleft = frame_padleft;
ost->padbottom = frame_padbottom;
ost->padright = frame_padright;
} }
ost->encoding_needed = 1; ost->encoding_needed = 1;
ist->decoding_needed = 1; ist->decoding_needed = 1;
...@@ -1809,6 +1934,93 @@ static void opt_frame_size(const char *arg) ...@@ -1809,6 +1934,93 @@ static void opt_frame_size(const char *arg)
} }
} }
#define SCALEBITS 10
#define ONE_HALF (1 << (SCALEBITS - 1))
#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
#define RGB_TO_Y(r, g, b) \
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
#define RGB_TO_U(r1, g1, b1, shift)\
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_TO_V(r1, g1, b1, shift)\
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
static void opt_pad_color(const char *arg) {
/* Input is expected to be six hex digits similar to
how colors are expressed in html tags (but without the #) */
int rgb = strtol(arg, NULL, 16);
int r,g,b;
r = (rgb >> 16);
g = ((rgb >> 8) & 255);
b = (rgb & 255);
padcolor[0] = RGB_TO_Y(r,g,b);
padcolor[1] = RGB_TO_U(r,g,b,0);
padcolor[2] = RGB_TO_V(r,g,b,0);
}
static void opt_frame_pad_top(const char *arg)
{
frame_padtop = atoi(arg);
if (frame_padtop < 0) {
fprintf(stderr, "Incorrect top pad size\n");
exit(1);
}
if ((frame_padtop % 2) != 0) {
fprintf(stderr, "Top pad size must be a multiple of 2\n");
exit(1);
}
}
static void opt_frame_pad_bottom(const char *arg)
{
frame_padbottom = atoi(arg);
if (frame_padbottom < 0) {
fprintf(stderr, "Incorrect bottom pad size\n");
exit(1);
}
if ((frame_padbottom % 2) != 0) {
fprintf(stderr, "Bottom pad size must be a multiple of 2\n");
exit(1);
}
}
static void opt_frame_pad_left(const char *arg)
{
frame_padleft = atoi(arg);
if (frame_padleft < 0) {
fprintf(stderr, "Incorrect left pad size\n");
exit(1);
}
if ((frame_padleft % 2) != 0) {
fprintf(stderr, "Left pad size must be a multiple of 2\n");
exit(1);
}
}
static void opt_frame_pad_right(const char *arg)
{
frame_padright = atoi(arg);
if (frame_padright < 0) {
fprintf(stderr, "Incorrect right pad size\n");
exit(1);
}
if ((frame_padright % 2) != 0) {
fprintf(stderr, "Right pad size must be a multiple of 2\n");
exit(1);
}
}
static void opt_frame_pix_fmt(const char *arg) static void opt_frame_pix_fmt(const char *arg)
{ {
frame_pix_fmt = avcodec_get_pix_fmt(arg); frame_pix_fmt = avcodec_get_pix_fmt(arg);
...@@ -2237,8 +2449,8 @@ static void opt_input_file(const char *filename) ...@@ -2237,8 +2449,8 @@ static void opt_input_file(const char *filename)
ap->channels = audio_channels; ap->channels = audio_channels;
ap->frame_rate = frame_rate; ap->frame_rate = frame_rate;
ap->frame_rate_base = frame_rate_base; ap->frame_rate_base = frame_rate_base;
ap->width = frame_width; ap->width = frame_width + frame_padleft + frame_padright;
ap->height = frame_height; ap->height = frame_height + frame_padtop + frame_padbottom;
ap->image_format = image_format; ap->image_format = image_format;
ap->pix_fmt = frame_pix_fmt; ap->pix_fmt = frame_pix_fmt;
...@@ -2454,8 +2666,8 @@ static void opt_output_file(const char *filename) ...@@ -2454,8 +2666,8 @@ static void opt_output_file(const char *filename)
video_enc->frame_rate = frame_rate; video_enc->frame_rate = frame_rate;
video_enc->frame_rate_base = frame_rate_base; video_enc->frame_rate_base = frame_rate_base;
video_enc->width = frame_width; video_enc->width = frame_width + frame_padright + frame_padleft;
video_enc->height = frame_height; video_enc->height = frame_height + frame_padtop + frame_padbottom;
video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255); video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
video_enc->pix_fmt = frame_pix_fmt; video_enc->pix_fmt = frame_pix_fmt;
...@@ -3164,6 +3376,11 @@ const OptionDef options[] = { ...@@ -3164,6 +3376,11 @@ const OptionDef options[] = {
{ "cropbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" }, { "cropbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" },
{ "cropleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_left}, "set left crop band size (in pixels)", "size" }, { "cropleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_left}, "set left crop band size (in pixels)", "size" },
{ "cropright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_right}, "set right crop band size (in pixels)", "size" }, { "cropright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_right}, "set right crop band size (in pixels)", "size" },
{ "padtop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_top}, "set top pad band size (in pixels)", "size" },
{ "padbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_bottom}, "set bottom pad band size (in pixels)", "size" },
{ "padleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_left}, "set left pad band size (in pixels)", "size" },
{ "padright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_right}, "set right pad band size (in pixels)", "size" },
{ "padcolor", HAS_ARG | OPT_VIDEO, {(void*)opt_pad_color}, "set color of pad bands (Hex 000000 thru FFFFFF)", "color" },
{ "g", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_gop_size}, "set the group of picture size", "gop_size" }, { "g", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_gop_size}, "set the group of picture size", "gop_size" },
{ "intra", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_only}, "use only intra frames"}, { "intra", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_only}, "use only intra frames"},
{ "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" }, { "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" },
...@@ -3217,7 +3434,7 @@ const OptionDef options[] = { ...@@ -3217,7 +3434,7 @@ const OptionDef options[] = {
{ "bug", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_workaround_bugs}, "workaround not auto detected encoder bugs", "param" }, { "bug", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_workaround_bugs}, "workaround not auto detected encoder bugs", "param" },
{ "ps", HAS_ARG | OPT_EXPERT, {(void*)opt_packet_size}, "set packet size in bits", "size" }, { "ps", HAS_ARG | OPT_EXPERT, {(void*)opt_packet_size}, "set packet size in bits", "size" },
{ "error", HAS_ARG | OPT_EXPERT, {(void*)opt_error_rate}, "error rate", "rate" }, { "error", HAS_ARG | OPT_EXPERT, {(void*)opt_error_rate}, "error rate", "rate" },
{ "strict", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_strict}, "how strictly to follow the standarts", "strictness" }, { "strict", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_strict}, "how strictly to follow the standards", "strictness" },
{ "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, { "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality},
"use same video quality as source (implies VBR)" }, "use same video quality as source (implies VBR)" },
{ "pass", HAS_ARG | OPT_VIDEO, {(void*)&opt_pass}, "select the pass number (1 or 2)", "n" }, { "pass", HAS_ARG | OPT_VIDEO, {(void*)&opt_pass}, "select the pass number (1 or 2)", "n" },
......
...@@ -17,7 +17,7 @@ extern "C" { ...@@ -17,7 +17,7 @@ extern "C" {
#define FFMPEG_VERSION_INT 0x000408 #define FFMPEG_VERSION_INT 0x000408
#define FFMPEG_VERSION "0.4.8" #define FFMPEG_VERSION "0.4.8"
#define LIBAVCODEC_BUILD 4707 #define LIBAVCODEC_BUILD 4708
#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
#define LIBAVCODEC_VERSION FFMPEG_VERSION #define LIBAVCODEC_VERSION FFMPEG_VERSION
...@@ -1821,7 +1821,10 @@ ImgReSampleContext *img_resample_init(int output_width, int output_height, ...@@ -1821,7 +1821,10 @@ ImgReSampleContext *img_resample_init(int output_width, int output_height,
ImgReSampleContext *img_resample_full_init(int owidth, int oheight, ImgReSampleContext *img_resample_full_init(int owidth, int oheight,
int iwidth, int iheight, int iwidth, int iheight,
int topBand, int bottomBand, int topBand, int bottomBand,
int leftBand, int rightBand); int leftBand, int rightBand,
int padtop, int padbottom,
int padleft, int padright);
void img_resample(ImgReSampleContext *s, void img_resample(ImgReSampleContext *s,
AVPicture *output, const AVPicture *input); AVPicture *output, const AVPicture *input);
......
...@@ -45,7 +45,10 @@ ...@@ -45,7 +45,10 @@
#define LINE_BUF_HEIGHT (NB_TAPS * 4) #define LINE_BUF_HEIGHT (NB_TAPS * 4)
struct ImgReSampleContext { struct ImgReSampleContext {
int iwidth, iheight, owidth, oheight, topBand, bottomBand, leftBand, rightBand; int iwidth, iheight, owidth, oheight;
int topBand, bottomBand, leftBand, rightBand;
int padtop, padbottom, padleft, padright;
int pad_owidth, pad_oheight;
int h_incr, v_incr; int h_incr, v_incr;
int16_t h_filters[NB_PHASES][NB_TAPS] __align8; /* horizontal filters */ int16_t h_filters[NB_PHASES][NB_TAPS] __align8; /* horizontal filters */
int16_t v_filters[NB_PHASES][NB_TAPS] __align8; /* vertical filters */ int16_t v_filters[NB_PHASES][NB_TAPS] __align8; /* vertical filters */
...@@ -532,6 +535,7 @@ static void component_resample(ImgReSampleContext *s, ...@@ -532,6 +535,7 @@ static void component_resample(ImgReSampleContext *s,
&s->v_filters[phase_y][0]); &s->v_filters[phase_y][0]);
src_y += s->v_incr; src_y += s->v_incr;
output += owrap; output += owrap;
} }
} }
...@@ -572,13 +576,16 @@ static void build_filter(int16_t *filter, float factor) ...@@ -572,13 +576,16 @@ static void build_filter(int16_t *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); return img_resample_full_init(owidth, oheight, iwidth, iheight,
0, 0, 0, 0, 0, 0, 0, 0);
} }
ImgReSampleContext *img_resample_full_init(int owidth, int oheight, ImgReSampleContext *img_resample_full_init(int owidth, int oheight,
int iwidth, int iheight, int iwidth, int iheight,
int topBand, int bottomBand, int topBand, int bottomBand,
int leftBand, int rightBand) int leftBand, int rightBand,
int padtop, int padbottom,
int padleft, int padright)
{ {
ImgReSampleContext *s; ImgReSampleContext *s;
...@@ -593,19 +600,30 @@ ImgReSampleContext *img_resample_full_init(int owidth, int oheight, ...@@ -593,19 +600,30 @@ ImgReSampleContext *img_resample_full_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->topBand = topBand;
s->bottomBand = bottomBand; s->bottomBand = bottomBand;
s->leftBand = leftBand; s->leftBand = leftBand;
s->rightBand = rightBand; s->rightBand = rightBand;
s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / owidth; s->padtop = padtop;
s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / oheight; s->padbottom = padbottom;
s->padleft = padleft;
build_filter(&s->h_filters[0][0], (float) owidth / (float) (iwidth - leftBand - rightBand)); s->padright = padright;
build_filter(&s->v_filters[0][0], (float) oheight / (float) (iheight - topBand - bottomBand));
s->pad_owidth = owidth - (padleft + padright);
s->pad_oheight = oheight - (padtop + padbottom);
s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth;
s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight;
build_filter(&s->h_filters[0][0], (float) s->pad_owidth /
(float) (iwidth - leftBand - rightBand));
build_filter(&s->v_filters[0][0], (float) s->pad_oheight /
(float) (iheight - topBand - bottomBand));
return s; return s;
fail: fail:
av_free(s); av_free(s);
return NULL; return NULL;
} }
...@@ -614,13 +632,20 @@ void img_resample(ImgReSampleContext *s, ...@@ -614,13 +632,20 @@ void img_resample(ImgReSampleContext *s,
AVPicture *output, const AVPicture *input) AVPicture *output, const AVPicture *input)
{ {
int i, shift; int i, shift;
uint8_t* optr;
for(i=0;i<3;i++) { for (i=0;i<3;i++) {
shift = (i == 0) ? 0 : 1; shift = (i == 0) ? 0 : 1;
component_resample(s, output->data[i], output->linesize[i],
s->owidth >> shift, s->oheight >> shift, optr = output->data[i] + (((output->linesize[i] *
input->data[i] + (input->linesize[i] * (s->topBand >> shift)) + (s->leftBand >> shift), s->padtop) + s->padleft) >> shift);
input->linesize[i], ((s->iwidth - s->leftBand - s->rightBand) >> shift),
component_resample(s, optr, output->linesize[i],
s->pad_owidth >> shift, s->pad_oheight >> shift,
input->data[i] + (input->linesize[i] *
(s->topBand >> shift)) + (s->leftBand >> shift),
input->linesize[i], ((s->iwidth - s->leftBand -
s->rightBand) >> shift),
(s->iheight - s->topBand - s->bottomBand) >> shift); (s->iheight - s->topBand - s->bottomBand) >> shift);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment