MythTV  master
avformatdecoder.h
Go to the documentation of this file.
1 
2 #ifndef AVFORMATDECODER_H_
3 #define AVFORMATDECODER_H_
4 
5 #include <cstdint>
6 
7 #include <QString>
8 #include <QMap>
9 #include <QList>
10 
11 #include "programinfo.h"
12 #include "format.h"
13 #include "decoderbase.h"
14 #include "privatedecoder.h"
15 #include "audiooutputsettings.h"
16 #include "audiooutpututil.h"
17 #include "spdifencoder.h"
18 #include "vbilut.h"
19 #include "H264Parser.h"
20 #include "videodisplayprofile.h"
21 #include "mythcodeccontext.h"
22 #include "mythplayer.h"
23 
24 extern "C" {
25 #include "mythframe.h"
26 #include "libavcodec/avcodec.h"
27 #include "libavformat/avformat.h"
28 }
29 
30 #include "avfringbuffer.h"
31 
32 class TeletextDecoder;
33 class CC608Decoder;
34 class CC708Decoder;
35 class SubtitleReader;
36 class InteractiveTV;
37 class ProgramInfo;
38 class MythSqlDatabase;
39 
40 struct SwsContext;
41 
42 extern "C" void HandleStreamChange(void *data);
43 
44 class AudioInfo
45 {
46  public:
47  AudioInfo() = default;
48 
49  AudioInfo(AVCodecID id, AudioFormat fmt, int sr, int ch, bool passthru,
50  int original_ch, int profile = 0) :
51  m_codecId(id), format(fmt),
52  m_sampleSize(ch * AudioOutputSettings::SampleSize(fmt)),
54  m_doPassthru(passthru), m_originalChannels(original_ch)
55  {
56  }
57 
58  AVCodecID m_codecId {AV_CODEC_ID_NONE};
60  int m_sampleSize {-2};
61  int m_sampleRate {-1};
62  int m_channels {-1};
63  int m_codecProfile {0};
64  bool m_doPassthru {false};
66 
67  bool operator==(const AudioInfo &o) const
68  {
69  return (m_codecId==o.m_codecId && m_channels==o.m_channels &&
74  }
75  QString toString() const
76  {
77  return QString("id(%1) %2Hz %3ch %4bps %5 (profile %6)")
78  .arg(ff_codec_id_string(m_codecId),4).arg(m_sampleRate,6)
80  .arg((m_doPassthru) ? "pt":"",3).arg(m_codecProfile);
81  }
82 };
83 
85 
89 {
90  friend void HandleStreamChange(void *data);
91  public:
92  static void GetDecoders(RenderOptions &opts);
93  AvFormatDecoder(MythPlayer *parent, const ProgramInfo &pginfo,
94  PlayerFlags flags);
95  ~AvFormatDecoder() override;
96 
97  // Deleted functions should be public.
98  AvFormatDecoder(const AvFormatDecoder &) = delete; // not copyable
99  AvFormatDecoder &operator=(const AvFormatDecoder &) = delete; // not copyable
100 
101  void SetEof(bool eof) override; // DecoderBase
102 
103  void CloseCodecs();
104  void CloseContext();
105  void Reset(bool reset_video_data, bool seek_reset,
106  bool reset_file) override; // DecoderBase
107 
110  static bool CanHandle(char testbuf[kDecoderProbeBufferSize],
111  const QString &filename,
112  int testbufsize = kDecoderProbeBufferSize);
113 
115  int OpenFile(RingBuffer *rbuffer, bool novideo,
116  char testbuf[kDecoderProbeBufferSize],
117  int testbufsize = kDecoderProbeBufferSize) override; // DecoderBase
118 
119  bool GetFrame(DecodeType Type, bool &Retry) override; // DecoderBase
120 
121  bool IsLastFrameKey(void) const override { return false; } // DecoderBase
122 
124  void WriteStoredData(RingBuffer *rb, bool storevid,
125  long timecodeOffset) override // DecoderBase
126  { (void)rb; (void)storevid; (void)timecodeOffset;}
127 
129  void SetRawAudioState(bool state) override { (void)state; } // DecoderBase
130 
132  bool GetRawAudioState(void) const override { return false; } // DecoderBase
133 
135  void SetRawVideoState(bool state) override { (void)state; } // DecoderBase
136 
138  bool GetRawVideoState(void) const override { return false; } // DecoderBase
139 
141  long UpdateStoredFrameNum(long frame) override { (void)frame; return 0;} // DecoderBase
142 
143  QString GetCodecDecoderName(void) const override; // DecoderBase
144  QString GetRawEncodingType(void) override; // DecoderBase
145  MythCodecID GetVideoCodecID(void) const override { return m_videoCodecId; } // DecoderBase
146 
147  void SetDisablePassThrough(bool disable) override; // DecoderBase
148  void ForceSetupAudioStream(void) override; // DecoderBase
149  void AddTextData(unsigned char *buf, int len, int64_t timecode, char type);
150 
151  QString GetTrackDesc(uint type, uint trackNo) const override; // DecoderBase
152  int SetTrack(uint type, int trackNo) override; // DecoderBase
153 
154  int ScanStreams(bool novideo);
155  int FindStreamInfo(void);
156 
157  int GetNumChapters() override; // DecoderBase
158  void GetChapterTimes(QList<long long> &times) override; // DecoderBase
159  int GetCurrentChapter(long long framesPlayed) override; // DecoderBase
160  long long GetChapter(int chapter) override; // DecoderBase
161  bool DoRewind(long long desiredFrame, bool discardFrames = true) override; // DecoderBase
162  bool DoFastForward(long long desiredFrame, bool discardFrames = true) override; // DecoderBase
163  void SetIdrOnlyKeyframes(bool value) override // DecoderBase
164  { m_h264Parser->use_I_forKeyframes(!value); }
165 
166  int64_t NormalizeVideoTimecode(int64_t timecode) override; // DecoderBase
167  virtual int64_t NormalizeVideoTimecode(AVStream *st, int64_t timecode);
168 
169  int GetTeletextDecoderType(void) const override; // DecoderBase
170 
171  QString GetXDS(const QString &key) const override; // DecoderBase
172  QByteArray GetSubHeader(uint trackNo) const override; // DecoderBase
173  void GetAttachmentData(uint trackNo, QByteArray &filename,
174  QByteArray &data) override; // DecoderBase
175 
176  // MHEG stuff
177  bool SetAudioByComponentTag(int tag) override; // DecoderBase
178  bool SetVideoByComponentTag(int tag) override; // DecoderBase
179 
180  // Stream language info
181  virtual int GetTeletextLanguage(uint lang_idx) const;
182  virtual int GetSubtitleLanguage(uint subtitle_index, uint stream_index);
183  virtual int GetCaptionLanguage(TrackType trackType, int service_num);
184  virtual int GetAudioLanguage(uint audio_index, uint stream_index);
185  virtual AudioTrackType GetAudioTrackType(uint stream_index);
186 
187  static int GetMaxReferenceFrames(AVCodecContext *Context);
188 
189  protected:
190  int AutoSelectTrack(uint type) override; // DecoderBase
191  void ScanATSCCaptionStreams(int av_index);
192  void UpdateATSCCaptionTracks(void);
193  void UpdateCaptionTracksFromStreams(bool check_608, bool check_708);
194  void ScanTeletextCaptions(int av_index);
195  void ScanRawTextCaptions(int av_stream_index);
196  void ScanDSMCCStreams(void);
197  int AutoSelectAudioTrack(void);
198  int filter_max_ch(const AVFormatContext *ic,
199  const sinfo_vec_t &tracks,
200  const vector<int> &fs,
201  enum AVCodecID codecId = AV_CODEC_ID_NONE,
202  int profile = -1);
203 
204  friend int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic,
205  int flags);
206  friend int open_avf(URLContext *h, const char *filename, int flags);
207  friend int read_avf(URLContext *h, uint8_t *buf, int buf_size);
208  friend int write_avf(URLContext *h, uint8_t *buf, int buf_size);
209  friend int64_t seek_avf(URLContext *h, int64_t offset, int whence);
210  friend int close_avf(URLContext *h);
211 
212  void DecodeDTVCC(const uint8_t *buf, uint buf_size, bool scte);
213  void DecodeCCx08(const uint8_t *buf, uint buf_size, bool scte);
214  void InitByteContext(bool forceseek = false);
215  void InitVideoCodec(AVStream *stream, AVCodecContext *enc,
216  bool selectedStream = false);
217 
219  void MpegPreProcessPkt(AVStream *stream, AVPacket *pkt);
220  int H264PreProcessPkt(AVStream *stream, AVPacket *pkt);
221  bool PreProcessVideoPacket(AVStream *stream, AVPacket *pkt);
222  virtual bool ProcessVideoPacket(AVStream *stream, AVPacket *pkt, bool &Retry);
223  virtual bool ProcessVideoFrame(AVStream *Stream, AVFrame *AvFrame);
224  bool ProcessAudioPacket(AVStream *stream, AVPacket *pkt,
225  DecodeType decodetype);
226  bool ProcessSubtitlePacket(AVStream *stream, AVPacket *pkt);
227  bool ProcessRawTextPacket(AVPacket *pkt);
228  virtual bool ProcessDataPacket(AVStream *curstream, AVPacket *pkt,
229  DecodeType decodetype);
230 
231  void ProcessVBIDataPacket(const AVStream *stream, const AVPacket *pkt);
232  void ProcessDVBDataPacket(const AVStream *stream, const AVPacket *pkt);
233  void ProcessDSMCCPacket(const AVStream *stream, const AVPacket *pkt);
234 
235  void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames) override; // DecoderBase
236 
237  inline bool DecoderWillDownmix(const AVCodecContext *ctx);
238  bool DoPassThrough(const AVCodecParameters *par, bool withProfile=true);
239  bool SetupAudioStream(void);
240  void SetupAudioStreamSubIndexes(int streamIndex);
241  void RemoveAudioStreams();
242 
245  void HandleGopStart(AVPacket *pkt, bool can_reliably_parse_keyframes);
246 
247  bool GenerateDummyVideoFrames(void);
248  bool HasVideo(const AVFormatContext *ic);
249  float GetVideoFrameRate(AVStream *Stream, AVCodecContext *Context, bool Sanitise = false);
250  static void av_update_stream_timings_video(AVFormatContext *ic);
251  static bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec);
252 
253  void UpdateFramesPlayed(void) override; // DecoderBase
254  bool DoRewindSeek(long long desiredFrame) override; // DecoderBase
255  void DoFastForwardSeek(long long desiredFrame, bool &needflush) override; // DecoderBase
256  virtual void StreamChangeCheck(void);
257  virtual void PostProcessTracks(void) { }
258  virtual bool IsValidStream(int /*streamid*/) {return true;}
259 
260  int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size,
261  AVPacket *pkt);
262 
263  virtual int ReadPacket(AVFormatContext *ctx, AVPacket *pkt, bool &storePacket);
264 
266 
268 
270 
271  AVFormatContext *m_ic {nullptr};
272  // AVFormatParameters params;
273 
274  URLContext m_readContext {};
275 
276  int m_frameDecoded {0};
279 
280  struct SwsContext *m_swsCtx {nullptr};
281  bool m_directRendering {false};
282 
283  bool m_noDtsHack {false};
284  bool m_doRewind {false};
285 
286  bool m_gopSet {false};
288  bool m_seenGop {false};
290  int m_seqCount {0};
291 
292  QList<AVPacket*> m_storedPackets;
293 
294  int m_prevGopPos {0};
295 
296  // GetFrame
297  bool m_gotVideoFrame {false};
298  bool m_hasVideo {false};
300  bool m_skipAudio {false};
301  bool m_allowedQuit {false};
302 
303  uint32_t m_startCodeState {0xffffffff};
304 
305  long long m_lastVPts {0};
306  long long m_lastAPts {0};
307  long long m_lastCcPtsu {0};
308  long long m_firstVPts {0};
309  bool m_firstVPtsInuse {false};
310 
311  int64_t m_faultyPts {0};
312  int64_t m_faultyDts {0};
315  bool m_ptsDetected {false};
317  bool m_ptsSelected {true};
318  // set use_frame_timing true to utilize the pts values in returned
319  // frames. Set fale to use deprecated method.
320  bool m_useFrameTiming {false};
321 
322  bool m_forceDtsTimestamps {false};
323 
326 
328  int m_averrorCount {0};
329 
330  // Caption/Subtitle/Teletext decoders
334  CC608Decoder *m_ccd608 {nullptr};
335  CC708Decoder *m_ccd708 {nullptr};
336  TeletextDecoder *m_ttd {nullptr};
337  int m_cc608ParityTable[256] {0};
341  bool m_ccX08InPmt[64+4] {};
345  bool m_ccX08InTracks[64+4] {};
347  QList<StreamInfo> m_pmtTracks;
349  QList<TrackType> m_pmtTrackTypes;
352  QList<StreamInfo> m_streamTracks;
355  QList<TrackType> m_streamTrackTypes;
356 
358  InteractiveTV *m_itv {nullptr};
359 
360  // Audio
361  uint8_t *m_audioSamples {nullptr};
362  bool m_disablePassthru {false};
363 
366 
367  float m_fps {0.0F};
368  bool m_processFrames {true};
369 
370  bool m_streamsChanged { false };
371  bool m_resetHardwareDecoders { false };
372 
373  // Value in milliseconds, from setting AudioReadAhead
374  int m_audioReadAhead {100};
375 };
376 
377 #endif
378 
379 /* vim: set expandtab tabstop=4 shiftwidth=4: */
virtual bool ProcessDataPacket(AVStream *curstream, AVPacket *pkt, DecodeType decodetype)
int AutoSelectTrack(uint type) override
Select best track.
bool ProcessSubtitlePacket(AVStream *stream, AVPacket *pkt)
AudioInfo()=default
bool ProcessAudioPacket(AVStream *stream, AVPacket *pkt, DecodeType decodetype)
void SetDisablePassThrough(bool disable) override
Disables AC3/DTS pass through.
QString GetTrackDesc(uint type, uint trackNo) const override
H264Parser * m_h264Parser
int filter_max_ch(const AVFormatContext *ic, const sinfo_vec_t &tracks, const vector< int > &fs, enum AVCodecID codecId=AV_CODEC_ID_NONE, int profile=-1)
void GetAttachmentData(uint trackNo, QByteArray &filename, QByteArray &data) override
void DecodeDTVCC(const uint8_t *buf, uint buf_size, bool scte)
PlayerFlags
Definition: mythplayer.h:86
uint8_t * m_audioSamples
static void GetDecoders(RenderOptions &opts)
QHash< QString, Action * > Context
Definition: action.h:77
void use_I_forKeyframes(bool val)
Definition: H264Parser.h:188
InteractiveTV * m_itv
MHEG/MHP decoder.
MythCodecID
Definition: mythcodecid.h:10
int AutoSelectAudioTrack(void)
Selects the best audio track.
friend int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic, int flags)
AudioTrackType
Definition: decoderbase.h:55
void RemoveAudioStreams()
remove audio streams from the context used by dvd code during title transitions to remove stale audio...
AVCodecID m_codecId
bool SetVideoByComponentTag(int tag) override
QString GetCodecDecoderName(void) const override
void SetupAudioStreamSubIndexes(int streamIndex)
Reacts to DUAL/STEREO changes on the fly and fix streams.
friend int64_t seek_avf(URLContext *h, int64_t offset, int whence)
int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, AVPacket *pkt)
CC708Decoder * m_ccd708
int OpenFile(RingBuffer *rbuffer, bool novideo, char testbuf[kDecoderProbeBufferSize], int testbufsize=kDecoderProbeBufferSize) override
Open our file and set up or audio and video parameters.
struct AVFrame AVFrame
friend int write_avf(URLContext *h, uint8_t *buf, int buf_size)
virtual bool ProcessVideoPacket(AVStream *stream, AVPacket *pkt, bool &Retry)
AudioInfo m_audioOut
void ForceSetupAudioStream(void) override
QString GetXDS(const QString &key) const override
static bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec)
AudioInfo(AVCodecID id, AudioFormat fmt, int sr, int ch, bool passthru, int original_ch, int profile=0)
static int GetMaxReferenceFrames(AVCodecContext *Context)
virtual int GetTeletextLanguage(uint lang_idx) const
Returns TeleText language.
virtual int GetSubtitleLanguage(uint subtitle_index, uint stream_index)
Returns DVD Subtitle language.
static int FormatToBits(AudioFormat format)
static void av_update_stream_timings_video(AVFormatContext *ic)
void MpegPreProcessPkt(AVStream *stream, AVPacket *pkt)
Preprocess a packet, setting the video parms if necessary.
friend int close_avf(URLContext *h)
int m_cc608ParityTable[256]
int H264PreProcessPkt(AVStream *stream, AVPacket *pkt)
void UpdateFramesPlayed(void) override
bool GetFrame(DecodeType Type, bool &Retry) override
Demux, preprocess and possibly decode a frame of video/audio.
void UpdateCaptionTracksFromStreams(bool check_608, bool check_708)
long long m_lastCcPtsu
void WriteStoredData(RingBuffer *rb, bool storevid, long timecodeOffset) override
This is a No-op for this class.
MythCodecID m_videoCodecId
AVFRingBuffer * m_avfRingBuffer
int m_codecProfile
void HandleGopStart(AVPacket *pkt, bool can_reliably_parse_keyframes)
Update our position map, keyframe distance, and the like.
bool HasVideo(const AVFormatContext *ic)
uint32_t m_startCodeState
bool GetRawAudioState(void) const override
This is a No-op for this class.
Holds information on recordings and videos.
Definition: programinfo.h:67
void SetEof(bool eof) override
bool DoRewind(long long desiredFrame, bool discardFrames=true) override
~AvFormatDecoder() override
QList< TrackType > m_pmtTrackTypes
TrackType (608 or 708) for Captions seen in the PMT descriptor.
friend int read_avf(URLContext *h, uint8_t *buf, int buf_size)
void ProcessVBIDataPacket(const AVStream *stream, const AVPacket *pkt)
Process ivtv proprietary embedded vertical blanking interval captions.
const int kDecoderProbeBufferSize
Definition: decoderbase.h:23
virtual int GetCaptionLanguage(TrackType trackType, int service_num)
Return ATSC Closed Caption Language.
void ProcessDVBDataPacket(const AVStream *stream, const AVPacket *pkt)
Process DVB Teletext.
friend int open_avf(URLContext *h, const char *filename, int flags)
QString toString() const
struct SwsContext * m_swsCtx
void GetChapterTimes(QList< long long > &times) override
void InitVideoCodec(AVStream *stream, AVCodecContext *enc, bool selectedStream=false)
CC608Decoder * m_ccd608
void ScanRawTextCaptions(int av_stream_index)
AVFormatContext * m_ic
bool ProcessRawTextPacket(AVPacket *pkt)
void UpdateATSCCaptionTracks(void)
void DecodeCCx08(const uint8_t *buf, uint buf_size, bool scte)
TrackType
Track types.
Definition: decoderbase.h:26
int SetTrack(uint type, int trackNo) override
A decoder for video files.
void ScanATSCCaptionStreams(int av_index)
long long m_lastAPts
int64_t m_lastPtsForFaultDetection
bool m_ccX08InPmt[64+4]
Lookup table for whether a stream was seen in the PMT entries 0-3 correspond to CEA-608 CC1 through C...
unsigned int uint
Definition: compat.h:140
void SetRawVideoState(bool state) override
This is a No-op for this class.
long long GetChapter(int chapter) override
void HandleStreamChange(void *data)
virtual void StreamChangeCheck(void)
QByteArray GetSubHeader(uint trackNo) const override
bool GetRawVideoState(void) const override
This is a No-op for this class.
virtual int GetAudioLanguage(uint audio_index, uint stream_index)
long long m_firstVPts
int GetTeletextDecoderType(void) const override
AudioFormat format
bool operator==(const AudioInfo &o) const
void DoFastForwardSeek(long long desiredFrame, bool &needflush) override
Seeks to the keyframe just before the desiredFrame if exact seeks is enabled, or the frame just after...
static bool CanHandle(char testbuf[kDecoderProbeBufferSize], const QString &filename, int testbufsize=kDecoderProbeBufferSize)
Perform an av_probe_input_format on the passed data to see if we can decode it with this class.
int64_t m_lastDtsForFaultDetection
void InitByteContext(bool forceseek=false)
int FindStreamInfo(void)
void SetRawAudioState(bool state) override
This is a No-op for this class.
QList< StreamInfo > m_streamTracks
StreamInfo for 608 and 708 Captions seen in the caption stream itself but not seen in the PMT.
long long m_lastVPts
int ScanStreams(bool novideo)
bool SetupAudioStream(void)
Reinitializes audio if it needs to be reinitialized.
void SetIdrOnlyKeyframes(bool value) override
virtual int ReadPacket(AVFormatContext *ctx, AVPacket *pkt, bool &storePacket)
void Reset(bool reset_video_data, bool seek_reset, bool reset_file) override
int GetCurrentChapter(long long framesPlayed) override
VideoFrame * m_decodedVideoFrame
DecodeType
Definition: decoderbase.h:47
void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames) override
int64_t NormalizeVideoTimecode(int64_t timecode) override
bool DoFastForward(long long desiredFrame, bool discardFrames=true) override
Skips ahead or rewinds to desiredFrame.
virtual void PostProcessTracks(void)
QString GetRawEncodingType(void) override
AvFormatDecoder(MythPlayer *parent, const ProgramInfo &pginfo, PlayerFlags flags)
bool m_ccX08InTracks[64+4]
Lookup table for whether a stream is represented in the UI entries 0-3 correspond to CEA-608 CC1 thro...
QList< TrackType > m_streamTrackTypes
TrackType (608 or 708) for Captions seen in the caption stream itself but not seen in the PMT.
PrivateDecoder * m_privateDec
bool GenerateDummyVideoFrames(void)
virtual bool ProcessVideoFrame(AVStream *Stream, AVFrame *AvFrame)
AvFormatDecoder & operator=(const AvFormatDecoder &)=delete
friend void HandleStreamChange(void *data)
TeletextDecoder * m_ttd
bool m_doPassthru
bool SetAudioByComponentTag(int tag) override
QList< AVPacket * > m_storedPackets
void ScanDSMCCStreams(void)
Check to see whether there is a Network Boot Ifo sub-descriptor in the PMT which requires the MHEG ap...
void ScanTeletextCaptions(int av_index)
Implements a file/stream reader/writer.
bool DoRewindSeek(long long desiredFrame) override
bool IsLastFrameKey(void) const override
void AddTextData(unsigned char *buf, int len, int64_t timecode, char type)
vector< StreamInfo > sinfo_vec_t
Definition: decoderbase.h:111
int m_originalChannels
bool DecoderWillDownmix(const AVCodecContext *ctx)
void ProcessDSMCCPacket(const AVStream *stream, const AVPacket *pkt)
Process DSMCC object carousel packet.
bool m_seenGop
A flag to indicate that we've seen a GOP frame. Used in junction with seq_count.
int m_seqCount
A counter used to determine if we need to force a call to HandleGopStart.
QList< StreamInfo > m_pmtTracks
StreamInfo for 608 and 708 Captions seen in the PMT descriptor.
bool DoPassThrough(const AVCodecParameters *par, bool withProfile=true)
MythCodecID GetVideoCodecID(void) const override
int GetNumChapters() override
This is the interface between an MHEG engine and a MythTV TV object.
Definition: interactivetv.h:12
URLContext m_readContext
virtual bool IsValidStream(int)
float GetVideoFrameRate(AVStream *Stream, AVCodecContext *Context, bool Sanitise=false)
long UpdateStoredFrameNum(long frame) override
This is a No-op for this class.
PlayerFlags m_playerFlags
bool PreProcessVideoPacket(AVStream *stream, AVPacket *pkt)
virtual AudioTrackType GetAudioTrackType(uint stream_index)