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
21
22#include "captions/vbilut.h"
23#include "decoderbase.h"
25#include "mpeg/AVCParser.h"
26#include "mythcodeccontext.h"
27#include "mythplayer.h"
28
29class TeletextDecoder;
30class CC608Decoder;
31class CC708Decoder;
32class SubtitleReader;
33class InteractiveTV;
34class MythSqlDatabase;
35
36struct SwsContext;
37
39{
40 public:
41 AudioInfo() = default;
42
43 AudioInfo(AVCodecID id, AudioFormat fmt, int sr, int ch, bool passthru,
44 int original_ch, int profile = 0) :
45 m_codecId(id), format(fmt),
46 m_sampleSize(ch * AudioOutputSettings::SampleSize(fmt)),
48 m_doPassthru(passthru), m_originalChannels(original_ch)
49 {
50 }
51
52 AVCodecID m_codecId {AV_CODEC_ID_NONE};
54 int m_sampleSize {-2};
55 int m_sampleRate {-1};
56 int m_channels {-1};
58 bool m_doPassthru {false};
60
61 bool operator==(const AudioInfo &o) const
62 {
63 return (m_codecId==o.m_codecId && m_channels==o.m_channels &&
68 }
69 QString toString() const
70 {
71 return QString("id(%1) %2Hz %3ch %4bps %5 (profile %6)")
72 .arg(avcodec_get_name(m_codecId),4).arg(m_sampleRate,6)
74 .arg((m_doPassthru) ? "pt":"",3).arg(m_codecProfile);
75 }
76};
77
80{
81 public:
82 AvFormatDecoder(MythPlayer *parent, const ProgramInfo &pginfo,
83 PlayerFlags flags);
84 ~AvFormatDecoder() override;
85
86 // Deleted functions should be public.
87 AvFormatDecoder(const AvFormatDecoder &) = delete; // not copyable
88 AvFormatDecoder &operator=(const AvFormatDecoder &) = delete; // not copyable
89
90 void SetEof(bool eof) override; // DecoderBase
91
93 void CloseCodecs();
94 void CloseContext();
95 void Reset(bool reset_video_data, bool seek_reset,
96 bool reset_file) override; // DecoderBase
97
100 static bool CanHandle(TestBufferVec & testbuf,
101 const QString &filename);
102
104 int OpenFile(MythMediaBuffer *Buffer, bool novideo,
105 TestBufferVec & testbuf) override; // DecoderBase
106
107 bool GetFrame(DecodeType Type, bool &Retry) override; // DecoderBase
108
109 bool IsLastFrameKey(void) const override { return false; } // DecoderBase
110
111 QString GetCodecDecoderName(void) const override; // DecoderBase
112 QString GetRawEncodingType(void) override; // DecoderBase
113 MythCodecID GetVideoCodecID(void) const override { return m_videoCodecId; } // DecoderBase
114
115 void SetDisablePassThrough(bool disable) override; // DecoderBase
116 void ForceSetupAudioStream(void) override; // DecoderBase
117 void AddTextData(unsigned char *buf, int len, int64_t timecode, char type);
118
119 QString GetTrackDesc(uint Type, uint TrackNo) override;
120 int SetTrack(uint Type, int TrackNo) override;
121
122 int ScanStreams(bool novideo);
123
124 int GetNumChapters() override; // DecoderBase
125 void GetChapterTimes(QList<std::chrono::seconds> &times) override; // DecoderBase
126 int GetCurrentChapter(long long framesPlayed) override; // DecoderBase
127 long long GetChapter(int chapter) override; // DecoderBase
128 bool DoRewind(long long desiredFrame, bool discardFrames = true) override; // DecoderBase
129 bool DoFastForward(long long desiredFrame, bool discardFrames = true) override; // DecoderBase
130 void SetIdrOnlyKeyframes(bool value) override // DecoderBase
131 { m_avcParser->use_I_forKeyframes(!value); }
132
133 std::chrono::milliseconds NormalizeVideoTimecode(std::chrono::milliseconds timecode) override; // DecoderBase
134 virtual std::chrono::milliseconds NormalizeVideoTimecode(AVStream *st, std::chrono::milliseconds timecode);
135
136 int GetTeletextDecoderType(void) const override; // DecoderBase
137
138 QString GetXDS(const QString &Key) const override; // DecoderBase
139 QByteArray GetSubHeader(uint TrackNo) override;
140 void GetAttachmentData(uint TrackNo, QByteArray &Filename, QByteArray &Data) override; // DecoderBase
141
142 // MHEG stuff
143 bool SetAudioByComponentTag(int Tag) override; // DecoderBase
144 bool SetVideoByComponentTag(int Tag) override; // DecoderBase
145
146 // Stream language info
147 virtual int GetTeletextLanguage(uint Index);
148 virtual int GetSubtitleLanguage(uint /*unused*/, uint StreamIndex);
149 virtual int GetCaptionLanguage(TrackType TrackType, int ServiceNum);
150 virtual int GetAudioLanguage(uint AudioIndex, uint StreamIndex);
151 virtual AudioTrackType GetAudioTrackType(uint StreamIndex);
152
153 static int GetMaxReferenceFrames(AVCodecContext *Context);
154
155 static void streams_changed(void *data, int avprogram_id);
156
157 protected:
158 int AutoSelectTrack(uint type) override; // DecoderBase
159 void ScanATSCCaptionStreams(int av_index);
160 void UpdateATSCCaptionTracks(void);
161 void UpdateCaptionTracksFromStreams(bool check_608, bool check_708);
162 void ScanTeletextCaptions(int av_index);
163 void ScanRawTextCaptions(int av_stream_index);
164 void ScanDSMCCStreams(AVBufferRef* pmt_section);
165 int AutoSelectAudioTrack(void);
166 int filter_max_ch(const AVFormatContext *ic,
167 const sinfo_vec_t &tracks,
168 const std::vector<int>&fs,
169 enum AVCodecID codecId = AV_CODEC_ID_NONE,
170 int profile = -1);
171 int selectBestAudioTrack(int lang_key, const std::vector<int> &ftype);
172
173 friend int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic,
174 int flags);
175
176 void DecodeCCx08(const uint8_t *buf, uint buf_size);
177 void InitVideoCodec(AVStream *stream, AVCodecContext *codecContext,
178 bool selectedStream = false);
179
181 void MpegPreProcessPkt(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt);
182 int H264PreProcessPkt(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt);
183 bool PreProcessVideoPacket(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt);
184 virtual bool ProcessVideoPacket(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt, bool &Retry);
185 virtual bool ProcessVideoFrame(AVCodecContext* codecContext, AVStream *Stream, AVFrame *AvFrame);
186 bool ProcessAudioPacket(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt,
187 DecodeType decodetype);
188 bool ProcessSubtitlePacket(AVCodecContext* codecContext, AVStream *stream, AVPacket *pkt);
189 bool ProcessRawTextPacket(AVPacket* Packet);
190 virtual bool ProcessDataPacket(AVStream *curstream, AVPacket *pkt,
191 DecodeType decodetype);
192
193 void ProcessVBIDataPacket(const AVStream *stream, const AVPacket *pkt);
194 void ProcessDVBDataPacket(const AVStream *stream, const AVPacket *pkt);
195 void ProcessDSMCCPacket(const AVStream *stream, const AVPacket *pkt);
196
197 void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames) override; // DecoderBase
198
199 inline bool DecoderWillDownmix(const AVCodecContext *ctx);
200 bool DoPassThrough(const AVCodecParameters *par, bool withProfile=true);
201 bool SetupAudioStream(void);
202 void SetupAudioStreamSubIndexes(int streamIndex);
203 void RemoveAudioStreams();
204
207 void HandleGopStart(AVPacket *pkt, bool can_reliably_parse_keyframes);
208
209 bool GenerateDummyVideoFrames(void);
210 bool HasVideo();
211 float GetVideoFrameRate(AVStream *Stream, AVCodecContext *Context, bool Sanitise = false);
212 static void av_update_stream_timings_video(AVFormatContext *ic);
213 bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec);
214
215 void UpdateFramesPlayed(void) override; // DecoderBase
216 bool DoRewindSeek(long long desiredFrame) override; // DecoderBase
217 void DoFastForwardSeek(long long desiredFrame, bool &needflush) override; // DecoderBase
218 virtual void StreamChangeCheck(void);
219 virtual void PostProcessTracks(void) { }
220 virtual bool IsValidStream(int /*streamid*/) {return true;}
221
222 int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size,
223 AVPacket *pkt);
224
225 virtual int ReadPacket(AVFormatContext *ctx, AVPacket *pkt, bool &storePacket);
226
227 bool FlagIsSet(PlayerFlags arg) { return m_playerFlags & arg; }
228
229 int autoSelectVideoTrack(int& scanerror);
230 void remove_tracks_not_in_same_AVProgram(int stream_index);
231
233 AVProgram* get_current_AVProgram();
234
235 bool do_av_seek(long long desiredFrame, bool discardFrames, int flags);
236
238
240
241 AVFormatContext *m_ic {nullptr};
243
244 // AVFormatParameters params;
245
249
250 struct SwsContext *m_swsCtx {nullptr};
251 bool m_directRendering {false};
252
253 bool m_gopSet {false};
255 bool m_seenGop {false};
257 int m_seqCount {0};
258
259 QList<AVPacket*> m_storedPackets;
260
262
263 // GetFrame
264 bool m_gotVideoFrame {false};
265 bool m_hasVideo {false};
267 bool m_skipAudio {false};
268 bool m_allowedQuit {false};
269
270 uint32_t m_startCodeState {0xffffffff};
271
272 std::chrono::milliseconds m_lastVPts {0ms};
273 std::chrono::milliseconds m_lastAPts {0ms};
274 std::chrono::microseconds m_lastCcPtsu {0ms};
275 std::chrono::milliseconds m_firstVPts {0ms};
276 bool m_firstVPtsInuse {false};
277
280
283
284 // Caption/Subtitle/Teletext decoders
291 std::array<bool,68> m_ccX08InPmt {};
295 std::array<bool,68> m_ccX08InTracks {};
297 QList<StreamInfo> m_pmtTracks;
299 QList<TrackType> m_pmtTrackTypes;
302 QList<StreamInfo> m_streamTracks;
305 QList<TrackType> m_streamTrackTypes;
306
309
310 // Audio
311 uint8_t *m_audioSamples {nullptr};
312 bool m_disablePassthru {false};
313
316
317 bool m_processFrames {true};
318
319 bool m_streamsChanged { false };
321
322 // Value in milliseconds, from setting AudioReadAhead
323 std::chrono::milliseconds m_audioReadAhead {100ms};
324
325 QRecursiveMutex m_avCodecLock;
326};
327
328#endif
329
330/* 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: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
unsigned int uint
Definition: freesurround.h:24
MythCodecID
Definition: mythcodecid.h:14
@ kCodec_NONE
Definition: mythcodecid.h:17
PlayerFlags
Definition: mythplayer.h:65