text: /*
   * Copyright 2019 NVIDIA Corporation
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *    http://www.apache.org/licenses/LICENSE-2.0
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #pragma once
  
  #if defined(_WIN32)
  #define DllExport __declspec(dllexport)
  #else
  #define DllExport
  #endif
  
  extern "C" {
  #include "libavcodec/avcodec.h"
  #include "libavformat/avformat.h"
  #include "libavformat/avio.h"
  }
  
  #include "CodecsSupport.hpp"
  #include "NvCodecUtils.h"
  #include "cuviddec.h"
  #include <vector>
  
  class DataProvider;
  
  class DllExport FFmpegDemuxer {
    AVIOContext *avioc = nullptr;
    AVBSFContext *bsfc = nullptr;
    AVFormatContext *fmtc = nullptr;
  
    AVPacket pkt;
    AVPacket pktFiltered;
    PacketData lastPacketData;
    AVCodecID eVideoCodec = AV_CODEC_ID_NONE;
    AVPixelFormat eChromaFormat;
  
    uint32_t width;
    uint32_t height;
    uint32_t framerate;
  
    int videoStream = -1;
  
    bool is_mp4H264;
    bool is_mp4HEVC;
    bool is_EOF = false;
  
    std::vector<uint8_t> videoBytes;
  
    explicit FFmpegDemuxer(AVFormatContext *fmtcx);
  
    AVFormatContext *CreateFormatContext(DataProvider *pDataProvider);
  
    AVFormatContext *CreateFormatContext(const char *szFilePath);
  
  public:
    explicit FFmpegDemuxer(const char *szFilePath);
    explicit FFmpegDemuxer(DataProvider *pDataProvider);
    ~FFmpegDemuxer();
  
    AVCodecID GetVideoCodec() const;
  
    uint32_t GetWidth() const;
  
    uint32_t GetHeight() const;
  
    uint32_t GetFramerate() const;
  
    uint32_t GetVideoStreamIndex() const;
  
    AVPixelFormat GetPixelFormat() const;
  
    bool Demux(uint8_t *&pVideo, size_t &rVideoBytes);
  
    void GetLastPacketData(PacketData &pktData);
  
    static int ReadPacket(void *opaque, uint8_t *pBuf, int nBuf);
  };
  
  inline cudaVideoCodec FFmpeg2NvCodecId(AVCodecID id) {
    switch (id) {
    case AV_CODEC_ID_MPEG1VIDEO:
      return cudaVideoCodec_MPEG1;
    case AV_CODEC_ID_MPEG2VIDEO:
      return cudaVideoCodec_MPEG2;
    case AV_CODEC_ID_MPEG4:
      return cudaVideoCodec_MPEG4;
    case AV_CODEC_ID_VC1:
      return cudaVideoCodec_VC1;
    case AV_CODEC_ID_H264:
      return cudaVideoCodec_H264;
    case AV_CODEC_ID_HEVC:
      return cudaVideoCodec_HEVC;
    case AV_CODEC_ID_VP8:
      return cudaVideoCodec_VP8;
    case AV_CODEC_ID_VP9:
      return cudaVideoCodec_VP9;
    case AV_CODEC_ID_MJPEG:
      return cudaVideoCodec_JPEG;
    default:
      return cudaVideoCodec_NumCodecs;
    }
  }
  