You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	FATE: add a test for sliced scaling
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -64,6 +64,8 @@ tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS) | ||||
|  | ||||
| tools/enum_options$(EXESUF): ELIBS = $(FF_EXTRALIBS) | ||||
| tools/enum_options$(EXESUF): $(FF_DEP_LIBS) | ||||
| tools/scale_slice_test$(EXESUF): $(FF_DEP_LIBS) | ||||
| tools/scale_slice_test$(EXESUF): ELIBS = $(FF_EXTRALIBS) | ||||
| tools/sofa2wavs$(EXESUF): ELIBS = $(FF_EXTRALIBS) | ||||
| tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS) | ||||
| tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS) | ||||
|   | ||||
| @@ -221,6 +221,7 @@ $(FATE_FFPROBE) $(FATE_FFMPEG_FFPROBE) $(FATE_SAMPLES_FFPROBE) $(FATE_SAMPLES_FF | ||||
|  | ||||
| $(FATE_SAMPLES_FASTSTART): tools/qt-faststart$(EXESUF) | ||||
| $(FATE_SAMPLES_DUMP_DATA): tools/venc_data_dump$(EXESUF) | ||||
| $(FATE_SAMPLES_SCALE_SLICE): tools/scale_slice_test$(EXESUF) | ||||
|  | ||||
| ifdef SAMPLES | ||||
| FATE += $(FATE_EXTERN) | ||||
|   | ||||
| @@ -6,6 +6,17 @@ FATE_LIBSWSCALE += fate-sws-floatimg-cmp | ||||
| fate-sws-floatimg-cmp: libswscale/tests/floatimg_cmp$(EXESUF) | ||||
| fate-sws-floatimg-cmp: CMD = run libswscale/tests/floatimg_cmp$(EXESUF) | ||||
|  | ||||
| SWS_SLICE_TEST-$(call DEMDEC, MATROSKA, VP9) += fate-sws-slice-yuv422-12bit-rgb48 | ||||
| fate-sws-slice-yuv422-12bit-rgb48: CMD = run tools/scale_slice_test$(EXESUF) $(TARGET_SAMPLES)/vp9-test-vectors/vp93-2-20-12bit-yuv422.webm 150 100 rgb48 | ||||
|  | ||||
| SWS_SLICE_TEST-$(call DEMDEC, IMAGE_BMP_PIPE, BMP) += fate-sws-slice-bgr0-nv12 | ||||
| fate-sws-slice-bgr0-nv12: CMD = run tools/scale_slice_test$(EXESUF) $(TARGET_SAMPLES)/bmp/test32bf.bmp 32 64 nv12 | ||||
|  | ||||
| fate-sws-slice: $(SWS_SLICE_TEST-yes) | ||||
| $(SWS_SLICE_TEST-yes): tools/scale_slice_test$(EXESUF) | ||||
| $(SWS_SLICE_TEST-yes): REF = /dev/null | ||||
| FATE_LIBSWSCALE += $(SWS_SLICE_TEST-yes) | ||||
|  | ||||
| FATE_LIBSWSCALE += $(FATE_LIBSWSCALE-yes) | ||||
| FATE-$(CONFIG_SWSCALE) += $(FATE_LIBSWSCALE) | ||||
| fate-libswscale: $(FATE_LIBSWSCALE) | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| TOOLS = enum_options qt-faststart trasher uncoded_frame | ||||
| TOOLS = enum_options qt-faststart scale_slice_test trasher uncoded_frame | ||||
| TOOLS-$(CONFIG_LIBMYSOFA) += sofa2wavs | ||||
| TOOLS-$(CONFIG_ZLIB) += cws2fws | ||||
|  | ||||
| @@ -18,6 +18,7 @@ tools/target_io_dem_fuzzer.o: tools/target_dem_fuzzer.c | ||||
| 	$(COMPILE_C) -DIO_FLAT=0 | ||||
|  | ||||
| tools/venc_data_dump$(EXESUF): tools/decode_simple.o | ||||
| tools/scale_slice_test$(EXESUF): tools/decode_simple.o | ||||
|  | ||||
| OUTDIRS += tools | ||||
|  | ||||
|   | ||||
							
								
								
									
										190
									
								
								tools/scale_slice_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								tools/scale_slice_test.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | ||||
| /* | ||||
|  * This file is part of FFmpeg. | ||||
|  * | ||||
|  * FFmpeg is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2.1 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * FFmpeg is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with FFmpeg; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "decode_simple.h" | ||||
|  | ||||
| #include "libavutil/common.h" | ||||
| #include "libavutil/pixdesc.h" | ||||
| #include "libavutil/error.h" | ||||
| #include "libavutil/lfg.h" | ||||
| #include "libavutil/random_seed.h" | ||||
| #include "libavutil/video_enc_params.h" | ||||
|  | ||||
| #include "libavformat/avformat.h" | ||||
|  | ||||
| #include "libavcodec/avcodec.h" | ||||
|  | ||||
| #include "libswscale/swscale.h" | ||||
|  | ||||
| typedef struct PrivData { | ||||
|     unsigned int random_seed; | ||||
|     AVLFG        lfg; | ||||
|  | ||||
|     struct SwsContext *scaler; | ||||
|  | ||||
|     int v_shift_dst, h_shift_dst; | ||||
|     int v_shift_src, h_shift_src; | ||||
|  | ||||
|     AVFrame *frame_ref; | ||||
|     AVFrame *frame_dst; | ||||
| } PrivData; | ||||
|  | ||||
| static int process_frame(DecodeContext *dc, AVFrame *frame) | ||||
| { | ||||
|     PrivData *pd = dc->opaque; | ||||
|     int slice_start = 0; | ||||
|     int ret; | ||||
|  | ||||
|     if (!frame) | ||||
|         return 0; | ||||
|  | ||||
|     if (!pd->scaler) { | ||||
|         pd->scaler = sws_getContext(frame->width, frame->height, frame->format, | ||||
|                                     pd->frame_ref->width, pd->frame_ref->height, | ||||
|                                     pd->frame_ref->format, 0, NULL, NULL, NULL); | ||||
|         if (!pd->scaler) | ||||
|             return AVERROR(ENOMEM); | ||||
|  | ||||
|         av_pix_fmt_get_chroma_sub_sample(frame->format, &pd->h_shift_src, &pd->v_shift_src); | ||||
|     } | ||||
|  | ||||
|     /* scale the whole input frame as reference */ | ||||
|     ret = sws_scale(pd->scaler, (const uint8_t **)frame->data, frame->linesize, 0, frame->height, | ||||
|                     pd->frame_ref->data, pd->frame_ref->linesize); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     /* scale slices with randomly generated heights */ | ||||
|     while (slice_start < frame->height) { | ||||
|         int slice_height; | ||||
|         const uint8_t *src[4]; | ||||
|  | ||||
|         slice_height = av_lfg_get(&pd->lfg) % (frame->height - slice_start); | ||||
|         slice_height = FFALIGN(FFMAX(1, slice_height), 1 << pd->v_shift_src); | ||||
|  | ||||
|         for (int j = 0; j < FF_ARRAY_ELEMS(src) && frame->data[j]; j++) { | ||||
|             int shift = (j == 1 || j == 2) ? pd->v_shift_src : 0; | ||||
|             src[j] = frame->data[j] + frame->linesize[j] * (slice_start >> shift); | ||||
|         } | ||||
|  | ||||
|         ret = sws_scale(pd->scaler, src, frame->linesize, slice_start, slice_height, | ||||
|                         pd->frame_dst->data, pd->frame_dst->linesize); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|  | ||||
|         slice_start += slice_height; | ||||
|     } | ||||
|  | ||||
|     /* compare the two results */ | ||||
|     for (int i = 0; i < 4 && pd->frame_ref->data[i]; i++) { | ||||
|         int shift = (i == 1 || i == 2) ? pd->v_shift_dst : 0; | ||||
|  | ||||
|         if (memcmp(pd->frame_ref->data[i], pd->frame_dst->data[i], | ||||
|                    pd->frame_ref->linesize[i] * (pd->frame_ref->height >> shift))) { | ||||
|             fprintf(stderr, "mismatch frame %d seed %u\n", | ||||
|                     dc->decoder->frame_number - 1, pd->random_seed); | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|     PrivData      pd; | ||||
|     DecodeContext dc; | ||||
|  | ||||
|     int width, height; | ||||
|     enum AVPixelFormat pix_fmt; | ||||
|     const char *filename; | ||||
|     int ret = 0; | ||||
|  | ||||
|     if (argc <= 4) { | ||||
|         fprintf(stderr, | ||||
|                 "Usage: %s <input file> <dst width> <dst height> <dst pixfmt> [<random seed>] \n", | ||||
|                 argv[0]); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     memset(&pd, 0, sizeof(pd)); | ||||
|  | ||||
|     filename     = argv[1]; | ||||
|     width        = strtol(argv[2], NULL, 0); | ||||
|     height       = strtol(argv[3], NULL, 0); | ||||
|     pix_fmt      = av_get_pix_fmt(argv[4]); | ||||
|  | ||||
|     /* init RNG for generating slice sizes */ | ||||
|     if (argc >= 6) | ||||
|         pd.random_seed = strtoul(argv[5], NULL, 0); | ||||
|     else | ||||
|         pd.random_seed = av_get_random_seed(); | ||||
|  | ||||
|     av_lfg_init(&pd.lfg, pd.random_seed); | ||||
|  | ||||
|     av_pix_fmt_get_chroma_sub_sample(pix_fmt, &pd.h_shift_dst, &pd.v_shift_dst); | ||||
|  | ||||
|     /* allocate the frames for scaler output */ | ||||
|     for (int i = 0; i < 2; i++) { | ||||
|         AVFrame *frame = av_frame_alloc(); | ||||
|         if (!frame) { | ||||
|             fprintf(stderr, "Error allocating frames\n"); | ||||
|             return AVERROR(ENOMEM); | ||||
|         } | ||||
|  | ||||
|         frame->width  = width; | ||||
|         frame->height = height; | ||||
|         frame->format = pix_fmt; | ||||
|  | ||||
|         ret = av_frame_get_buffer(frame, 0); | ||||
|         if (ret < 0) { | ||||
|             fprintf(stderr, "Error allocating frame data\n"); | ||||
|             return ret; | ||||
|         } | ||||
|  | ||||
|         /* make sure the padding is zeroed */ | ||||
|         for (int j = 0; j < 4 && frame->data[j]; j++) { | ||||
|             int shift = (j == 1 || j == 2) ? pd.v_shift_dst : 0; | ||||
|             memset(frame->data[j], 0, | ||||
|                    frame->linesize[j] * (height >> shift)); | ||||
|         } | ||||
|         if (i) pd.frame_ref = frame; | ||||
|         else   pd.frame_dst = frame; | ||||
|     } | ||||
|  | ||||
|     ret = ds_open(&dc, filename, 0); | ||||
|     if (ret < 0) { | ||||
|         fprintf(stderr, "Error opening the file\n"); | ||||
|         return ret; | ||||
|     } | ||||
|  | ||||
|     dc.process_frame = process_frame; | ||||
|     dc.opaque        = &pd; | ||||
|  | ||||
|     ret = ds_run(&dc); | ||||
|  | ||||
|     av_frame_free(&pd.frame_dst); | ||||
|     av_frame_free(&pd.frame_ref); | ||||
|     sws_freeContext(pd.scaler); | ||||
|     ds_free(&dc); | ||||
|     return ret; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user