1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "DVDResource.h" 12 #include "cores/VideoPlayer/Buffers/VideoBuffer.h" 13 #include "cores/VideoPlayer/Interface/DemuxPacket.h" 14 #include "cores/VideoPlayer/Process/ProcessInfo.h" 15 16 extern "C" { 17 #include <libavcodec/avcodec.h> 18 #include <libavutil/mastering_display_metadata.h> 19 } 20 21 #include <vector> 22 #include <string> 23 #include <map> 24 25 class CSetting; 26 27 // when modifying these structures, make sure you update all codecs accordingly 28 #define FRAME_TYPE_UNDEF 0 29 #define FRAME_TYPE_I 1 30 #define FRAME_TYPE_P 2 31 #define FRAME_TYPE_B 3 32 #define FRAME_TYPE_D 4 33 34 35 // should be entirely filled by all codecs 36 struct VideoPicture 37 { 38 public: 39 VideoPicture(); 40 ~VideoPicture(); 41 VideoPicture& CopyRef(const VideoPicture &pic); 42 VideoPicture& SetParams(const VideoPicture &pic); 43 void Reset(); // reinitialize members, videoBuffer will be released if set! 44 45 CVideoBuffer *videoBuffer = nullptr; 46 47 double pts; // timestamp in seconds, used in the CVideoPlayer class to keep track of pts 48 double dts; 49 unsigned int iFlags; 50 double iRepeatPicture; 51 double iDuration; 52 unsigned int iFrameType : 4; //< see defines above // 1->I, 2->P, 3->B, 0->Undef 53 unsigned int color_space; 54 unsigned int color_range : 1; //< 1 indicate if we have a full range of color 55 unsigned int chroma_position; 56 unsigned int color_primaries; 57 unsigned int color_transfer; 58 unsigned int colorBits = 8; 59 std::string stereoMode; 60 61 int8_t* qp_table; //< Quantization parameters, primarily used by filters 62 int qstride; 63 int qscale_type; 64 int pict_type; 65 66 bool hasDisplayMetadata = false; 67 AVMasteringDisplayMetadata displayMetadata; 68 bool hasLightMetadata = false; 69 AVContentLightMetadata lightMetadata; 70 71 AVPixelFormat pixelFormat; //< source pixel format 72 73 unsigned int iWidth; 74 unsigned int iHeight; 75 unsigned int iDisplayWidth; //< width of the picture without black bars 76 unsigned int iDisplayHeight; //< height of the picture without black bars 77 78 private: 79 VideoPicture(VideoPicture const&); 80 VideoPicture& operator=(VideoPicture const&); 81 }; 82 83 #define DVP_FLAG_TOP_FIELD_FIRST 0x00000001 84 #define DVP_FLAG_REPEAT_TOP_FIELD 0x00000002 //< Set to indicate that the top field should be repeated 85 #define DVP_FLAG_INTERLACED 0x00000008 //< Set to indicate that this frame is interlaced 86 #define DVP_FLAG_DROPPED 0x00000010 //< indicate that this picture has been dropped in decoder stage, will have no data 87 88 #define DVD_CODEC_CTRL_SKIPDEINT 0x01000000 //< request to skip a deinterlacing cycle, if possible 89 #define DVD_CODEC_CTRL_NO_POSTPROC 0x02000000 //< see GetCodecStats 90 #define DVD_CODEC_CTRL_HURRY 0x04000000 //< see GetCodecStats 91 #define DVD_CODEC_CTRL_DROP 0x08000000 //< drop in decoder or set DVP_FLAG_DROPPED, no render of frame 92 #define DVD_CODEC_CTRL_DROP_ANY 0x10000000 //< drop some non-reference frame 93 #define DVD_CODEC_CTRL_DRAIN 0x20000000 //< squeeze out pictured without feeding new packets 94 #define DVD_CODEC_CTRL_ROTATE 0x40000000 //< rotate if renderer does not support it 95 96 // DVP_FLAG 0x00000100 - 0x00000f00 is in use by libmpeg2! 97 98 #define DVP_QSCALE_UNKNOWN 0 99 #define DVP_QSCALE_MPEG1 1 100 #define DVP_QSCALE_MPEG2 2 101 #define DVP_QSCALE_H264 3 102 103 class CDVDStreamInfo; 104 class CDVDCodecOption; 105 class CDVDCodecOptions; 106 107 class CDVDVideoCodec 108 { 109 public: 110 111 enum VCReturn 112 { 113 VC_NONE = 0, 114 VC_ERROR, //< an error occurred, no other messages will be returned 115 VC_FATAL, //< non recoverable error 116 VC_BUFFER, //< the decoder needs more data 117 VC_PICTURE, //< the decoder got a picture, call Decode(NULL, 0) again to parse the rest of the data 118 VC_FLUSHED, //< the decoder lost it's state, we need to restart decoding again 119 VC_NOBUFFER, //< last FFmpeg GetBuffer failed 120 VC_REOPEN, //< decoder request to re-open 121 VC_EOF //< EOF 122 }; 123 CDVDVideoCodec(CProcessInfo & processInfo)124 explicit CDVDVideoCodec(CProcessInfo &processInfo) : m_processInfo(processInfo) {} 125 virtual ~CDVDVideoCodec() = default; 126 127 /** 128 * Open the decoder, returns true on success 129 * Decoders not capable of runnung multiple instances should return false in case 130 * there is already a instance open 131 */ 132 virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) = 0; 133 134 /** 135 * Reconfigure the decoder, returns true on success 136 * Decoders not capable of runnung multiple instances may be capable of reconfiguring 137 * the running instance. If Reconfigure returns false, player will close / open 138 * the decoder 139 */ Reconfigure(CDVDStreamInfo & hints)140 virtual bool Reconfigure(CDVDStreamInfo &hints) 141 { 142 return false; 143 } 144 145 /** 146 * add data, decoder has to consume the entire packet 147 * returns true if the packet was consumed or if resubmitting it is useless 148 */ 149 virtual bool AddData(const DemuxPacket &packet) = 0; 150 151 /** 152 * Reset the decoder. 153 * Should be the same as calling Dispose and Open after each other 154 */ 155 virtual void Reset() = 0; 156 157 /** 158 * GetPicture controls decoding. Player calls it on every cycle 159 * it can signal a picture, request a buffer, or return none, if nothing applies 160 * the data is valid until the next GetPicture return VC_PICTURE 161 */ 162 virtual VCReturn GetPicture(VideoPicture* pVideoPicture) = 0; 163 164 /** 165 * will be called by video player indicating the playback speed. see DVD_PLAYSPEED_NORMAL, 166 * DVD_PLAYSPEED_PAUSE and friends. 167 */ SetSpeed(int iSpeed)168 virtual void SetSpeed(int iSpeed) {}; 169 170 /** 171 * should return codecs name 172 */ 173 virtual const char* GetName() = 0; 174 175 /** 176 * How many packets should player remember, so codec can recover should 177 * something cause it to flush outside of players control 178 */ GetConvergeCount()179 virtual unsigned GetConvergeCount() 180 { 181 return 0; 182 } 183 184 /** 185 * Number of references to old pictures that are allowed to be retained when 186 * calling decode on the next demux packet 187 */ GetAllowedReferences()188 virtual unsigned GetAllowedReferences() { return 0; } 189 190 /** 191 * For calculation of dropping requirements player asks for some information. 192 * - pts : right after decoder, used to detect gaps (dropped frames in decoder) 193 * - droppedFrames : indicates if decoder has dropped a frame 194 * -1 means that decoder has no info on this. 195 * - skippedPics : indicates if postproc has skipped a already decoded picture 196 * -1 means that decoder has no info on this. 197 * 198 * If codec does not implement this method, pts of decoded frame at input 199 * video player is used. In case decoder does post-proc and de-interlacing there 200 * may be quite some frames queued up between exit decoder and entry player. 201 */ GetCodecStats(double & pts,int & droppedFrames,int & skippedPics)202 virtual bool GetCodecStats(double &pts, int &droppedFrames, int &skippedPics) 203 { 204 droppedFrames = -1; 205 skippedPics = -1; 206 return false; 207 } 208 209 /** 210 * Codec can be informed by player with the following flags: 211 * 212 * DVD_CODEC_CTRL_NO_POSTPROC : 213 * if speed is not normal the codec can switch off 214 * postprocessing and de-interlacing 215 * 216 * DVD_CODEC_CTRL_HURRY : 217 * codecs may do postprocessing and de-interlacing. 218 * If video buffers in RenderManager are about to run dry, 219 * this is signaled to codec. Codec can wait for post-proc 220 * to be finished instead of returning empty and getting another 221 * packet. 222 * 223 * DVD_CODEC_CTRL_DRAIN : 224 * instruct decoder to deliver last pictures without requesting 225 * new packets 226 * 227 * DVD_CODEC_CTRL_DROP : 228 * this packet is going to be dropped. decoder is free to use it 229 * for decoding 230 * 231 */ SetCodecControl(int flags)232 virtual void SetCodecControl(int flags) {} 233 234 /** 235 * Re-open the decoder. 236 * Decoder request to re-open 237 */ Reopen()238 virtual void Reopen() {}; 239 240 protected: 241 CProcessInfo &m_processInfo; 242 }; 243 244 // callback interface for ffmpeg hw accelerators 245 class IHardwareDecoder : public IDVDResourceCounted<IHardwareDecoder> 246 { 247 public: 248 IHardwareDecoder() = default; 249 ~IHardwareDecoder() override = default; 250 virtual bool Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum AVPixelFormat) = 0; 251 virtual CDVDVideoCodec::VCReturn Decode(AVCodecContext* avctx, AVFrame* frame) = 0; 252 virtual bool GetPicture(AVCodecContext* avctx, VideoPicture* picture) = 0; 253 virtual CDVDVideoCodec::VCReturn Check(AVCodecContext* avctx) = 0; Reset()254 virtual void Reset() {} GetAllowedReferences()255 virtual unsigned GetAllowedReferences() { return 0; } CanSkipDeint()256 virtual bool CanSkipDeint() {return false; } 257 virtual const std::string Name() = 0; SetCodecControl(int flags)258 virtual void SetCodecControl(int flags) {}; 259 }; 260 261 class ICallbackHWAccel 262 { 263 public: 264 virtual ~ICallbackHWAccel() = default; 265 virtual IHardwareDecoder* GetHWAccel() = 0; 266 virtual bool GetPictureCommon(VideoPicture* pVideoPicture) = 0; 267 }; 268