You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
5.8 KiB
219 lines
5.8 KiB
/*
|
|
* H.265 video codec.
|
|
* Copyright (c) 2015 struktur AG, Dirk Farin <farin@struktur.de>
|
|
*
|
|
* This file is part of libde265.
|
|
*
|
|
* libde265 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* libde265 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with libde265. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <getopt.h>
|
|
|
|
#include <string>
|
|
#include <stack>
|
|
#include <memory>
|
|
|
|
#include "libde265/image.h"
|
|
#include "libde265/fallback-dct.h"
|
|
#include "libde265/image-io.h"
|
|
|
|
#include "acceleration-speed.h"
|
|
|
|
|
|
/* TODO: for more realistic input to IDCTs, we could save the real coefficients in
|
|
a decoder run and use this data as input.
|
|
*/
|
|
|
|
|
|
bool show_help=false;
|
|
bool do_check=false;
|
|
bool do_time=false;
|
|
bool do_eval=false;
|
|
int img_width=352;
|
|
int img_height=288;
|
|
int nframes=1000;
|
|
int repeat=10;
|
|
std::string function;
|
|
std::string input_file;
|
|
|
|
static struct option long_options[] = {
|
|
{"help", no_argument, 0, 'H' },
|
|
{"input", required_argument, 0, 'i' },
|
|
{"width", required_argument, 0, 'w' },
|
|
{"height", required_argument, 0, 'h' },
|
|
{"nframes", required_argument, 0, 'n' },
|
|
{"function",required_argument, 0, 'f' },
|
|
{"check", no_argument, 0, 'c' },
|
|
{"time", no_argument, 0, 't' },
|
|
{"eval", no_argument, 0, 'e' },
|
|
{"repeat", required_argument, 0, 'r' },
|
|
{0, 0, 0, 0 }
|
|
};
|
|
|
|
|
|
|
|
DSPFunc* DSPFunc::first = NULL;
|
|
|
|
|
|
bool DSPFunc::runOnImage(std::shared_ptr<const de265_image> img, bool compareToReference)
|
|
{
|
|
int w = img->get_width(0);
|
|
int h = img->get_height(0);
|
|
|
|
int blkWidth = getBlkWidth();
|
|
int blkHeight = getBlkHeight();
|
|
|
|
bool success = true;
|
|
|
|
for (int y=0;y<=h-blkHeight;y+=blkHeight)
|
|
for (int x=0;x<=w-blkWidth;x+=blkWidth) {
|
|
runOnBlock(x,y);
|
|
|
|
if (compareToReference) {
|
|
referenceImplementation()->runOnBlock(x,y);
|
|
success &= compareToReferenceImplementation();
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
while (1) {
|
|
int option_index = 0;
|
|
|
|
int c = getopt_long(argc, argv, "Hci:w:h:n:f:ter:", long_options, &option_index);
|
|
if (c == -1)
|
|
break;
|
|
|
|
switch (c) {
|
|
case 'H': show_help=true; break;
|
|
case 'c': do_check=true; break;
|
|
case 'w': img_width =atoi(optarg); break;
|
|
case 'h': img_height=atoi(optarg); break;
|
|
case 'n': nframes=atoi(optarg); break;
|
|
case 'f': function=optarg; break;
|
|
case 'i': input_file=optarg; break;
|
|
case 't': do_time=true; break;
|
|
case 'e': do_eval=true; break;
|
|
case 'r': repeat=atoi(optarg); break;
|
|
}
|
|
}
|
|
|
|
|
|
if (show_help) {
|
|
fprintf(stderr,
|
|
"acceleration-speed SIMD DSP function testing tool\n"
|
|
"--------------------------------------------------\n"
|
|
" --help show help\n"
|
|
" -i, --input NAME input YUV file\n"
|
|
" -w, --width # input width (default: 352)\n"
|
|
" -h, --height # input height (default: 288)\n"
|
|
" -n, --nframes # number of frames to process (default: 1000)\n"
|
|
" -f, --function NAME which function to test (see below)\n"
|
|
" -r, --repeat # number of repetitions for each image (default: 10)\n"
|
|
" -c, --check compare function result against its reference code\n"
|
|
"\n"
|
|
"these functions are known:\n"
|
|
);
|
|
|
|
std::stack<const char*> funcnames;
|
|
|
|
for (DSPFunc* func = DSPFunc::first;
|
|
func ;
|
|
func=func->next) {
|
|
funcnames.push(func->name());
|
|
}
|
|
|
|
while (!funcnames.empty()) {
|
|
fprintf(stderr,
|
|
" %s\n", funcnames.top());
|
|
funcnames.pop();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// --- find DSP function with the given name ---
|
|
|
|
if (function.empty()) {
|
|
fprintf(stderr,"No function specified. Use option '--function'.\n");
|
|
exit(10);
|
|
}
|
|
|
|
DSPFunc* algo = NULL;
|
|
for (DSPFunc* f = DSPFunc::first; f ; f=f->next) {
|
|
if (strcasecmp(f->name(), function.c_str())==0) {
|
|
algo = f;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (algo==NULL) {
|
|
fprintf(stderr,"Argument to '--function' invalid. No function with that name.\n");
|
|
exit(10);
|
|
}
|
|
|
|
if (do_check && !algo->referenceImplementation()) {
|
|
fprintf(stderr,"cannot check function result: no reference function defined for the selected function.\n");
|
|
exit(10);
|
|
}
|
|
|
|
|
|
ImageSource_YUV image_source;
|
|
image_source.set_input_file(input_file.c_str(), img_width, img_height);
|
|
|
|
int img_counter=0;
|
|
|
|
bool eof = false;
|
|
for (int f=0; f<nframes ; f++)
|
|
{
|
|
std::shared_ptr<de265_image> image(image_source.get_image());
|
|
if (!image) {
|
|
eof=true;
|
|
break;
|
|
}
|
|
|
|
img_counter++;
|
|
|
|
if (algo->referenceImplementation()) {
|
|
algo->referenceImplementation()->prepareNextImage(image);
|
|
}
|
|
|
|
if (algo->prepareNextImage(image)) {
|
|
printf("run %d times on image %d\n",repeat,img_counter);
|
|
|
|
for (int r=0;r<repeat;r++) {
|
|
bool success = algo->runOnImage(image, do_check);
|
|
if (!success) {
|
|
fprintf(stderr, "computation mismatch to reference implementation...\n");
|
|
exit(10);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|