Home | History | Annotate | Download | only in test_framework
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/modules/video_coding/codecs/test_framework/video_source.h"
     12 
     13 #include <stdio.h>
     14 
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "webrtc/test/testsupport/fileutils.h"
     17 
     18 VideoSource::VideoSource()
     19 :
     20 _fileName(webrtc::test::ProjectRootPath() + "resources/foreman_cif.yuv"),
     21 _width(352),
     22 _height(288),
     23 _type(webrtc::kI420),
     24 _frameRate(30)
     25 {
     26 }
     27 
     28 VideoSource::VideoSource(std::string fileName, VideoSize size,
     29     int frameRate /*= 30*/, webrtc::VideoType type /*=  webrtc::kI420*/)
     30 :
     31 _fileName(fileName),
     32 _type(type),
     33 _frameRate(frameRate)
     34 {
     35     assert(size != kUndefined && size != kNumberOfVideoSizes);
     36     assert(type != webrtc::kUnknown);
     37     assert(frameRate > 0);
     38     if (GetWidthHeight(size, _width, _height) != 0) {
     39         assert(false);
     40     }
     41 }
     42 
     43 VideoSource::VideoSource(std::string fileName, int width, int height,
     44     int frameRate /*= 30*/,  webrtc::VideoType type /*=  webrtc::kI420*/)
     45 :
     46 _fileName(fileName),
     47 _width(width),
     48 _height(height),
     49 _type(type),
     50 _frameRate(frameRate)
     51 {
     52     assert(width > 0);
     53     assert(height > 0);
     54     assert(type != webrtc::kUnknown);
     55     assert(frameRate > 0);
     56 }
     57 
     58 VideoSize
     59 VideoSource::GetSize() const
     60 {
     61     return GetSize(_width, _height);
     62 }
     63 
     64 VideoSize
     65 VideoSource::GetSize(uint16_t width, uint16_t height)
     66 {
     67     if(width == 128 && height == 96)
     68     {
     69         return kSQCIF;
     70     }else if(width == 160 && height == 120)
     71     {
     72         return kQQVGA;
     73     }else if(width == 176 && height == 144)
     74     {
     75         return kQCIF;
     76     }else if(width == 320 && height == 240)
     77     {
     78         return kQVGA;
     79     }else if(width == 352 && height == 288)
     80     {
     81         return kCIF;
     82     }else if(width == 640 && height == 480)
     83     {
     84         return kVGA;
     85     }else if(width == 720 && height == 480)
     86     {
     87         return kNTSC;
     88     }else if(width == 704 && height == 576)
     89     {
     90         return k4CIF;
     91     }else if(width == 800 && height == 600)
     92     {
     93         return kSVGA;
     94     }else if(width == 960 && height == 720)
     95     {
     96         return kHD;
     97     }else if(width == 1024 && height == 768)
     98     {
     99         return kXGA;
    100     }else if(width == 1440 && height == 1080)
    101     {
    102         return kFullHD;
    103     }else if(width == 400 && height == 240)
    104     {
    105         return kWQVGA;
    106     }else if(width == 800 && height == 480)
    107     {
    108         return kWVGA;
    109     }else if(width == 1280 && height == 720)
    110     {
    111         return kWHD;
    112     }else if(width == 1920 && height == 1080)
    113     {
    114         return kWFullHD;
    115     }
    116     return kUndefined;
    117 }
    118 
    119 unsigned int
    120 VideoSource::GetFrameLength() const
    121 {
    122     return webrtc::CalcBufferSize(_type, _width, _height);
    123 }
    124 
    125 const char*
    126 VideoSource::GetMySizeString() const
    127 {
    128     return VideoSource::GetSizeString(GetSize());
    129 }
    130 
    131 const char*
    132 VideoSource::GetSizeString(VideoSize size)
    133 {
    134     switch (size)
    135     {
    136         case kSQCIF:
    137             return "SQCIF";
    138         case kQQVGA:
    139             return "QQVGA";
    140         case kQCIF:
    141             return "QCIF";
    142         case kQVGA:
    143             return "QVGA";
    144         case kCIF:
    145             return "CIF";
    146         case kVGA:
    147             return "VGA";
    148         case kNTSC:
    149             return "NTSC";
    150         case k4CIF:
    151             return "4CIF";
    152         case kSVGA:
    153             return "SVGA";
    154         case kHD:
    155             return "HD";
    156         case kXGA:
    157             return "XGA";
    158         case kFullHD:
    159             return "Full_HD";
    160         case kWQVGA:
    161             return "WQVGA";
    162         case kWHD:
    163             return "WHD";
    164         case kWFullHD:
    165             return "WFull_HD";
    166         default:
    167             return "Undefined";
    168     }
    169 }
    170 
    171 std::string
    172 VideoSource::GetFilePath() const
    173 {
    174     size_t slashPos = _fileName.find_last_of("/\\");
    175     if (slashPos == std::string::npos)
    176     {
    177         return ".";
    178     }
    179 
    180     return _fileName.substr(0, slashPos);
    181 }
    182 
    183 std::string
    184 VideoSource::GetName() const
    185 {
    186     // Remove path.
    187     size_t slashPos = _fileName.find_last_of("/\\");
    188     if (slashPos == std::string::npos)
    189     {
    190         slashPos = 0;
    191     }
    192     else
    193     {
    194         slashPos++;
    195     }
    196 
    197     // Remove extension and underscored suffix if it exists.
    198     return _fileName.substr(slashPos, std::min(_fileName.find_last_of("_"),
    199         _fileName.find_last_of(".")) - slashPos);
    200 }
    201 
    202 void
    203 VideoSource::Convert(const VideoSource &target, bool force /* = false */) const
    204 {
    205     // Ensure target rate is less than or equal to source
    206     // (i.e. we are only temporally downsampling).
    207     ASSERT_TRUE(target.GetFrameRate() <= _frameRate);
    208     // Only supports YUV420 currently.
    209     ASSERT_TRUE(_type == webrtc::kI420 && target.GetType() == webrtc::kI420);
    210     if (!force && (FileExists(target.GetFileName().c_str()) ||
    211         (target.GetWidth() == _width && target.GetHeight() == _height && target.GetFrameRate() == _frameRate)))
    212     {
    213         // Assume that the filename uniquely defines the content.
    214         // If the file already exists, it is the correct file.
    215         return;
    216     }
    217     FILE *inFile = NULL;
    218     FILE *outFile = NULL;
    219 
    220     inFile = fopen(_fileName.c_str(), "rb");
    221     ASSERT_TRUE(inFile != NULL);
    222 
    223     outFile = fopen(target.GetFileName().c_str(), "wb");
    224     ASSERT_TRUE(outFile != NULL);
    225 
    226     FrameDropper fd;
    227     fd.SetFrameRate(target.GetFrameRate(), _frameRate);
    228 
    229     const size_t lengthOutFrame = webrtc::CalcBufferSize(target.GetType(),
    230         target.GetWidth(), target.GetHeight());
    231     ASSERT_TRUE(lengthOutFrame > 0);
    232     unsigned char *outFrame = new unsigned char[lengthOutFrame];
    233 
    234     const size_t lengthInFrame = webrtc::CalcBufferSize(_type, _width, _height);
    235     ASSERT_TRUE(lengthInFrame > 0);
    236     unsigned char *inFrame = new unsigned char[lengthInFrame];
    237 
    238     while (fread(inFrame, 1, lengthInFrame, inFile) == lengthInFrame)
    239     {
    240         if (!fd.DropFrame())
    241         {
    242             ASSERT_TRUE(target.GetWidth() == _width &&
    243                    target.GetHeight() == _height);
    244             // Add video interpolator here!
    245             if (fwrite(outFrame, 1, lengthOutFrame,
    246                        outFile) !=  lengthOutFrame) {
    247               return;
    248             }
    249         }
    250     }
    251 
    252     delete inFrame;
    253     delete outFrame;
    254     fclose(inFile);
    255     fclose(outFile);
    256 }
    257 
    258 bool VideoSource::FileExists(const char* fileName)
    259 {
    260     FILE* fp = NULL;
    261     fp = fopen(fileName, "rb");
    262     if(fp != NULL)
    263     {
    264         fclose(fp);
    265         return true;
    266     }
    267     return false;
    268 }
    269 
    270 
    271 int
    272 VideoSource::GetWidthHeight( VideoSize size, int & width, int& height)
    273 {
    274     switch(size)
    275     {
    276     case kSQCIF:
    277         width = 128;
    278         height = 96;
    279         return 0;
    280     case kQQVGA:
    281         width = 160;
    282         height = 120;
    283         return 0;
    284     case kQCIF:
    285         width = 176;
    286         height = 144;
    287         return 0;
    288     case kCGA:
    289         width = 320;
    290         height = 200;
    291         return 0;
    292     case kQVGA:
    293         width = 320;
    294         height = 240;
    295         return 0;
    296     case kSIF:
    297         width = 352;
    298         height = 240;
    299         return 0;
    300     case kWQVGA:
    301         width = 400;
    302         height = 240;
    303         return 0;
    304     case kCIF:
    305         width = 352;
    306         height = 288;
    307         return 0;
    308     case kW288p:
    309         width = 512;
    310         height = 288;
    311         return 0;
    312     case k448p:
    313         width = 576;
    314         height = 448;
    315         return 0;
    316     case kVGA:
    317         width = 640;
    318         height = 480;
    319         return 0;
    320     case k432p:
    321         width = 720;
    322         height = 432;
    323         return 0;
    324     case kW432p:
    325         width = 768;
    326         height = 432;
    327         return 0;
    328     case k4SIF:
    329         width = 704;
    330         height = 480;
    331         return 0;
    332     case kW448p:
    333         width = 768;
    334         height = 448;
    335         return 0;
    336     case kNTSC:
    337         width = 720;
    338         height = 480;
    339         return 0;
    340     case kFW448p:
    341         width = 800;
    342         height = 448;
    343         return 0;
    344     case kWVGA:
    345         width = 800;
    346         height = 480;
    347         return 0;
    348     case k4CIF:
    349         width = 704;
    350         height = 576;
    351         return 0;
    352     case kSVGA:
    353         width = 800;
    354         height = 600;
    355         return 0;
    356     case kW544p:
    357         width = 960;
    358         height = 544;
    359         return 0;
    360     case kW576p:
    361         width = 1024;
    362         height = 576;
    363         return 0;
    364     case kHD:
    365         width = 960;
    366         height = 720;
    367         return 0;
    368     case kXGA:
    369         width = 1024;
    370         height = 768;
    371         return 0;
    372     case kFullHD:
    373         width = 1440;
    374         height = 1080;
    375         return 0;
    376     case kWHD:
    377         width = 1280;
    378         height = 720;
    379         return 0;
    380     case kWFullHD:
    381         width = 1920;
    382         height = 1080;
    383         return 0;
    384     default:
    385         return -1;
    386     }
    387 }
    388 
    389 FrameDropper::FrameDropper()
    390 :
    391 _dropsBetweenRenders(0),
    392 _frameCounter(0)
    393 {
    394 }
    395 
    396 bool
    397 FrameDropper::DropFrame()
    398 {
    399     _frameCounter++;
    400     if (_frameCounter > _dropsBetweenRenders)
    401     {
    402         _frameCounter = 0;
    403         return false;
    404     }
    405     return true;
    406 }
    407 
    408 unsigned int
    409 FrameDropper::DropsBetweenRenders()
    410 {
    411     return _dropsBetweenRenders;
    412 }
    413 
    414 void
    415 FrameDropper::SetFrameRate(double frameRate, double maxFrameRate)
    416 {
    417     if (frameRate >= 1.0)
    418     {
    419         _dropsBetweenRenders = static_cast<unsigned int>(maxFrameRate / frameRate + 0.5) - 1;
    420     }
    421     else
    422     {
    423         _dropsBetweenRenders = 0;
    424     }
    425 }
    426