[x265] [PATCH] input: change from ifstream to stdio stream

Mateusz mateuszb at poczta.onet.pl
Tue Jan 16 08:55:37 CET 2018


W dniu 16.01.2018 o 05:35, Pradeep Ramachandran pisze:
> Mauteusz,
> Did you get a chance to turn-this around? I think the performance improvement on MacOS is worth pulling this in.
> Pradeep.

On Sat, Jan 13, 2018 I've sent new version of this patch (in new thread).

There is one improvement -- in y4m reader there are only two freads per frame
(instead of freads, fgets, freads). This gives tiny speed improvement
(most probable due to eliminate of fgets function and conserve L1 code cache).

Mateusz


> 
> On Wed, Jan 10, 2018 at 8:04 PM, Mateusz <mateuszb at poczta.onet.pl <mailto:mateuszb at poczta.onet.pl>> wrote:
> 
>     W dniu 25.05.2017 o 06:46, Pradeep Ramachandran pisze:
>>
>>     On Sun, Apr 30, 2017 at 5:24 PM, Mateusz Brzostek <mateusz at msystem.waw.pl <mailto:mateusz at msystem.waw.pl>> wrote:
>>
>>         This patch fixes issue #341 and allows Unicode filenames in Windows.
>>
>>         Please review.
>>
>>         # HG changeset patch
>>         # User Ma0 <mateuszb at poczta.onet.pl <mailto:mateuszb at poczta.onet.pl>>
>>         # Date 1493552587 -7200
>>         #      Sun Apr 30 13:43:07 2017 +0200
>>         # Node ID 0c7e08be80975e4b52f6c8aabe95d3b817d6723d
>>         # Parent  5bc5e73760cdb61d2674e74cc52149fa0603af8a
>>         input: change from ifstream to stdio stream
>>
>>
>>     I finally got around to testing this patch! Apologies for the delay.
>>
>>     I like this change and would like to pull it in. I don't see any performance improvement from my test with my linux box, but I would suspect there would be benefits of moving to stdio stream from ifstream.
>>
>>     This patch no longer applied on top of the default tip. Could you please refactor and resend so that I can pull-it in and commit it to the default tip?
> 
>     Sorry for delay -- I've subscribed to ffmpeg-devel list and didn't notice this e-mail.
> 
>     Now I'm busy at work but at the end of the week (Sunday) I will prepare new patch.
>     It is also not faster on my system (Windows) with this patch.
> 
>     Mateusz
> 
> 
> 
> 
> 
>>
>>
>>         diff -r 5bc5e73760cd -r 0c7e08be8097 source/common/common.h
>>         --- a/source/common/common.h    Sat Apr 22 17:00:28 2017 -0700
>>         +++ b/source/common/common.h    Sun Apr 30 13:43:07 2017 +0200
>>         @@ -78,6 +78,7 @@
>>
>>          #if defined(__MINGW32__)
>>          #define fseeko fseeko64
>>         +#define ftello ftello64
>>          #endif
>>
>>          #elif defined(_MSC_VER)
>>         @@ -87,6 +88,7 @@
>>          #define ALIGN_VAR_16(T, var) __declspec(align(16)) T var
>>          #define ALIGN_VAR_32(T, var) __declspec(align(32)) T var
>>          #define fseeko _fseeki64
>>         +#define ftello _ftelli64
>>
>>          #endif // if defined(__GNUC__)
>>
>>         diff -r 5bc5e73760cd -r 0c7e08be8097 source/input/y4m.cpp
>>         --- a/source/input/y4m.cpp    Sat Apr 22 17:00:28 2017 -0700
>>         +++ b/source/input/y4m.cpp    Sun Apr 30 13:43:07 2017 +0200
>>         @@ -60,15 +60,15 @@
>>              ifs = NULL;
>>              if (!strcmp(info.filename, "-"))
>>              {
>>         -        ifs = &cin;
>>         +        ifs = stdin;
>>          #if _WIN32
>>                  setmode(fileno(stdin), O_BINARY);
>>          #endif
>>              }
>>              else
>>         -        ifs = new ifstream(info.filename, ios::binary | ios::in);
>>         +        ifs = x265_fopen(info.filename, "rb");
>>
>>         -    if (ifs && ifs->good() && parseHeader())
>>         +    if (ifs && !ferror(ifs) && parseHeader())
>>              {
>>                  int pixelbytes = depth > 8 ? 2 : 1;
>>                  for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
>>         @@ -91,8 +91,8 @@
>>              }
>>              if (!threadActive)
>>              {
>>         -        if (ifs && ifs != &cin)
>>         -            delete ifs;
>>         +        if (ifs && ifs != stdin)
>>         +            fclose(ifs);
>>                  ifs = NULL;
>>                  return;
>>              }
>>         @@ -110,56 +110,35 @@
>>              size_t estFrameSize = framesize + strlen(header) + 1; /* assume basic FRAME\n headers */
>>
>>              /* try to estimate frame count, if this is not stdin */
>>         -    if (ifs != &cin)
>>         +    if (ifs != stdin)
>>              {
>>         -        istream::pos_type cur = ifs->tellg();
>>         +        int64_t cur = ftello(ifs);
>>
>>         -#if defined(_MSC_VER) && _MSC_VER < 1700
>>         -        /* Older MSVC versions cannot handle 64bit file sizes properly, so go native */
>>         -        HANDLE hFile = CreateFileA(info.filename, GENERIC_READ,
>>         -                                   FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
>>         -                                   FILE_ATTRIBUTE_NORMAL, NULL);
>>         -        if (hFile != INVALID_HANDLE_VALUE)
>>         -        {
>>         -            LARGE_INTEGER size;
>>         -            if (GetFileSizeEx(hFile, &size))
>>         -                info.frameCount = (int)((size.QuadPart - (int64_t)cur) / estFrameSize);
>>         -            CloseHandle(hFile);
>>         -        }
>>         -#else // if defined(_MSC_VER) && _MSC_VER < 1700
>>                  if (cur >= 0)
>>                  {
>>         -            ifs->seekg(0, ios::end);
>>         -            istream::pos_type size = ifs->tellg();
>>         -            ifs->seekg(cur, ios::beg);
>>         +            fseeko(ifs, 0, SEEK_END);
>>         +            int64_t size = ftello(ifs);
>>         +            fseeko(ifs, cur, SEEK_SET);
>>                      if (size > 0)
>>                          info.frameCount = (int)((size - cur) / estFrameSize);
>>                  }
>>         -#endif // if defined(_MSC_VER) && _MSC_VER < 1700
>>              }
>>
>>              if (info.skipFrames)
>>              {
>>         -#if X86_64
>>         -        if (ifs != &cin)
>>         -            ifs->seekg((uint64_t)estFrameSize * info.skipFrames, ios::cur);
>>         +        if (ifs != stdin)
>>         +            fseeko(ifs, (int64_t)estFrameSize * info.skipFrames, SEEK_CUR);
>>                  else
>>                      for (int i = 0; i < info.skipFrames; i++)
>>         -            {
>>         -                ifs->read(buf[0], estFrameSize - framesize);
>>         -                ifs->read(buf[0], framesize);
>>         -            }
>>         -#else
>>         -        for (int i = 0; i < info.skipFrames; i++)
>>         -            ifs->ignore(estFrameSize);
>>         -#endif
>>         +                if (fread(buf[0], estFrameSize - framesize, 1, ifs) + fread(buf[0], framesize, 1, ifs) != 2)
>>         +                    break;
>>              }
>>          }
>>
>>          Y4MInput::~Y4MInput()
>>          {
>>         -    if (ifs && ifs != &cin)
>>         -        delete ifs;
>>         +    if (ifs && ifs != stdin)
>>         +        fclose(ifs);
>>
>>              for (int i = 0; i < QUEUE_SIZE; i++)
>>                  X265_FREE(buf[i]);
>>         @@ -181,24 +160,22 @@
>>              int csp = 0;
>>              int d = 0;
>>
>>         -    while (ifs->good())
>>         +    int c;
>>         +    while ((c = fgetc(ifs)) != EOF)
>>              {
>>                  // Skip Y4MPEG string
>>         -        int c = ifs->get();
>>         -        while (ifs->good() && (c != ' ') && (c != '\n'))
>>         -            c = ifs->get();
>>         +        while ((c != EOF) && (c != ' ') && (c != '\n'))
>>         +            c = fgetc(ifs);
>>
>>         -        while (c == ' ' && ifs->good())
>>         +        while (c == ' ')
>>                  {
>>                      // read parameter identifier
>>         -            switch (ifs->get())
>>         +            switch (fgetc(ifs))
>>                      {
>>                      case 'W':
>>                          width = 0;
>>         -                while (ifs->good())
>>         +                while ((c = fgetc(ifs)) != EOF)
>>                          {
>>         -                    c = ifs->get();
>>         -
>>                              if (c == ' ' || c == '\n')
>>                                  break;
>>                              else
>>         @@ -208,9 +185,8 @@
>>
>>                      case 'H':
>>                          height = 0;
>>         -                while (ifs->good())
>>         +                while ((c = fgetc(ifs)) != EOF)
>>                          {
>>         -                    c = ifs->get();
>>                              if (c == ' ' || c == '\n')
>>                                  break;
>>                              else
>>         @@ -221,15 +197,13 @@
>>                      case 'F':
>>                          rateNum = 0;
>>                          rateDenom = 0;
>>         -                while (ifs->good())
>>         +                while ((c = fgetc(ifs)) != EOF)
>>                          {
>>         -                    c = ifs->get();
>>                              if (c == '.')
>>                              {
>>                                  rateDenom = 1;
>>         -                        while (ifs->good())
>>         +                        while ((c = fgetc(ifs)) != EOF)
>>                                  {
>>         -                            c = ifs->get();
>>                                      if (c == ' ' || c == '\n')
>>                                          break;
>>                                      else
>>         @@ -242,9 +216,8 @@
>>                              }
>>                              else if (c == ':')
>>                              {
>>         -                        while (ifs->good())
>>         +                        while ((c = fgetc(ifs)) != EOF)
>>                                  {
>>         -                            c = ifs->get();
>>                                      if (c == ' ' || c == '\n')
>>                                          break;
>>                                      else
>>         @@ -260,14 +233,12 @@
>>                      case 'A':
>>                          sarWidth = 0;
>>                          sarHeight = 0;
>>         -                while (ifs->good())
>>         +                while ((c = fgetc(ifs)) != EOF)
>>                          {
>>         -                    c = ifs->get();
>>                              if (c == ':')
>>                              {
>>         -                        while (ifs->good())
>>         +                        while ((c = fgetc(ifs)) != EOF)
>>                                  {
>>         -                            c = ifs->get();
>>                                      if (c == ' ' || c == '\n')
>>                                          break;
>>                                      else
>>         @@ -283,19 +254,15 @@
>>                      case 'C':
>>                          csp = 0;
>>                          d = 0;
>>         -                while (ifs->good())
>>         +                while ((c = fgetc(ifs)) != EOF)
>>                          {
>>         -                    c = ifs->get();
>>         -
>>                              if (c <= 'o' && c >= '0')
>>                                  csp = csp * 10 + (c - '0');
>>                              else if (c == 'p')
>>                              {
>>                                  // example: C420p16
>>         -                        while (ifs->good())
>>         +                        while ((c = fgetc(ifs)) != EOF)
>>                                  {
>>         -                            c = ifs->get();
>>         -
>>                                      if (c <= '9' && c >= '0')
>>                                          d = d * 10 + (c - '0');
>>                                      else
>>         @@ -327,10 +294,9 @@
>>                          break;
>>
>>                      default:
>>         -                while (ifs->good())
>>         +                while ((c = fgetc(ifs)) != EOF)
>>                          {
>>                              // consume this unsupported configuration word
>>         -                    c = ifs->get();
>>                              if (c == ' ' || c == '\n')
>>                                  break;
>>                          }
>>         @@ -375,26 +341,24 @@
>>
>>          bool Y4MInput::populateFrameQueue()
>>          {
>>         -    if (!ifs || ifs->fail())
>>         +    if (!ifs || ferror(ifs))
>>                  return false;
>>
>>              /* strip off the FRAME header */
>>              char hbuf[sizeof(header)];
>>
>>         -    ifs->read(hbuf, strlen(header));
>>         -    if (ifs->eof())
>>         -        return false;
>>         -
>>         -    if (!ifs->good() || memcmp(hbuf, header, strlen(header)))
>>         +    if (fread(hbuf, strlen(header), 1, ifs) != 1 || memcmp(hbuf, header, strlen(header)))
>>              {
>>         -        x265_log(NULL, X265_LOG_ERROR, "y4m: frame header missing\n");
>>         +        if (!feof(ifs))
>>         +            x265_log(NULL, X265_LOG_ERROR, "y4m: frame header missing\n");
>>                  return false;
>>              }
>>
>>              /* consume bytes up to line feed */
>>         -    int c = ifs->get();
>>         -    while (c != '\n' && ifs->good())
>>         -        c = ifs->get();
>>         +    int c;
>>         +    while ((c = fgetc(ifs)) != EOF)
>>         +        if (c == '\n')
>>         +            break;
>>
>>              /* wait for room in the ring buffer */
>>              int written = writeCount.get();
>>         @@ -407,8 +371,7 @@
>>              }
>>
>>              ProfileScopeEvent(frameRead);
>>         -    ifs->read(buf[written % QUEUE_SIZE], framesize);
>>         -    if (ifs->good())
>>         +    if (fread(buf[written % QUEUE_SIZE], framesize, 1, ifs) == 1)
>>              {
>>                  writeCount.incr();
>>                  return true;
>>         diff -r 5bc5e73760cd -r 0c7e08be8097 source/input/y4m.h
>>         --- a/source/input/y4m.h    Sat Apr 22 17:00:28 2017 -0700
>>         +++ b/source/input/y4m.h    Sun Apr 30 13:43:07 2017 +0200
>>         @@ -63,7 +63,7 @@
>>
>>              char* buf[QUEUE_SIZE];
>>
>>         -    std::istream *ifs;
>>         +    FILE *ifs;
>>
>>              bool parseHeader();
>>
>>         @@ -79,9 +79,9 @@
>>
>>              void release();
>>
>>         -    bool isEof() const            { return ifs && ifs->eof();  }
>>         +    bool isEof() const            { return ifs && feof(ifs); }
>>
>>         -    bool isFail()                 { return !(ifs && !ifs->fail() && threadActive); }
>>         +    bool isFail()                 { return !(ifs && !ferror(ifs) && threadActive); }
>>
>>              void startReader();
>>
>>         diff -r 5bc5e73760cd -r 0c7e08be8097 source/input/yuv.cpp
>>         --- a/source/input/yuv.cpp    Sat Apr 22 17:00:28 2017 -0700
>>         +++ b/source/input/yuv.cpp    Sun Apr 30 13:43:07 2017 +0200
>>         @@ -68,20 +68,20 @@
>>
>>              if (!strcmp(info.filename, "-"))
>>              {
>>         -        ifs = &cin;
>>         +        ifs = stdin;
>>          #if _WIN32
>>                  setmode(fileno(stdin), O_BINARY);
>>          #endif
>>              }
>>              else
>>         -        ifs = new ifstream(info.filename, ios::binary | ios::in);
>>         +        ifs = x265_fopen(info.filename, "rb");
>>
>>         -    if (ifs && ifs->good())
>>         +    if (ifs && !ferror(ifs))
>>                  threadActive = true;
>>              else
>>              {
>>         -        if (ifs && ifs != &cin)
>>         -            delete ifs;
>>         +        if (ifs && ifs != stdin)
>>         +            fclose(ifs);
>>                  ifs = NULL;
>>                  return;
>>              }
>>         @@ -100,53 +100,35 @@
>>              info.frameCount = -1;
>>
>>              /* try to estimate frame count, if this is not stdin */
>>         -    if (ifs != &cin)
>>         +    if (ifs != stdin)
>>              {
>>         -        istream::pos_type cur = ifs->tellg();
>>         +        int64_t cur = ftello(ifs);
>>
>>         -#if defined(_MSC_VER) && _MSC_VER < 1700
>>         -        /* Older MSVC versions cannot handle 64bit file sizes properly, so go native */
>>         -        HANDLE hFile = CreateFileA(info.filename, GENERIC_READ,
>>         -                                   FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
>>         -                                   FILE_ATTRIBUTE_NORMAL, NULL);
>>         -        if (hFile != INVALID_HANDLE_VALUE)
>>         -        {
>>         -            LARGE_INTEGER size;
>>         -            if (GetFileSizeEx(hFile, &size))
>>         -                info.frameCount = (int)((size.QuadPart - (int64_t)cur) / framesize);
>>         -            CloseHandle(hFile);
>>         -        }
>>         -#else // if defined(_MSC_VER) && _MSC_VER < 1700
>>                  if (cur >= 0)
>>                  {
>>         -            ifs->seekg(0, ios::end);
>>         -            istream::pos_type size = ifs->tellg();
>>         -            ifs->seekg(cur, ios::beg);
>>         +            fseeko(ifs, 0, SEEK_END);
>>         +            int64_t size = ftello(ifs);
>>         +            fseeko(ifs, cur, SEEK_SET);
>>                      if (size > 0)
>>                          info.frameCount = (int)((size - cur) / framesize);
>>                  }
>>         -#endif // if defined(_MSC_VER) && _MSC_VER < 1700
>>              }
>>
>>              if (info.skipFrames)
>>              {
>>         -#if X86_64
>>         -        if (ifs != &cin)
>>         -            ifs->seekg((uint64_t)framesize * info.skipFrames, ios::cur);
>>         +        if (ifs != stdin)
>>         +            fseeko(ifs, (int64_t)framesize * info.skipFrames, SEEK_CUR);
>>                  else
>>                      for (int i = 0; i < info.skipFrames; i++)
>>         -                ifs->read(buf[0], framesize);
>>         -#else
>>         -        for (int i = 0; i < info.skipFrames; i++)
>>         -            ifs->ignore(framesize);
>>         -#endif
>>         +                if (fread(buf[0], framesize, 1, ifs) != 1)
>>         +                    break;
>>              }
>>          }
>>
>>          YUVInput::~YUVInput()
>>          {
>>         -    if (ifs && ifs != &cin)
>>         -        delete ifs;
>>         +    if (ifs && ifs != stdin)
>>         +        fclose(ifs);
>>              for (int i = 0; i < QUEUE_SIZE; i++)
>>                  X265_FREE(buf[i]);
>>          }
>>         @@ -182,7 +164,7 @@
>>
>>          bool YUVInput::populateFrameQueue()
>>          {
>>         -    if (!ifs || ifs->fail())
>>         +    if (!ifs || ferror(ifs))
>>                  return false;
>>
>>              /* wait for room in the ring buffer */
>>         @@ -197,8 +179,7 @@
>>              }
>>
>>              ProfileScopeEvent(frameRead);
>>         -    ifs->read(buf[written % QUEUE_SIZE], framesize);
>>         -    if (ifs->good())
>>         +    if (fread(buf[written % QUEUE_SIZE], framesize, 1, ifs) == 1)
>>              {
>>                  writeCount.incr();
>>                  return true;
>>         diff -r 5bc5e73760cd -r 0c7e08be8097 source/input/yuv.h
>>         --- a/source/input/yuv.h    Sat Apr 22 17:00:28 2017 -0700
>>         +++ b/source/input/yuv.h    Sun Apr 30 13:43:07 2017 +0200
>>         @@ -55,7 +55,7 @@
>>
>>              char* buf[QUEUE_SIZE];
>>
>>         -    std::istream *ifs;
>>         +    FILE *ifs;
>>
>>              int guessFrameCount();
>>
>>         @@ -71,9 +71,9 @@
>>
>>              void release();
>>
>>         -    bool isEof() const                            { return ifs && ifs->eof();  }
>>         +    bool isEof() const                            { return ifs && feof(ifs); }
>>
>>         -    bool isFail()                                 { return !(ifs && !ifs->fail() && threadActive); }
>>         +    bool isFail()                                 { return !(ifs && !ferror(ifs) && threadActive); }
>>
>>              void startReader();
>>
>>
>>
>>         _______________________________________________
>>         x265-devel mailing list
>>         x265-devel at videolan.org <mailto:x265-devel at videolan.org>
>>         https://mailman.videolan.org/listinfo/x265-devel <https://mailman.videolan.org/listinfo/x265-devel>
>>
>>
>>
>>
>>     _______________________________________________
>>     x265-devel mailing list
>>     x265-devel at videolan.org <mailto:x265-devel at videolan.org>
>>     https://mailman.videolan.org/listinfo/x265-devel <https://mailman.videolan.org/listinfo/x265-devel>
> 
> 
>     _______________________________________________
>     x265-devel mailing list
>     x265-devel at videolan.org <mailto:x265-devel at videolan.org>
>     https://mailman.videolan.org/listinfo/x265-devel <https://mailman.videolan.org/listinfo/x265-devel>
> 
> 
> 
> 
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
> 




More information about the x265-devel mailing list