MythTV master
avformatdecoder.h
Go to the documentation of this file.
1
2#ifndef AVFORMATDECODER_H_
3#define AVFORMATDECODER_H_
4
5#include <array>
6#include <cstdint>
7
8extern "C" {
9#include "libavcodec/avcodec.h"
10#include "libavformat/avformat.h"
11}
12
13#include <QList>
14#include <QMap>
15#include <QString>
16
18#include "captions/vbilut.h"
19#include "decoderbase.h"
21#include "mpeg/AVCParser.h"
22#include "mythcodeccontext.h"
23#include "mythplayer.h"
24#include "programinfo.h"
25
26class TeletextDecoder;
27class CC608Decoder;
28class CC708Decoder;
29class SubtitleReader;
30class InteractiveTV;
31class MythSqlDatabase;
32
33struct SwsContext;
34
36{
37 public:
38 AudioInfo() = default;
39
40 AudioInfo(AVCodecID id, AudioFormat fmt, int sr, int ch, bool passthru,
41 int original_ch, int profile = 0) :
42 m_codecId(id), format(fmt),
43 m_sampleSize(ch * AudioOutputSettings::SampleSize(fmt)),
45 m_doPassthru(passthru), m_originalChannels(original_ch)
46 {
47 }
48
49 AVCodecID m_codecId {AV_CODEC_ID_NONE};
51 int m_sampleSize {-2};
52 int m_sampleRate {-1};
53 int m_channels {-1};
55 bool m_doPassthru {false};
57
58 bool operator==(const AudioInfo &o) const
59 {
60 return (m_codecId==o.m_codecId && m_channels==o.m_channels &&
65 }
66 QString toString() const
67 {
68 return QString("id(%1) %2Hz %3ch %4bps %5 (profile %6)")
69 .arg(avcodec_get_name(m_codecId),4).arg(m_sampleRate,6)
71 .arg((m_doPassthru) ? "pt":"",3).arg(m_codecProfile);
72 }
73};
74
77{
78 public:
79 AvFormatDecoder(MythPlayer *parent, const ProgramInfo &pginfo,
80 PlayerFlags flags);
81 ~AvFormatDecoder() override;
82
83 // Deleted functions should be public.
84 AvFormatDecoder(const AvFormatDecoder &) = delete; // not copyable
85 AvFormatDecoder &operator=(const AvFormatDecoder &) = delete; // not copyable
86
87 void SetEof(bool eof) override; // DecoderBase
88
90 void CloseCodecs();
91 void CloseContext();
92 void Reset(bool reset_video_data, bool seek_reset,
93 bool reset_file) override; // DecoderBase
94
97 static bool CanHandle(TestBufferVec & testbuf,
98 const QString &filename);
99
101 int OpenFile(MythMediaBuffer *Buffer, bool novideo,
102 TestBufferVec & testbuf) override; // DecoderBase
103
104 bool GetFrame(DecodeType Type, bool &Retry) override; // DecoderBase
105
106 bool IsLastFrameKey(void) const override { return false; } // DecoderBase
107
108 QString GetCodecDecoderName(void) const override; // DecoderBase
109 QString GetRawEncodingType(void) override; // DecoderBase
110 MythCodecID GetVideoCodecID(void) const override { return m_videoCodecId; } // DecoderBase
111
112 void SetDisablePassThrough(bool disable) override; // DecoderBase
113 void ForceSetupAudioStream(void) override; // DecoderBase
114 void AddTextData(unsigned char *buf, int len, int64_t timecode, char type);
115
116 QString GetTrackDesc(uint Type, uint TrackNo) override;
117 int SetTrack(uint Type, int TrackNo) override;
118
119 int ScanStreams(bool novideo);
120
121 int GetNumChapters() override; // DecoderBase
122 void GetChapterTimes(QList<std::chrono::seconds> &times) override; // DecoderBase
123 int GetCurrentChapter(long long framesPlayed) override; // DecoderBase
124 long long GetChapter(int chapter) override; // DecoderBase
125 bool DoRewind(long long desiredFrame, bool discardFrames = true) override; // DecoderBase
126 bool DoFastForward(long long desiredFrame, bool discardFrames = true) override; // DecoderBase
127 void SetIdrOnlyKeyframes(bool value) override // DecoderBase
128 { m_avcParser->use_I_forKeyframes(!value); }
129
130 std::chrono::milliseconds NormalizeVideoTimecode(std::chrono::milliseconds timecode) override; // DecoderBase
131 virtual std::chrono::milliseconds NormalizeVideoTimecode(AVStream *st, std::chrono::milliseconds timecode);
132
133 int GetTeletextDecoderType(void) const override; // DecoderBase
134
135 QString GetXDS(const QString &Key) const override; // DecoderBase
136 QByteArray GetSubHeader(uint TrackNo) override;
137 void GetAttachmentData(uint TrackNo, QByteArray &Filename, QByteArray &Data) override; // DecoderBase
138
139 // MHEG stuff
140 bool SetAudioByComponentTag(int Tag) override; // DecoderBase
141 bool SetVideoByComponentTag(int Tag) override; // DecoderBase
142
143 // Stream language info
144 virtual int GetTeletextLanguage(uint Index);
145 virtual int GetSubtitleLanguage(uint /*unused*/, uint StreamIndex);
146 virtual int GetCaptionLanguage(TrackType TrackType, int ServiceNum);
147 virtual int GetAudioLanguage(uint AudioIndex, uint StreamIndex);
148 virtual AudioTrackType GetAudioTrackType(uint StreamIndex);
149
150 static int GetMaxReferenceFrames(AVCodecContext *Context);
151
152 static void streams_changed(void *data, int avprogram_id);
153
154 protected:
155 int AutoSelectTrack(uint type) override; // DecoderBase
156 void ScanATSCCaptionStreams(int av_index);
157 void UpdateATSCCaptionTracks(void);
158 void UpdateCaptionTracksFromStreams(bool check_608, bool check_708);
159 void ScanTeletextCaptions(int av_index);
160 void ScanRawTextCaptions(int av_stream_index);
161 void ScanDSMCCStreams(AVBufferRef* pmt_section);
162 int AutoSelectAudioTrack(void);
163 int filter_max_ch(const AVFormatContext *ic,
164 const sinfo_vec_t &tracks,
165 const std::vector<int>&fs,
166 enum AVCodecID codecId = AV_CODEC_ID_NONE,
167 int profile = -1);
168 int selectBestAudioTrack(int lang_key, const std::vector<int> &ftype);
169
170 friend int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic,
171 int flags);
172
173 void DecodeCCx08(const uint8_t *buf, uint buf_size);
174 void InitVideoCodec(AVStream *stream, AVCodecContext *codecContext,
175 bool selectedStream = false);
176
178 void MpegPreProcessPkt(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt);
179 int H264PreProcessPkt(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt);
180 bool PreProcessVideoPacket(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt);
181 virtual bool ProcessVideoPacket(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt, bool &Retry);
182 virtual bool ProcessVideoFrame(AVCodecContext* codecContext, AVStream *Stream, AVFrame *AvFrame);
183 bool ProcessAudioPacket(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt,
184 DecodeType decodetype);
185 bool ProcessSubtitlePacket(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt);
186 bool ProcessRawTextPacket(AVPacket* Packet);
187 virtual bool ProcessDataPacket(AVStream *curstream, AVPacket *pkt,
188 DecodeType decodetype);
189
190 void ProcessVBIDataPacket(const AVStream *stream, const AVPacket *pkt);
191 void ProcessDVBDataPacket(const AVStream *stream, const AVPacket *pkt);
192 void ProcessDSMCCPacket(const AVStream *stream, const AVPacket *pkt);
193
194 void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames) override; // DecoderBase
195
196 inline bool DecoderWillDownmix(const AVCodecContext *ctx);
197 bool DoPassThrough(const AVCodecParameters *par, bool withProfile=true);
198 bool SetupAudioStream(void);
199 void SetupAudioStreamSubIndexes(int streamIndex);
200 void RemoveAudioStreams();
201
204 void HandleGopStart(AVPacket *pkt, bool can_reliably_parse_keyframes);
205
206 bool GenerateDummyVideoFrames(void);
207 bool HasVideo();
208 float GetVideoFrameRate(AVStream *Stream, AVCodecContext *Context, bool Sanitise = false);
209 static void av_update_stream_timings_video(AVFormatContext *ic);
210 bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec);
211
212 void UpdateFramesPlayed(void) override; // DecoderBase
213 bool DoRewindSeek(long long desiredFrame) override; // DecoderBase
214 void DoFastForwardSeek(long long desiredFrame, bool &needflush) override; // DecoderBase
215 virtual void StreamChangeCheck(void);
216 virtual void PostProcessTracks(void) { }
217 virtual bool IsValidStream(int /*streamid*/) {return true;}
218
219 int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size,
220 AVPacket *pkt);
221
222 virtual int ReadPacket(AVFormatContext *ctx, AVPacket *pkt, bool &storePacket);
223
224 bool FlagIsSet(PlayerFlags arg) { return m_playerFlags & arg; }
225
226 int autoSelectVideoTrack(int& scanerror);
227 void remove_tracks_not_in_same_AVProgram(int stream_index);
228
230 AVProgram* get_current_AVProgram();
231
232 bool do_av_seek(long long desiredFrame, bool discardFrames, int flags);
233
235
237
238 AVFormatContext *m_ic {nullptr};
240
241 // AVFormatParameters params;
242
246
247 struct SwsContext *m_swsCtx {nullptr};
248 bool m_directRendering {false};
249
250 bool m_gopSet {false};
252 bool m_seenGop {false};
254 int m_seqCount {0};
255
256 QList<AVPacket*> m_storedPackets;
257
259
260 // GetFrame
261 bool m_gotVideoFrame {false};
262 bool m_hasVideo {false};
264 bool m_skipAudio {false};
265 bool m_allowedQuit {false};
266
267 uint32_t m_startCodeState {0xffffffff};
268
269 std::chrono::milliseconds m_lastVPts {0ms};
270 std::chrono::milliseconds m_lastAPts {0ms};
271 std::chrono::microseconds m_lastCcPtsu {0ms};
272 std::chrono::milliseconds m_firstVPts {0ms};
273 bool m_firstVPtsInuse {false};
274
277
280
281 // Caption/Subtitle/Teletext decoders
288 std::array<bool,68> m_ccX08InPmt {};
292 std::array<bool,68> m_ccX08InTracks {};
294 QList<StreamInfo> m_pmtTracks;
296 QList<TrackType> m_pmtTrackTypes;
299 QList<StreamInfo> m_streamTracks;
302 QList<TrackType> m_streamTrackTypes;
303
306
307 // Audio
308 uint8_t *m_audioSamples {nullptr};
309 bool m_disablePassthru {false};
310
313
314 bool m_processFrames {true};
315
316 bool m_streamsChanged { false };
318
319 // Value in milliseconds, from setting AudioReadAhead
320 std::chrono::milliseconds m_audioReadAhead {100ms};
321
322 QRecursiveMutex m_avCodecLock;
323};
324
325#endif
326
327/* vim: set expandtab tabstop=4 shiftwidth=4: */
AVFrame AVFrame
@ FORMAT_NONE
void use_I_forKeyframes(bool val)
Definition: AVCParser.h:99
int m_originalChannels
bool operator==(const AudioInfo &o) const
QString toString() const
AVCodecID m_codecId
int m_codecProfile
AudioInfo()=default
AudioInfo(AVCodecID id, AudioFormat fmt, int sr, int ch, bool passthru, int original_ch, int profile=0)
bool m_doPassthru
AudioFormat format
static int FormatToBits(AudioFormat format)
A decoder for media files.
long long GetChapter(int chapter) override
uint8_t * m_audioSamples
std::chrono::milliseconds m_lastAPts
bool ProcessAudioPacket(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt, DecodeType decodetype)
MythCodecMap * CodecMap(void)
void ProcessVBIDataPacket(const AVStream *stream, const AVPacket *pkt)
Process ivtv proprietary embedded vertical blanking interval captions.
bool DecoderWillDownmix(const AVCodecContext *ctx)
QList< StreamInfo > m_streamTracks
StreamInfo for 608 and 708 Captions seen in the caption stream itself but not seen in the PMT.
int selectBestAudioTrack(int lang_key, const std::vector< int > &ftype)
void UpdateCaptionTracksFromStreams(bool check_608, bool check_708)
bool GenerateDummyVideoFrames(void)
int GetCurrentChapter(long long framesPlayed) override
AVFormatContext * m_ic
std::chrono::milliseconds m_lastVPts
void Reset(bool reset_video_data, bool seek_reset, bool reset_file) override
InteractiveTV * m_itv
MHEG/MHP decoder.
bool GetFrame(DecodeType Type, bool &Retry) override
Demux, preprocess and possibly decode a frame of video/audio.
PlayerFlags m_playerFlags
void SetIdrOnlyKeyframes(bool value) override
int GetTeletextDecoderType(void) const override
static int GetMaxReferenceFrames(AVCodecContext *Context)
void ForceSetupAudioStream(void) override
bool ProcessSubtitlePacket(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt)
QString GetTrackDesc(uint Type, uint TrackNo) override
CC608Decoder * m_ccd608
bool DoPassThrough(const AVCodecParameters *par, bool withProfile=true)
QList< TrackType > m_streamTrackTypes
TrackType (608 or 708) for Captions seen in the caption stream itself but not seen in the PMT.
QString GetCodecDecoderName(void) const override
virtual int GetCaptionLanguage(TrackType TrackType, int ServiceNum)
Return ATSC Closed Caption Language.
std::array< bool, 68 > m_ccX08InPmt
Lookup table for whether a stream was seen in the PMT entries 0-3 correspond to CEA-608 CC1 through C...
virtual int GetAudioLanguage(uint AudioIndex, uint StreamIndex)
AvFormatDecoder(const AvFormatDecoder &)=delete
friend int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic, int flags)
CC708Decoder * m_ccd708
int AutoSelectTrack(uint type) override
Select best track.
QList< TrackType > m_pmtTrackTypes
TrackType (608 or 708) for Captions seen in the PMT descriptor.
QString GetXDS(const QString &Key) const override
AVCParser * m_avcParser
MythAVFormatBuffer * m_avfRingBuffer
void RemoveAudioStreams()
remove audio streams from the context used by dvd code during title transitions to remove stale audio...
std::array< bool, 68 > m_ccX08InTracks
Lookup table for whether a stream is represented in the UI entries 0-3 correspond to CEA-608 CC1 thro...
void DecodeCCx08(const uint8_t *buf, uint buf_size)
bool do_av_seek(long long desiredFrame, bool discardFrames, int flags)
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...
int m_seqCount
A counter used to determine if we need to force a call to HandleGopStart.
void SetupAudioStreamSubIndexes(int streamIndex)
Reacts to DUAL/STEREO changes on the fly and fix streams.
void ScanTeletextCaptions(int av_index)
bool FlagIsSet(PlayerFlags arg)
void GetChapterTimes(QList< std::chrono::seconds > &times) override
AudioInfo m_audioOut
virtual void StreamChangeCheck(void)
void InitVideoCodec(AVStream *stream, AVCodecContext *codecContext, bool selectedStream=false)
int ScanStreams(bool novideo)
void ScanRawTextCaptions(int av_stream_index)
void AddTextData(unsigned char *buf, int len, int64_t timecode, char type)
void ScanDSMCCStreams(AVBufferRef *pmt_section)
Check to see whether there is a Network Boot Ifo sub-descriptor in the PMT which requires the MHEG ap...
AvFormatDecoder & operator=(const AvFormatDecoder &)=delete
int SetTrack(uint Type, int TrackNo) override
std::chrono::milliseconds m_firstVPts
bool SetAudioByComponentTag(int Tag) override
int AutoSelectAudioTrack(void)
Selects the best audio track.
void ScanATSCCaptionStreams(int av_index)
virtual void PostProcessTracks(void)
int filter_max_ch(const AVFormatContext *ic, const sinfo_vec_t &tracks, const std::vector< int > &fs, enum AVCodecID codecId=AV_CODEC_ID_NONE, int profile=-1)
bool IsLastFrameKey(void) const override
QList< AVPacket * > m_storedPackets
AVProgram * get_current_AVProgram()
void SetDisablePassThrough(bool disable) override
Disables AC3/DTS pass through.
void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames) override
void HandleGopStart(AVPacket *pkt, bool can_reliably_parse_keyframes)
Update our position map, keyframe distance, and the like.
int GetNumChapters() override
void UpdateATSCCaptionTracks(void)
bool PreProcessVideoPacket(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt)
virtual AudioTrackType GetAudioTrackType(uint StreamIndex)
void MpegPreProcessPkt(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt)
Preprocess a packet, setting the video parms if necessary.
QByteArray GetSubHeader(uint TrackNo) override
bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec)
MythCodecID m_videoCodecId
virtual int GetSubtitleLanguage(uint, uint StreamIndex)
Returns DVD Subtitle language.
void UpdateFramesPlayed(void) override
virtual bool ProcessDataPacket(AVStream *curstream, AVPacket *pkt, DecodeType decodetype)
static void av_update_stream_timings_video(AVFormatContext *ic)
AvFormatDecoder(MythPlayer *parent, const ProgramInfo &pginfo, PlayerFlags flags)
MythCodecMap m_codecMap
TeletextDecoder * m_ttd
int OpenFile(MythMediaBuffer *Buffer, bool novideo, TestBufferVec &testbuf) override
Open our file and set up or audio and video parameters.
void ProcessDSMCCPacket(const AVStream *stream, const AVPacket *pkt)
Process DSMCC object carousel packet.
int autoSelectVideoTrack(int &scanerror)
QRecursiveMutex m_avCodecLock
virtual int GetTeletextLanguage(uint Index)
Returns TeleText language.
void GetAttachmentData(uint TrackNo, QByteArray &Filename, QByteArray &Data) override
void ProcessDVBDataPacket(const AVStream *stream, const AVPacket *pkt)
Process DVB Teletext.
uint32_t m_startCodeState
struct SwsContext * m_swsCtx
int get_current_AVStream_index(TrackType type)
bool DoRewindSeek(long long desiredFrame) override
bool DoRewind(long long desiredFrame, bool discardFrames=true) override
virtual int ReadPacket(AVFormatContext *ctx, AVPacket *pkt, bool &storePacket)
int H264PreProcessPkt(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt)
bool SetupAudioStream(void)
Reinitializes audio if it needs to be reinitialized.
int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, AVPacket *pkt)
virtual bool IsValidStream(int)
std::chrono::milliseconds m_audioReadAhead
QString GetRawEncodingType(void) override
bool ProcessRawTextPacket(AVPacket *Packet)
~AvFormatDecoder() override
MythCodecID GetVideoCodecID(void) const override
std::chrono::milliseconds NormalizeVideoTimecode(std::chrono::milliseconds timecode) override
virtual bool ProcessVideoFrame(AVCodecContext *codecContext, AVStream *Stream, AVFrame *AvFrame)
void SetEof(bool eof) override
bool SetVideoByComponentTag(int Tag) override
static bool CanHandle(TestBufferVec &testbuf, const QString &filename)
Perform an av_probe_input_format on the passed data to see if we can decode it with this class.
void remove_tracks_not_in_same_AVProgram(int stream_index)
virtual bool ProcessVideoPacket(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt, bool &Retry)
float GetVideoFrameRate(AVStream *Stream, AVCodecContext *Context, bool Sanitise=false)
bool DoFastForward(long long desiredFrame, bool discardFrames=true) override
Skips ahead or rewinds to desiredFrame.
std::chrono::microseconds m_lastCcPtsu
static void streams_changed(void *data, int avprogram_id)
bool m_seenGop
A flag to indicate that we've seen a GOP frame. Used in junction with seq_count.
QList< StreamInfo > m_pmtTracks
StreamInfo for 608 and 708 Captions seen in the PMT descriptor.
MythVideoFrame * m_decodedVideoFrame
This is the interface between an MHEG engine and a MythTV TV object.
Definition: interactivetv.h:18
Holds information on recordings and videos.
Definition: programinfo.h:70
unsigned int uint
Definition: compat.h:68
AudioTrackType
Definition: decoderbase.h:56
std::vector< char > TestBufferVec
Definition: decoderbase.h:23
std::vector< StreamInfo > sinfo_vec_t
Definition: decoderbase.h:118
TrackType
Track types.
Definition: decoderbase.h:27
DecodeType
Definition: decoderbase.h:48
MythCodecID
Definition: mythcodecid.h:14
@ kCodec_NONE
Definition: mythcodecid.h:17
PlayerFlags
Definition: mythplayer.h:64