Commit 07d0cdfc authored by Luca Abeni's avatar Luca Abeni

Make cropping, padding, and rescaling independent (after this patch,

the cropping / padding code in img_resample() is not needed anymore)

Originally committed as revision 5279 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 5341c209
...@@ -267,15 +267,15 @@ typedef struct AVOutputStream { ...@@ -267,15 +267,15 @@ typedef struct AVOutputStream {
struct AVInputStream *sync_ist; /* input stream to sync against */ struct AVInputStream *sync_ist; /* input stream to sync against */
int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number
/* video only */ /* video only */
int video_resample; /* video_resample and video_crop are mutually exclusive */ int video_resample;
AVFrame pict_tmp; /* temporary image for resampling */ AVFrame pict_tmp; /* temporary image for resampling */
ImgReSampleContext *img_resample_ctx; /* for image resampling */ ImgReSampleContext *img_resample_ctx; /* for image resampling */
int video_crop; /* video_resample and video_crop are mutually exclusive */ int video_crop;
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 video_pad;
int padtop; /* padding area sizes */ int padtop; /* padding area sizes */
int padbottom; int padbottom;
int padleft; int padleft;
...@@ -704,14 +704,15 @@ static void do_video_out(AVFormatContext *s, ...@@ -704,14 +704,15 @@ static void do_video_out(AVFormatContext *s,
int *frame_size) int *frame_size)
{ {
int nb_frames, i, ret; int nb_frames, i, ret;
AVFrame *final_picture, *formatted_picture; AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src;
AVFrame picture_format_temp, picture_crop_temp; AVFrame picture_format_temp, picture_crop_temp, picture_pad_temp;
uint8_t *buf = NULL, *buf1 = NULL; uint8_t *buf = NULL, *buf1 = NULL;
AVCodecContext *enc, *dec; AVCodecContext *enc, *dec;
enum PixelFormat target_pixfmt; enum PixelFormat target_pixfmt;
avcodec_get_frame_defaults(&picture_format_temp); avcodec_get_frame_defaults(&picture_format_temp);
avcodec_get_frame_defaults(&picture_crop_temp); avcodec_get_frame_defaults(&picture_crop_temp);
avcodec_get_frame_defaults(&picture_pad_temp);
enc = ost->st->codec; enc = ost->st->codec;
dec = ist->st->codec; dec = ist->st->codec;
...@@ -772,14 +773,38 @@ static void do_video_out(AVFormatContext *s, ...@@ -772,14 +773,38 @@ static void do_video_out(AVFormatContext *s,
formatted_picture = in_picture; formatted_picture = in_picture;
} }
if (ost->video_crop) {
if (img_crop((AVPicture *)&picture_crop_temp, (AVPicture *)formatted_picture, target_pixfmt, ost->topBand, ost->leftBand) < 0) {
av_log(NULL, AV_LOG_ERROR, "error cropping picture\n");
goto the_end;
}
formatted_picture = &picture_crop_temp;
}
final_picture = formatted_picture;
padding_src = formatted_picture;
resampling_dst = &ost->pict_tmp;
if (ost->video_pad) {
final_picture = &ost->pict_tmp;
if (ost->video_resample) {
if (img_crop((AVPicture *)&picture_pad_temp, (AVPicture *)final_picture, target_pixfmt, ost->padtop, ost->padleft) < 0) {
av_log(NULL, AV_LOG_ERROR, "error padding picture\n");
goto the_end;
}
resampling_dst = &picture_pad_temp;
}
}
/* XXX: resampling could be done before raw format conversion 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) {
padding_src = NULL;
final_picture = &ost->pict_tmp; final_picture = &ost->pict_tmp;
img_resample(ost->img_resample_ctx, (AVPicture*)final_picture, (AVPicture*)formatted_picture); img_resample(ost->img_resample_ctx, (AVPicture *)resampling_dst, (AVPicture*)formatted_picture);
}
if (enc->pix_fmt != PIX_FMT_YUV420P) { if (enc->pix_fmt != target_pixfmt) {
int size; int size;
av_free(buf); av_free(buf);
...@@ -792,7 +817,7 @@ static void do_video_out(AVFormatContext *s, ...@@ -792,7 +817,7 @@ static void do_video_out(AVFormatContext *s,
avpicture_fill((AVPicture*)final_picture, buf, enc->pix_fmt, enc->width, enc->height); avpicture_fill((AVPicture*)final_picture, buf, enc->pix_fmt, enc->width, enc->height);
if (img_convert((AVPicture*)final_picture, enc->pix_fmt, if (img_convert((AVPicture*)final_picture, enc->pix_fmt,
(AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P, (AVPicture*)&ost->pict_tmp, target_pixfmt,
enc->width, enc->height) < 0) { enc->width, enc->height) < 0) {
if (verbose >= 0) if (verbose >= 0)
...@@ -801,28 +826,13 @@ static void do_video_out(AVFormatContext *s, ...@@ -801,28 +826,13 @@ static void do_video_out(AVFormatContext *s,
goto the_end; goto the_end;
} }
} }
if (ost->padtop || ost->padbottom || ost->padleft || ost->padright) {
img_pad((AVPicture*)final_picture, NULL, enc->height, enc->width, enc->pix_fmt, if (ost->video_pad) {
ost->padtop, ost->padbottom, ost->padleft, ost->padright, img_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
padcolor);
}
} else if (ost->video_crop) {
if (img_crop((AVPicture *)&picture_crop_temp, (AVPicture *)formatted_picture, enc->pix_fmt, ost->topBand, ost->leftBand) < 0) {
av_log(NULL, AV_LOG_ERROR, "error cropping picture\n");
goto the_end;
}
final_picture = &picture_crop_temp;
} else if (ost->video_pad) {
final_picture = &ost->pict_tmp;
if (img_pad((AVPicture*)final_picture, (AVPicture*)formatted_picture,
enc->height, enc->width, enc->pix_fmt, enc->height, enc->width, enc->pix_fmt,
ost->padtop, ost->padbottom, ost->padleft, ost->padright, padcolor) < 0) { ost->padtop, ost->padbottom, ost->padleft, ost->padright, padcolor);
av_log(NULL, AV_LOG_ERROR, "error padding picture\n");
goto the_end;
}
} else {
final_picture = formatted_picture;
} }
/* duplicates frame if needed */ /* duplicates frame if needed */
for(i=0;i<nb_frames;i++) { for(i=0;i<nb_frames;i++) {
AVPacket pkt; AVPacket pkt;
...@@ -1663,25 +1673,25 @@ static int av_encode(AVFormatContext **output_files, ...@@ -1663,25 +1673,25 @@ static int av_encode(AVFormatContext **output_files,
goto fail; 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 = ((frame_leftBand + frame_rightBand + frame_topBand + frame_bottomBand) != 0);
ost->video_pad = ((frame_padleft + frame_padright + frame_padtop + frame_padbottom) != 0);
avcodec_get_frame_defaults(&ost->pict_tmp); avcodec_get_frame_defaults(&ost->pict_tmp);
if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P, if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P,
codec->width, codec->height ) ) codec->width, codec->height ) )
goto fail; goto fail;
ost->img_resample_ctx = img_resample_full_init( ost->img_resample_ctx = img_resample_init(
codec->width, codec->height, codec->width - (frame_padleft + frame_padright),
icodec->width, icodec->height, codec->height - (frame_padtop + frame_padbottom),
frame_topBand, frame_bottomBand, icodec->width - (frame_leftBand + frame_rightBand),
frame_leftBand, frame_rightBand, icodec->height - (frame_topBand + frame_bottomBand));
frame_padtop, frame_padbottom,
frame_padleft, frame_padright);
ost->padtop = frame_padtop; ost->padtop = frame_padtop;
ost->padleft = frame_padleft; ost->padleft = frame_padleft;
ost->padbottom = frame_padbottom; ost->padbottom = frame_padbottom;
ost->padright = frame_padright; ost->padright = frame_padright;
ost->topBand = frame_topBand;
ost->leftBand = frame_leftBand;
} }
ost->encoding_needed = 1; ost->encoding_needed = 1;
ist->decoding_needed = 1; ist->decoding_needed = 1;
......
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