MythTV  master
mpeg2fix.h
Go to the documentation of this file.
1 // POSIX
2 #include <pthread.h>
3 
4 // C
5 #include <cstdlib>
6 
7 #include "mythconfig.h"
8 
9 extern "C"
10 {
11 //AVFormat/AVCodec
12 #include "libavcodec/avcodec.h"
13 #include "libavformat/avformat.h"
14 
15 //replex
18 
19 //libmpeg2
20 #include "config.h"
21 #if CONFIG_LIBMPEG2EXTERNAL
22 #include <mpeg2dec/mpeg2.h>
23 #else
24 #include "mpeg2.h"
25 #endif
26 }
27 
28 //Qt
29 #include <QMap>
30 #include <QList>
31 #include <QQueue>
32 #include <QStringList>
33 #include <QDateTime>
34 
35 // MythTV
36 #include "transcodedefs.h"
37 #include "programtypes.h"
38 #include "mythavutil.h"
39 
43 };
44 
46 {
47  public:
48  explicit MPEG2frame(int size);
49  ~MPEG2frame();
50  void ensure_size(int size);
51  void set_pkt(AVPacket *newpkt);
52 
53  AVPacket m_pkt;
54  bool m_isSequence {false};
55  bool m_isGop {false};
56  uint8_t *m_framePos {nullptr};
57  uint8_t *m_gopPos {nullptr};
58  mpeg2_sequence_t m_mpeg2_seq;
59  mpeg2_gop_t m_mpeg2_gop;
60  mpeg2_picture_t m_mpeg2_pic;
61 };
62 
63 typedef struct {
64  int64_t newPTS;
65  int64_t pos_pts;
66  int framenum;
67  bool type;
68 } poq_idx_t;
69 
71 {
72  public:
73  PTSOffsetQueue(int vidid, QList<int> keys, int64_t initPTS);
74  void SetNextPTS(int64_t newPTS, int64_t atPTS);
75  void SetNextPos(int64_t newPTS, AVPacket *pkt);
76  int64_t Get(int idx, AVPacket *pkt);
77  int64_t UpdateOrigPTS(int idx, int64_t &origPTS, AVPacket *pkt);
78  private:
79  QMap<int, QList<poq_idx_t> > m_offset;
80  QMap<int, QList<poq_idx_t> > m_orig;
81  QList<int> m_keyList;
82  int m_vid_id;
83 };
84 
85 //container for all multiplex related variables
87 {
88  public:
89  MPEG2replex() = default;
90  ~MPEG2replex();
91  void Start();
92  int WaitBuffers();
93  int m_done {0};
94  QString m_outfile;
95  int m_otype {0};
100  int m_ext_count {0};
101  int m_exttype[N_AUDIO] {0};
103 
104  pthread_mutex_t m_mutex {};
105  pthread_cond_t m_cond {};
108 
109  private:
110  multiplex_t *m_mplex {nullptr};
111 };
112 
113 typedef QList<MPEG2frame *> FrameList;
114 typedef QQueue<MPEG2frame *> FrameQueue;
115 typedef QMap<int, FrameList *> FrameMap;
116 
118 {
119  public:
120  MPEG2fixup(const QString &inf, const QString &outf,
121  frm_dir_map_t *deleteMap, const char *fmt, int norp,
122  int fixPTS, int maxf, bool showprog, int otype,
123  void (*update_func)(float) = nullptr, int (*check_func)() = nullptr);
124  ~MPEG2fixup();
125  int Start();
126  void AddRangeList(QStringList rangelist, int type);
127  static void ShowRangeMap(frm_dir_map_t *mapPtr, QString msg);
128  int BuildKeyframeIndex(QString &file, frm_pos_map_t &posMap, frm_pos_map_t &durMap);
129 
130  void SetAllAudio(bool keep) { m_allaudio = keep; }
131 
132  static void dec2x33(int64_t *pts1, int64_t pts2);
133  static void inc2x33(int64_t *pts1, int64_t pts2);
134  static int64_t udiff2x33(int64_t pts1, int64_t pts2);
135  static int64_t diff2x33(int64_t pts1, int64_t pts2);
136  static int64_t add2x33(int64_t pts1, int64_t pts2);
137  static int cmp2x33(int64_t pts1, int64_t pts2);
138 
139  protected:
140  static void *ReplexStart(void *data);
142 
143  private:
144  static int FindMPEG2Header(const uint8_t *buf, int size, uint8_t code);
145  void InitReplex();
146  void FrameInfo(MPEG2frame *f);
147  int AddFrame(MPEG2frame *f);
148  bool InitAV(const QString& inputfile, const char *type, int64_t offset);
149  void ScanAudio();
150  int ProcessVideo(MPEG2frame *vf, mpeg2dec_t *dec);
151  void WriteFrame(const QString& filename, MPEG2frame *f);
152  void WriteFrame(const QString& filename, AVPacket *pkt);
153  static void WriteYUV(const QString& filename, const mpeg2_info_t *info);
154  static void WriteData(const QString& filename, uint8_t *data, int size);
155  bool BuildFrame(AVPacket *pkt, const QString& fname);
156  MPEG2frame *GetPoolFrame(AVPacket *pkt);
158  int GetFrame(AVPacket *pkt);
159  bool FindStart();
160  static void SetRepeat(MPEG2frame *vf, int nb_fields, bool topff);
161  static void SetRepeat(uint8_t *ptr, int size, int fields, bool topff);
162  MPEG2frame *FindFrameNum(int frameNum);
163  void RenumberFrames(int start_pos, int delta);
164  void StoreSecondary();
165  int PlaybackSecondary();
166  MPEG2frame *DecodeToFrame(int frameNum, int skip_reset);
167  int ConvertToI(FrameList *orderedFrames, int headPos);
168  int InsertFrame(int frameNum, int64_t deltaPTS,
169  int64_t ptsIncrement, int64_t initPTS);
170  void AddSequence(MPEG2frame *frame1, MPEG2frame *frame2);
171  static FrameList ReorderDTStoPTS(FrameList *dtsOrder, int pos);
172  void InitialPTSFixup(MPEG2frame *curFrame, int64_t &origvPTS,
173  int64_t &PTSdiscrep, int numframes, bool fix);
174  static void SetFrameNum(uint8_t *ptr, int num);
175  static int GetFrameNum(const MPEG2frame *frame)
176  {
177  return frame->m_mpeg2_pic.temporal_reference;
178  }
179  static int GetFrameTypeN(const MPEG2frame *frame)
180  {
181  return frame->m_mpeg2_pic.flags & PIC_MASK_CODING_TYPE;
182  }
183  static char GetFrameTypeT(const MPEG2frame *frame)
184  {
185  int type = GetFrameTypeN(frame);
186  return (type == 1 ? 'I' :
187  (type == 2 ? 'P' : (type == 3 ? 'B' : 'X')));
188  }
189  static int GetNbFields(const MPEG2frame *frame)
190  {
191  return frame->m_mpeg2_pic.nb_fields;
192  }
193  int GetStreamType(int id) const
194  {
195  return (m_inputFC->streams[id]->codecpar->codec_id == AV_CODEC_ID_AC3) ?
196  AV_CODEC_ID_AC3 : AV_CODEC_ID_MP2;
197  }
198  AVCodecContext *getCodecContext(uint id)
199  {
200  if (id >= m_inputFC->nb_streams)
201  return nullptr;
202  return gCodecMap->getCodecContext(m_inputFC->streams[id]);
203  }
204  AVCodecParserContext *getCodecParserContext(uint id)
205  {
206  if (id >= m_inputFC->nb_streams)
207  return nullptr;
208  return m_inputFC->streams[id]->parser;
209  }
210 
211  static void dumpList(FrameList *list);
212 
213  int (*check_abort)() {nullptr};
214  void (*update_status)(float percent_done) {nullptr};
215 
217  bool m_use_secondary {false};
218 
223  int m_displayFrame {0};
224  mpeg2dec_t *m_header_decoder {nullptr};
225  mpeg2dec_t *m_img_decoder {nullptr};
226 
229 
230  pthread_t m_thread {};
231 
232  AVFormatContext *m_inputFC {nullptr};
233  AVFrame *m_picture {nullptr};
234 
235  int m_vid_id {-1};
236  int m_ext_count {0};
237  QMap <int, int> m_aud_map;
238  int64_t m_ptsIncrement {0};
239  bool m_mkvfile {false};
240 
241  bool m_discard {false};
242  //control options
244  QString m_infile;
245  const char *m_format {nullptr};
246  bool m_allaudio {false};
247 
248  //complete?
249  bool m_file_end {false};
250  bool m_real_file_end {false};
251 
252  //progress indicators
253  QDateTime m_statustime;
254  bool m_showprogress {false};
255  uint64_t m_filesize {0};
256  int m_framenum {0};
258  uint64_t m_last_written_pos {0};
260  bool m_zigzag_init {false};
261 };
262 
263 #ifdef NO_MYTH
264  #include <QDateTime>
265  #include <iostream>
266 
267  using namespace std;
268 
269  extern int verboseMask;
270  #undef LOG
271  #define LOG(mask,level,args...) \
272  do { \
273  if ((verboseMask & mask) != 0) \
274  { \
275  cout << args << endl; \
276  } \
277  } while (0)
278 
279  // Be sure to keep these the same as in libmythbase/exitcodes.h or expect
280  // odd behavior eventually
281  #define GENERIC_EXIT_OK 0
282  #define GENERIC_EXIT_NOT_OK 128
283  #define GENERIC_EXIT_WRITE_FRAME_ERROR 149
284  #define GENERIC_EXIT_DEADLOCK 150
285 #else
286  #include "exitcodes.h"
287  #include "mythcontext.h"
288 #endif
289 
290 /*
291  * vim:ts=4:sw=4:ai:et:si:sts=4
292  */
int m_displayFrame
Definition: mpeg2fix.h:223
bool m_file_end
Definition: mpeg2fix.h:249
int m_vid_id
Definition: mpeg2fix.h:235
int PlaybackSecondary()
Definition: mpeg2fix.cpp:1652
mpeg2dec_t * m_header_decoder
Definition: mpeg2fix.h:224
pthread_t m_thread
Definition: mpeg2fix.h:230
uint64_t m_filesize
Definition: mpeg2fix.h:255
int m_fix_PTS
Definition: mpeg2fix.h:243
MPEG2frame * DecodeToFrame(int frameNum, int skip_reset)
Definition: mpeg2fix.cpp:1665
void set_pkt(AVPacket *newpkt)
Definition: mpeg2fix.cpp:126
mpeg2_sequence_t m_mpeg2_seq
Definition: mpeg2fix.h:58
bool m_isGop
Definition: mpeg2fix.h:55
bool m_real_file_end
Definition: mpeg2fix.h:250
int m_ext_count
Definition: mpeg2fix.h:100
static int64_t add2x33(int64_t pts1, int64_t pts2)
Definition: mpeg2fix.cpp:415
int m_status_update_time
Definition: mpeg2fix.h:257
frm_dir_map_t m_delMap
Definition: mpeg2fix.h:227
mpeg2dec_t * m_img_decoder
Definition: mpeg2fix.h:225
static void SetRepeat(MPEG2frame *vf, int nb_fields, bool topff)
Definition: mpeg2fix.cpp:1576
AVFrame * m_picture
Definition: mpeg2fix.h:233
MPEG2frame(int size)
Definition: mpeg2fix.cpp:101
static void ShowRangeMap(frm_dir_map_t *mapPtr, QString msg)
Definition: mpeg2fix.cpp:1906
void AddSequence(MPEG2frame *frame1, MPEG2frame *frame2)
Definition: mpeg2fix.cpp:874
FrameQueue m_unreadFrames
Definition: mpeg2fix.h:222
QList< int > m_keyList
Definition: mpeg2fix.h:81
int BuildKeyframeIndex(QString &file, frm_pos_map_t &posMap, frm_pos_map_t &durMap)
Definition: mpeg2fix.cpp:2735
bool m_allaudio
Definition: mpeg2fix.h:246
void RenumberFrames(int start_pos, int delta)
Definition: mpeg2fix.cpp:1624
struct AVFrame AVFrame
int64_t pos_pts
Definition: mpeg2fix.h:65
ringbuffer m_index_extrbuf[N_AUDIO]
Definition: mpeg2fix.h:99
static void WriteYUV(const QString &filename, const mpeg2_info_t *info)
Definition: mpeg2fix.cpp:1066
void SetNextPos(int64_t newPTS, AVPacket *pkt)
Definition: mpeg2fix.cpp:189
bool m_zigzag_init
Definition: mpeg2fix.h:260
pthread_cond_t m_cond
Definition: mpeg2fix.h:105
static void WriteData(const QString &filename, uint8_t *data, int size)
Definition: mpeg2fix.cpp:1105
int(* check_abort)()
Definition: mpeg2fix.h:213
int m_otype
Definition: mpeg2fix.h:95
QString m_outfile
Definition: mpeg2fix.h:94
static int64_t udiff2x33(int64_t pts1, int64_t pts2)
Definition: mpeg2fix.cpp:379
uint16_t m_inv_zigzag_direct16[64]
Definition: mpeg2fix.h:259
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
Definition: programtypes.h:81
unsigned int uint
Definition: compat.h:140
int Start()
Definition: mpeg2fix.cpp:2001
uint64_t verboseMask
Definition: logging.cpp:107
bool m_isSequence
Definition: mpeg2fix.h:54
int64_t newPTS
Definition: mpeg2fix.h:64
AVFormatContext * m_inputFC
Definition: mpeg2fix.h:232
void InitReplex()
Definition: mpeg2fix.cpp:575
int64_t Get(int idx, AVPacket *pkt)
Definition: mpeg2fix.cpp:149
mpeg2_gop_t m_mpeg2_gop
Definition: mpeg2fix.h:59
uint8_t * m_framePos
Definition: mpeg2fix.h:56
bool InitAV(const QString &inputfile, const char *type, int64_t offset)
Definition: mpeg2fix.cpp:763
FrameQueue m_framePool
Definition: mpeg2fix.h:221
void WriteFrame(const QString &filename, MPEG2frame *f)
Definition: mpeg2fix.cpp:1020
multiplex_t * m_mplex
Definition: mpeg2fix.h:110
int m_exttypcnt[N_AUDIO]
Definition: mpeg2fix.h:102
QMap< int, QList< poq_idx_t > > m_orig
Definition: mpeg2fix.h:80
int AddFrame(MPEG2frame *f)
Definition: mpeg2fix.cpp:659
static void dumpList(FrameList *list)
Definition: mpeg2fix.cpp:1979
MPEG2replex()=default
frm_dir_map_t m_saveMap
Definition: mpeg2fix.h:228
static void * ReplexStart(void *data)
Definition: mpeg2fix.cpp:518
static int GetNbFields(const MPEG2frame *frame)
Definition: mpeg2fix.h:189
static char GetFrameTypeT(const MPEG2frame *frame)
Definition: mpeg2fix.h:183
MythCodecMap * gCodecMap
This global variable contains the MythCodecMap instance for the app.
Definition: mythavutil.cpp:380
mpeg2_picture_t m_mpeg2_pic
Definition: mpeg2fix.h:60
void SetAllAudio(bool keep)
Definition: mpeg2fix.h:130
int WaitBuffers()
Definition: mpeg2fix.cpp:487
AVPacket m_pkt
Definition: mpeg2fix.h:53
bool FindStart()
Definition: mpeg2fix.cpp:1448
QMap< int, FrameList * > FrameMap
Definition: mpeg2fix.h:115
unsigned short uint16_t
Definition: iso6937tables.h:1
int InsertFrame(int frameNum, int64_t deltaPTS, int64_t ptsIncrement, int64_t initPTS)
Definition: mpeg2fix.cpp:1798
PTSOffsetQueue(int vidid, QList< int > keys, int64_t initPTS)
Definition: mpeg2fix.cpp:133
bool m_use_secondary
Definition: mpeg2fix.h:217
ringbuffer m_index_vrbuf
Definition: mpeg2fix.h:98
QMap< int, QList< poq_idx_t > > m_offset
Definition: mpeg2fix.h:79
int framenum
Definition: mpeg2fix.h:66
int m_ext_count
Definition: mpeg2fix.h:236
AVCodecContext * getCodecContext(const AVStream *, const AVCodec *pCodec=nullptr, bool nullCodec=false)
Definition: mythavutil.cpp:391
int m_exttype[N_AUDIO]
Definition: mpeg2fix.h:101
int64_t m_ptsIncrement
Definition: mpeg2fix.h:238
void Start()
Definition: mpeg2fix.cpp:529
FrameList m_vSecondary
Definition: mpeg2fix.h:214
bool m_discard
Definition: mpeg2fix.h:241
void ensure_size(int size)
Definition: mpeg2fix.cpp:112
void InitialPTSFixup(MPEG2frame *curFrame, int64_t &origvPTS, int64_t &PTSdiscrep, int numframes, bool fix)
Definition: mpeg2fix.cpp:1940
QQueue< MPEG2frame * > FrameQueue
Definition: mpeg2fix.h:114
const char * m_format
Definition: mpeg2fix.h:245
void SetNextPTS(int64_t newPTS, int64_t atPTS)
Definition: mpeg2fix.cpp:176
int64_t UpdateOrigPTS(int idx, int64_t &origPTS, AVPacket *pkt)
Definition: mpeg2fix.cpp:210
void FrameInfo(MPEG2frame *f)
Definition: mpeg2fix.cpp:643
void(* update_status)(float percent_done)
Definition: mpeg2fix.h:214
AVCodecParserContext * getCodecParserContext(uint id)
Definition: mpeg2fix.h:204
static FrameList ReorderDTStoPTS(FrameList *dtsOrder, int pos)
Definition: mpeg2fix.cpp:1923
AVCodecContext * getCodecContext(uint id)
Definition: mpeg2fix.h:198
int m_done
Definition: mpeg2fix.h:93
sequence_t m_seq_head
Definition: mpeg2fix.h:107
ringbuffer m_vrbuf
Definition: mpeg2fix.h:96
MPEG2replex m_rx
Definition: mpeg2fix.h:141
static int64_t diff2x33(int64_t pts1, int64_t pts2)
Definition: mpeg2fix.cpp:390
QList< MPEG2frame * > FrameList
Definition: mpeg2fix.h:113
audio_frame_t m_extframe[N_AUDIO]
Definition: mpeg2fix.h:106
static void inc2x33(int64_t *pts1, int64_t pts2)
Definition: mpeg2fix.cpp:374
MPEG2frame * FindFrameNum(int frameNum)
Definition: mpeg2fix.cpp:1613
FrameList m_vFrame
Definition: mpeg2fix.h:219
MPFListType
Definition: mpeg2fix.h:40
int GetFrame(AVPacket *pkt)
Definition: mpeg2fix.cpp:1331
int GetStreamType(int id) const
Definition: mpeg2fix.h:193
void AddRangeList(QStringList rangelist, int type)
Definition: mpeg2fix.cpp:1863
bool m_mkvfile
Definition: mpeg2fix.h:239
static void dec2x33(int64_t *pts1, int64_t pts2)
Definition: mpeg2fix.cpp:369
static int GetFrameTypeN(const MPEG2frame *frame)
Definition: mpeg2fix.h:179
uint64_t m_last_written_pos
Definition: mpeg2fix.h:258
MPEG2frame * GetPoolFrame(AVPacket *pkt)
Definition: mpeg2fix.cpp:1294
int ConvertToI(FrameList *orderedFrames, int headPos)
Definition: mpeg2fix.cpp:1742
static int FindMPEG2Header(const uint8_t *buf, int size, uint8_t code)
Definition: mpeg2fix.cpp:446
static int cmp2x33(int64_t pts1, int64_t pts2)
Definition: mpeg2fix.cpp:423
MPEG2fixup(const QString &inf, const QString &outf, frm_dir_map_t *deleteMap, const char *fmt, int norp, int fixPTS, int maxf, bool showprog, int otype, void(*update_func)(float)=nullptr, int(*check_func)()=nullptr)
Definition: mpeg2fix.cpp:231
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:46
#define N_AUDIO
Definition: multiplex.h:33
bool type
Definition: mpeg2fix.h:67
static void SetFrameNum(uint8_t *ptr, int num)
Definition: mpeg2fix.cpp:869
int m_framenum
Definition: mpeg2fix.h:256
pthread_mutex_t m_mutex
Definition: mpeg2fix.h:104
uint8_t * m_gopPos
Definition: mpeg2fix.h:57
int ProcessVideo(MPEG2frame *vf, mpeg2dec_t *dec)
Definition: mpeg2fix.cpp:896
static int GetFrameNum(const MPEG2frame *frame)
Definition: mpeg2fix.h:175
bool m_showprogress
Definition: mpeg2fix.h:254
int m_no_repeat
Definition: mpeg2fix.h:243
QDateTime m_statustime
Definition: mpeg2fix.h:253
int m_maxframes
Definition: mpeg2fix.h:243
FrameMap m_aFrame
Definition: mpeg2fix.h:220
QString m_infile
Definition: mpeg2fix.h:244
ringbuffer m_extrbuf[N_AUDIO]
Definition: mpeg2fix.h:97
QMap< int, int > m_aud_map
Definition: mpeg2fix.h:237
void ScanAudio()
void StoreSecondary()
Definition: mpeg2fix.cpp:1636
bool BuildFrame(AVPacket *pkt, const QString &fname)
Definition: mpeg2fix.cpp:1123