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
This commit is contained in:
parent
929a0c41d5
commit
1ff93ffcd4
@ -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
|
||||||
|
235
ffmpeg.c
235
ffmpeg.c
@ -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 {
|
|||||||
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
|
|||||||
/* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#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)
|
|||||||
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)
|
|||||||
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[] = {
|
|||||||
{ "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[] = {
|
|||||||
{ "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" {
|
|||||||
|
|
||||||
#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,
|
|||||||
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 @@
|
|||||||
#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,
|
|||||||
&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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user