Baptiste COUDURIER's padding patch (reworked by me a little bit).
Moves padding code to imgconvert.c, and enables padding colorspaces != YUV420P. Originally committed as revision 5278 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
							parent
							
								
									7b98bcbd0f
								
							
						
					
					
						commit
						5341c20954
					
				
							
								
								
									
										99
									
								
								ffmpeg.c
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								ffmpeg.c
									
									
									
									
									
								
							| @ -642,39 +642,6 @@ 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) - 1) >> shift); y++) { |  | ||||||
|                 memset(optr, color[i], (padleft + padright) >> shift); |  | ||||||
|                 optr += img->linesize[i]; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (padbottom || padright) { |  | ||||||
|             optr = img->data[i] + (((img->linesize[i] * (height - padbottom)) - padright) >> shift); |  | ||||||
|             memset(optr, color[i], (((img->linesize[i] * padbottom) + padright) >> shift)); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void do_subtitle_out(AVFormatContext *s, | static void do_subtitle_out(AVFormatContext *s, | ||||||
|                             AVOutputStream *ost, |                             AVOutputStream *ost, | ||||||
|                             AVInputStream *ist, |                             AVInputStream *ist, | ||||||
| @ -780,8 +747,7 @@ static void do_video_out(AVFormatContext *s, | |||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     /* convert pixel format if needed */ |     /* convert pixel format if needed */ | ||||||
|     target_pixfmt = ost->video_resample || ost->video_pad |     target_pixfmt = ost->video_resample ? PIX_FMT_YUV420P : enc->pix_fmt; | ||||||
|         ? PIX_FMT_YUV420P : enc->pix_fmt; |  | ||||||
|     if (dec->pix_fmt != target_pixfmt) { |     if (dec->pix_fmt != target_pixfmt) { | ||||||
|         int size; |         int size; | ||||||
| 
 | 
 | ||||||
| @ -813,12 +779,6 @@ static void do_video_out(AVFormatContext *s, | |||||||
|         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*)final_picture, (AVPicture*)formatted_picture); | ||||||
| 
 | 
 | ||||||
|         if (ost->padtop || ost->padbottom || ost->padleft || ost->padright) { |  | ||||||
|             fill_pad_region((AVPicture*)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; | ||||||
| 
 | 
 | ||||||
| @ -841,6 +801,11 @@ 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, | ||||||
|  |                     ost->padtop, ost->padbottom, ost->padleft, ost->padright, | ||||||
|  |                     padcolor); | ||||||
|  |         } | ||||||
|     } else if (ost->video_crop) { |     } else if (ost->video_crop) { | ||||||
|         if (img_crop((AVPicture *)&picture_crop_temp, (AVPicture *)formatted_picture, enc->pix_fmt, ost->topBand, ost->leftBand) < 0) { |         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"); |             av_log(NULL, AV_LOG_ERROR, "error cropping picture\n"); | ||||||
| @ -849,51 +814,11 @@ static void do_video_out(AVFormatContext *s, | |||||||
|         final_picture = &picture_crop_temp; |         final_picture = &picture_crop_temp; | ||||||
|     } else if (ost->video_pad) { |     } else if (ost->video_pad) { | ||||||
|         final_picture = &ost->pict_tmp; |         final_picture = &ost->pict_tmp; | ||||||
| 
 |         if (img_pad((AVPicture*)final_picture, (AVPicture*)formatted_picture, | ||||||
|         for (i = 0; i < 3; i++) { |                     enc->height, enc->width, enc->pix_fmt, | ||||||
|             uint8_t *optr, *iptr; |                     ost->padtop, ost->padbottom, ost->padleft, ost->padright, padcolor) < 0) { | ||||||
|             int shift = (i == 0) ? 0 : 1; |             av_log(NULL, AV_LOG_ERROR, "error padding picture\n"); | ||||||
|             int y, yheight; |             goto the_end; | ||||||
| 
 |  | ||||||
|             /* 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((AVPicture*)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((AVPicture*)final_picture, buf, enc->pix_fmt, enc->width, enc->height); |  | ||||||
| 
 |  | ||||||
|             if (img_convert((AVPicture*)final_picture, enc->pix_fmt, |  | ||||||
|                         (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P, |  | ||||||
|                         enc->width, enc->height) < 0) { |  | ||||||
| 
 |  | ||||||
|                 if (verbose >= 0) |  | ||||||
|                     fprintf(stderr, "pixel format conversion not handled\n"); |  | ||||||
| 
 |  | ||||||
|                 goto the_end; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
|         final_picture = formatted_picture; |         final_picture = formatted_picture; | ||||||
| @ -1733,7 +1658,7 @@ static int av_encode(AVFormatContext **output_files, | |||||||
|                     ost->padbottom = frame_padbottom; |                     ost->padbottom = frame_padbottom; | ||||||
|                     ost->padright = frame_padright; |                     ost->padright = frame_padright; | ||||||
|                     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, codec->pix_fmt, | ||||||
|                                 codec->width, codec->height ) ) |                                 codec->width, codec->height ) ) | ||||||
|                         goto fail; |                         goto fail; | ||||||
|                 } else { |                 } else { | ||||||
|  | |||||||
| @ -2521,6 +2521,9 @@ void img_copy(AVPicture *dst, const AVPicture *src, | |||||||
| int img_crop(AVPicture *dst, const AVPicture *src, | int img_crop(AVPicture *dst, const AVPicture *src, | ||||||
|              int pix_fmt, int top_band, int left_band); |              int pix_fmt, int top_band, int left_band); | ||||||
| 
 | 
 | ||||||
|  | int img_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, | ||||||
|  |             int padtop, int padbottom, int padleft, int padright, int *color); | ||||||
|  | 
 | ||||||
| /* av_log API */ | /* av_log API */ | ||||||
| 
 | 
 | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
|  | |||||||
| @ -1998,6 +1998,56 @@ int img_crop(AVPicture *dst, const AVPicture *src, | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Pad image | ||||||
|  |  */ | ||||||
|  | int img_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, | ||||||
|  |             int padtop, int padbottom, int padleft, int padright, int *color) | ||||||
|  | { | ||||||
|  |     uint8_t *optr, *iptr; | ||||||
|  |     int y_shift; | ||||||
|  |     int x_shift; | ||||||
|  |     int yheight; | ||||||
|  |     int i, y; | ||||||
|  | 
 | ||||||
|  |     if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) | ||||||
|  |         return -1; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < 3; i++) { | ||||||
|  |         x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0; | ||||||
|  |         y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0; | ||||||
|  | 
 | ||||||
|  |         if (padtop || padleft) { | ||||||
|  |             memset(dst->data[i], color[i], dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (padleft || padright || src) { | ||||||
|  |             if (src) { /* first line */ | ||||||
|  |                 iptr = src->data[i]; | ||||||
|  |                 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift); | ||||||
|  |                 memcpy(optr, iptr, src->linesize[i]); | ||||||
|  |                 iptr += src->linesize[i]; | ||||||
|  |             } | ||||||
|  |             optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (dst->linesize[i] - (padright >> x_shift)); | ||||||
|  |             yheight = (height - 1 - (padtop + padbottom)) >> y_shift; | ||||||
|  |             for (y = 0; y < yheight; y++) { | ||||||
|  |                 memset(optr, color[i], (padleft + padright) >> x_shift); | ||||||
|  |                 if (src) { | ||||||
|  |                     memcpy(optr + ((padleft + padright) >> x_shift), iptr, src->linesize[i]); | ||||||
|  |                     iptr += src->linesize[i]; | ||||||
|  |                 } | ||||||
|  |                 optr += dst->linesize[i]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (padbottom || padright) { | ||||||
|  |             optr = dst->data[i] + dst->linesize[i] * ((height - padbottom) >> y_shift) - (padright >> x_shift); | ||||||
|  |             memset(optr, color[i], dst->linesize[i] * (padbottom >> y_shift) + (padright >> x_shift)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* XXX: always use linesize. Return -1 if not supported */ | /* XXX: always use linesize. Return -1 if not supported */ | ||||||
| int img_convert(AVPicture *dst, int dst_pix_fmt, | int img_convert(AVPicture *dst, int dst_pix_fmt, | ||||||
|                 const AVPicture *src, int src_pix_fmt, |                 const AVPicture *src, int src_pix_fmt, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user