提交 34b10a57 编写于 作者: D Dieter 提交者: Michael Niedermayer

crop optmization patch by (Dieter Shirley <dieters at schemasoft dot com>)

Originally committed as revision 1311 to svn://svn.ffmpeg.org/ffmpeg/trunk
上级 8aa1e3da
...@@ -169,9 +169,13 @@ typedef struct AVOutputStream { ...@@ -169,9 +169,13 @@ typedef struct AVOutputStream {
double sync_ipts_offset; double sync_ipts_offset;
INT64 sync_opts; INT64 sync_opts;
/* video only */ /* video only */
AVPicture pict_tmp; /* temporary image for resizing */ int video_resample; /* video_resample and video_crop are mutually exclusive */
int video_resample; AVPicture 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 topBand; /* cropping area sizes */
int leftBand;
/* audio only */ /* audio only */
int audio_resample; int audio_resample;
...@@ -499,12 +503,12 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void ...@@ -499,12 +503,12 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void
static void do_video_out(AVFormatContext *s, static void do_video_out(AVFormatContext *s,
AVOutputStream *ost, AVOutputStream *ost,
AVInputStream *ist, AVInputStream *ist,
AVPicture *picture1, AVPicture *in_picture,
int *frame_size, AVOutputStream *audio_sync) int *frame_size, AVOutputStream *audio_sync)
{ {
int nb_frames, i, ret; int nb_frames, i, ret;
AVPicture *picture, *pict; AVPicture *final_picture, *formatted_picture;
AVPicture picture_tmp1; AVPicture picture_format_temp, picture_crop_temp;
static UINT8 *video_buffer; static UINT8 *video_buffer;
UINT8 *buf = NULL, *buf1 = NULL; UINT8 *buf = NULL, *buf1 = NULL;
AVCodecContext *enc, *dec; AVCodecContext *enc, *dec;
...@@ -583,27 +587,43 @@ static void do_video_out(AVFormatContext *s, ...@@ -583,27 +587,43 @@ static void do_video_out(AVFormatContext *s,
buf = av_malloc(size); buf = av_malloc(size);
if (!buf) if (!buf)
return; return;
pict = &picture_tmp1; formatted_picture = &picture_format_temp;
avpicture_fill(pict, buf, enc->pix_fmt, dec->width, dec->height); avpicture_fill(formatted_picture, buf, enc->pix_fmt, dec->width, dec->height);
if (img_convert(pict, enc->pix_fmt, if (img_convert(formatted_picture, enc->pix_fmt,
picture1, dec->pix_fmt, in_picture, dec->pix_fmt,
dec->width, dec->height) < 0) { dec->width, dec->height) < 0) {
fprintf(stderr, "pixel format conversion not handled\n"); fprintf(stderr, "pixel format conversion not handled\n");
goto the_end; goto the_end;
} }
} else { } else {
pict = picture1; formatted_picture = in_picture;
} }
/* XXX: resampling could be done before raw format convertion in /* XXX: resampling could be done before raw format convertion 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) {
picture = &ost->pict_tmp; final_picture = &ost->pict_tmp;
img_resample(ost->img_resample_ctx, picture, pict); img_resample(ost->img_resample_ctx, final_picture, formatted_picture);
} else if (ost->video_crop) {
picture_crop_temp.data[0] = formatted_picture->data[0] +
(ost->topBand * formatted_picture->linesize[0]) + ost->leftBand;
picture_crop_temp.data[1] = formatted_picture->data[1] +
((ost->topBand >> 1) * formatted_picture->linesize[1]) +
(ost->leftBand >> 1);
picture_crop_temp.data[2] = formatted_picture->data[2] +
((ost->topBand >> 1) * formatted_picture->linesize[2]) +
(ost->leftBand >> 1);
picture_crop_temp.linesize[0] = formatted_picture->linesize[0];
picture_crop_temp.linesize[1] = formatted_picture->linesize[1];
picture_crop_temp.linesize[2] = formatted_picture->linesize[2];
final_picture = &picture_crop_temp;
} else { } else {
picture = pict; final_picture = formatted_picture;
} }
/* duplicates frame if needed */ /* duplicates frame if needed */
/* XXX: pb because no interleaving */ /* XXX: pb because no interleaving */
...@@ -612,7 +632,7 @@ static void do_video_out(AVFormatContext *s, ...@@ -612,7 +632,7 @@ static void do_video_out(AVFormatContext *s,
AVVideoFrame big_picture; AVVideoFrame big_picture;
memset(&big_picture, 0, sizeof(AVVideoFrame)); memset(&big_picture, 0, sizeof(AVVideoFrame));
*(AVPicture*)&big_picture= *picture; *(AVPicture*)&big_picture= *final_picture;
/* handles sameq here. This is not correct because it may /* handles sameq here. This is not correct because it may
not be a global option */ not be a global option */
...@@ -640,9 +660,9 @@ static void do_video_out(AVFormatContext *s, ...@@ -640,9 +660,9 @@ static void do_video_out(AVFormatContext *s,
avoid any copies. We support temorarily the older avoid any copies. We support temorarily the older
method. */ method. */
av_write_frame(s, ost->index, av_write_frame(s, ost->index,
(UINT8 *)picture, sizeof(AVPicture)); (UINT8 *)final_picture, sizeof(AVPicture));
} else { } else {
write_picture(s, ost->index, picture, enc->pix_fmt, write_picture(s, ost->index, final_picture, enc->pix_fmt,
enc->width, enc->height); enc->width, enc->height);
} }
} }
...@@ -966,11 +986,27 @@ static int av_encode(AVFormatContext **output_files, ...@@ -966,11 +986,27 @@ static int av_encode(AVFormatContext **output_files,
break; break;
case CODEC_TYPE_VIDEO: case CODEC_TYPE_VIDEO:
if (codec->width == icodec->width && if (codec->width == icodec->width &&
codec->height == icodec->height) { codec->height == icodec->height &&
frame_topBand == 0 &&
frame_bottomBand == 0 &&
frame_leftBand == 0 &&
frame_rightBand == 0)
{
ost->video_resample = 0;
ost->video_crop = 0;
} else if ((codec->width == icodec->width -
(frame_leftBand + frame_rightBand)) &&
(codec->height == icodec->height -
(frame_topBand + frame_bottomBand)))
{
ost->video_resample = 0; ost->video_resample = 0;
ost->video_crop = 1;
ost->topBand = frame_topBand;
ost->leftBand = frame_leftBand;
} else { } else {
UINT8 *buf; UINT8 *buf;
ost->video_resample = 1; ost->video_resample = 1;
ost->video_crop = 0; // cropping is handled as part of resample
buf = av_malloc((codec->width * codec->height * 3) / 2); buf = av_malloc((codec->width * codec->height * 3) / 2);
if (!buf) if (!buf)
goto fail; goto fail;
...@@ -1196,7 +1232,7 @@ static int av_encode(AVFormatContext **output_files, ...@@ -1196,7 +1232,7 @@ static int av_encode(AVFormatContext **output_files,
av_hex_dump(pkt.data, pkt.size); av_hex_dump(pkt.data, pkt.size);
} }
// printf("read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size); // printf("read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);
len = pkt.size; len = pkt.size;
ptr = pkt.data; ptr = pkt.data;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册