]> git.vomp.tv Git - vompclient.git/blob - src/videoomx.h
Potential fix for PTS rollover
[vompclient.git] / src / videoomx.h
1 /*
2     Copyright 2004-2005 Chris Tallon 2009,2012 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #ifndef VIDEOOMX_H
21 #define VIDEOOMX_H
22
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <sys/ioctl.h>
27 #include <string.h>
28 #include <stdint.h>
29 #include <list>
30 #include <vector>
31 #include <mutex>
32 #include <condition_variable>
33
34 #include "defines.h"
35 #include "video.h"
36
37 #define OMX_SKIP64BIT
38
39 #include <IL/OMX_Core.h>
40 #include <IL/OMX_Types.h>
41 #include <IL/OMX_Component.h>
42 #include <IL/OMX_Broadcom.h>
43
44 struct VPE_OMX_EVENT
45 {
46   OMX_IN OMX_HANDLETYPE handle;
47   OMX_IN OMX_PTR appdata;
48   OMX_IN OMX_EVENTTYPE event_type;
49   OMX_IN OMX_U32 data1;
50   OMX_IN OMX_U32 data2;
51   OMX_IN OMX_PTR event_data;
52 };
53
54 class LogNT;
55 class AudioVPE;
56
57 class VideoOMX : public Video
58 {
59   friend class AudioOMX;
60   friend class ImageOMX;
61
62   public:
63     VideoOMX();
64     virtual ~VideoOMX();
65
66     int init(u1 format);
67     int shutdown();
68
69     u1 getSupportedFormats() { return COMPOSITERGB | HDMI; }
70     u4 supportedTVsize()     { return ASPECT4X3 | ASPECT16X9 | ASPECT14X9; }
71     u1 supportedTVFormats()  { return NTSC | PAL | PAL_M | NTSC_J; }
72
73     int setFormat(u1 format);
74     int setConnection(u1 connection);
75     int setAspectRatio(u1 aspectRatio, int tparx,int tpary); // This one does the pin 8 scart widescreen switching
76     int setMode(u1 mode);
77     bool setVideoDisplay(VideoDisplay display);
78     int setTVsize(u1 size); // Is the TV a widescreen?
79     u1 getTVsize();
80
81     void executePendingModeChanges();
82     int setDefaultAspect();
83     int setSource();
84     int setPosition(int x, int y);
85     int sync();
86     int play();
87     int stop();
88     int pause();
89     int unPause();
90     int fastForward();
91     int unFastForward();
92     int reset();
93     int blank();
94     int signalOn();
95     int signalOff();
96     int attachFrameBuffer(); // What does this do?
97     u4 timecodeToFrameNumber(u8 timecode);
98     u8 getCurrentTimestamp();
99     bool displayIFrame(const u1* bulibaver, u4 length);
100
101     virtual bool dtsTimefix() { return false; } // please we need dts time values
102     virtual int getTeletextBufferFaktor() { return 5; }
103
104     // Writing Data to Videodevice
105     virtual void PrepareMediaSample(const MediaPacketList&, u4 samplepos);
106     virtual u4 DeliverMediaSample(u1* bulibaver, u4* samplepos);
107
108     virtual bool supportsh264() { return true; }
109     virtual bool supportsmpeg2() { return mpeg2_supported; }
110
111     int WriteOutTS(const unsigned char *bulibaver, int length, int type);
112     void WriteOutPATPMT();
113
114     virtual long long SetStartOffset(long long curreftime, bool *rsync);
115     long long SetStartAudioOffset(long long curreftime, bool *rsync);
116     virtual void ResetTimeOffsets();
117
118     bool loadOptionsFromServer(VDR* vdr);
119     bool saveOptionstoServer();
120     bool addOptionsToPanes(int panenumber, Options *options, WOptionPane* pane);
121     bool handleOptionChanges(Option* option);
122
123 #ifdef DEV
124     int test();
125     int test2();
126 #endif
127
128     static inline OMX_TICKS intToOMXTicks(long long pts)
129     {
130       OMX_TICKS temp;
131       // Assigning a long long int to an int drops the MSBs which is what we want here
132       // But to avoid a -Wconversion warning, cast it
133       temp.nLowPart = static_cast<OMX_U32>(pts);
134       temp.nHighPart = static_cast<OMX_U32>(pts >> 32);
135       return temp;
136     }
137
138   private:
139     static OMX_ERRORTYPE EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
140                                           OMX_IN OMX_EVENTTYPE event_type, OMX_IN OMX_U32 data1,
141                                           OMX_IN OMX_U32 data2, OMX_IN OMX_PTR event_data);
142     static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata, OMX_IN OMX_BUFFERHEADERTYPE* bulibaver);
143     static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata, OMX_IN OMX_BUFFERHEADERTYPE* bulibaver);
144
145
146     LogNT* logger;
147     int EnterIframePlayback();
148     bool iframemode;
149     bool InIframemode() { return iframemode; }
150
151     virtual bool DrainTargetBufferFull();
152
153     u4 DeliverMediaPacket(MediaPacket packet, const u1* bulibaver, u4 *samplepos);
154
155 #define VPE_DECODER_OMX 1
156
157     bool offsetnotset{true};
158     bool offsetvideonotset{true};
159     bool offsetaudionotset{true};
160     long long startoffset{};
161     long long rolloveroffset{};
162     long long lastrefvideotime{};
163     long long lastrefaudiotime{};
164     // long long cur_pts;
165     long long lastreftimeOMX{};
166     u8 lastreftimePTS{};
167
168     // long long playbacktimeoffset; //this is the offset between the media time and system clock
169     // long long pausetimecode;
170     bool clockpaused;
171
172     /*
173     static long long GetCurrentSystemTime();
174     static void WaitUntil(long long time);
175     void FrameWaitforDisplay(long long pts);
176     bool FrameSkip(long long pts);
177     bool skipping;
178     void AdjustAudioPTS(long long pts);
179     */
180
181     u4 DeliverMediaPacketOMX(MediaPacket packet, const u1* bulibaver, u4 *samplepos);
182
183     bool detectIFrame(const u1 *buffer, unsigned int length);
184
185     int PrepareInputBufsOMX();
186     int DestroyInputBufsOMX();
187
188     void AddOmxEvent(VPE_OMX_EVENT new_event);
189     void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver);
190
191     int ChangeComponentState(OMX_HANDLETYPE handle, OMX_STATETYPE type, bool wait = true);
192     int CommandFinished(OMX_HANDLETYPE handle, OMX_U32 command, OMX_U32 data2);
193     int WaitForEvent(OMX_HANDLETYPE handle, OMX_U32 event, int wait = 200);
194     int EnablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait);
195     int DisablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait = true);
196     int clearEvents();
197     int clearEventsForComponent(OMX_HANDLETYPE handle);
198     void checkForStalledBuffers();
199
200
201     int setClockExecutingandRunning();
202     int initClock();
203     void destroyClock();
204     int idleClock();
205     int getClockAudioandInit(OMX_HANDLETYPE* p_omx_clock, OMX_U32* p_omx_clock_output_port);
206     int getClockVideoandInit();
207     void LockClock() { clock_mutex.lock(); }
208     void UnlockClock() { clock_mutex.unlock(); }
209     OMX_ERRORTYPE ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer);
210     void clockPause();
211     void clockUnpause();
212     bool isClockPaused() { return clockpaused; }
213
214     void signalOmx();
215     std::condition_variable omx_event_ready_signal;
216     std::mutex omx_event_ready_signal_mutex;
217
218     void interlaceSwitch4Demux();
219
220     std::mutex clock_mutex; //clock mutex is now responsible for all omx stuff
221     long long cur_clock_time{};
222
223
224     OMX_HANDLETYPE omx_vid_dec{};
225     OMX_HANDLETYPE omx_vid_sched;
226     OMX_HANDLETYPE omx_vid_deint;
227     OMX_HANDLETYPE omx_vid_rend;
228     OMX_HANDLETYPE omx_clock;
229     int clock_references{};
230     bool dodeint; //deinterlacer was activated in omx filtergraph
231     bool first_frame; //handle frame change
232     void FirstFrameFix();
233
234
235     OMX_U32 omx_codec_input_port;
236     OMX_U32 omx_codec_output_port;
237     OMX_U32 omx_deint_input_port;
238     OMX_U32 omx_deint_output_port;
239     OMX_U32 omx_rend_input_port;
240     OMX_U32 omx_shed_input_port;
241     OMX_U32 omx_shed_output_port;
242     OMX_U32 omx_shed_clock_port;
243     OMX_U32 omx_clock_output_port;
244     //  OMX_NALUFORMATSTYPE omx_nalu_format;
245     bool omx_vid_stalled{};
246
247
248     int AllocateCodecsOMX();
249     int DeAllocateCodecsOMX();
250     int FlushRenderingPipe();
251
252     std::vector<OMX_BUFFERHEADERTYPE*> input_bufs_omx_all;
253     std::list<OMX_BUFFERHEADERTYPE*> input_bufs_omx_free;
254     std::mutex input_bufs_omx_mutex;
255     OMX_BUFFERHEADERTYPE* cur_input_buf_omx{};
256
257     void PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer);
258
259     bool omx_running{};
260     bool omx_first_frame;
261
262     std::mutex omx_event_mutex;
263
264     std::list<VPE_OMX_EVENT> omx_events;
265
266     bool omx_mpeg2{true};
267     bool omx_h264{true};
268     float xpos{0.f}, ypos{0.f};
269     float width, height;
270     bool windowed;
271     int deinterlace;
272     void updateMode(); //called internally to adjust for different parameters
273     void selectVideoMode(int interlaced);
274
275     u1 tvsystem;
276     bool signalon{};
277     bool pendingmodechange;
278     bool hdmi;
279     bool mpeg2_supported{};
280     int outputinterlaced{};
281
282     bool firstsynched{};
283
284     std::vector<MediaPacket> mediapackets;
285
286     char L_VPE_OMX_CLOCK[128];
287     char L_VPE_OMX_H264_DECODER[128];
288     char L_VPE_OMX_MPEG2_DECODER[128];
289     char L_VPE_OMX_VIDEO_SCHED[128];
290     char L_VPE_OMX_VIDEO_REND[128];
291     char L_VPE_OMX_VIDEO_DEINTERLACE[128];
292 };
293
294 #endif