2 Copyright 2004-2005 Chris Tallon 2009,2012 Marten Richter
4 This file is part of VOMP.
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.
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.
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/>.
26 #include <sys/ioctl.h>
32 #include <condition_variable>
39 #include <IL/OMX_Core.h>
40 #include <IL/OMX_Types.h>
41 #include <IL/OMX_Component.h>
42 #include <IL/OMX_Broadcom.h>
46 OMX_IN OMX_HANDLETYPE handle;
47 OMX_IN OMX_PTR appdata;
48 OMX_IN OMX_EVENTTYPE event_type;
51 OMX_IN OMX_PTR event_data;
57 class VideoOMX : public Video
59 friend class AudioOMX;
60 friend class ImageOMX;
69 u1 getSupportedFormats() { return COMPOSITERGB | HDMI; }
70 u4 supportedTVsize() { return ASPECT4X3 | ASPECT16X9 | ASPECT14X9; }
71 u1 supportedTVFormats() { return NTSC | PAL | PAL_M | NTSC_J; }
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
77 bool setVideoDisplay(VideoDisplay display);
78 int setTVsize(u1 size); // Is the TV a widescreen?
81 void executePendingModeChanges();
82 int setDefaultAspect();
84 int setPosition(int x, int y);
96 int attachFrameBuffer(); // What does this do?
97 u4 timecodeToFrameNumber(u8 timecode);
98 u8 getCurrentTimestamp();
99 bool displayIFrame(const u1* bulibaver, u4 length);
101 virtual bool dtsTimefix() { return false; } // please we need dts time values
102 virtual int getTeletextBufferFaktor() { return 5; }
104 // Writing Data to Videodevice
105 virtual void PrepareMediaSample(const MediaPacketList&, u4 samplepos);
106 virtual u4 DeliverMediaSample(u1* bulibaver, u4* samplepos);
108 virtual bool supportsh264() { return true; }
109 virtual bool supportsmpeg2() { return mpeg2_supported; }
111 int WriteOutTS(const unsigned char *bulibaver, int length, int type);
112 void WriteOutPATPMT();
114 virtual long long SetStartOffset(long long curreftime, bool *rsync);
115 long long SetStartAudioOffset(long long curreftime, bool *rsync);
116 virtual void ResetTimeOffsets();
118 bool loadOptionsFromServer(VDR* vdr);
119 bool saveOptionstoServer();
120 bool addOptionsToPanes(int panenumber, Options *options, WOptionPane* pane);
121 bool handleOptionChanges(Option* option);
128 static inline OMX_TICKS intToOMXTicks(long long pts)
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);
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);
147 int EnterIframePlayback();
149 bool InIframemode() { return iframemode; }
151 virtual bool DrainTargetBufferFull();
153 u4 DeliverMediaPacket(MediaPacket packet, const u1* bulibaver, u4 *samplepos);
155 #define VPE_DECODER_OMX 1
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{};
168 // long long playbacktimeoffset; //this is the offset between the media time and system clock
169 // long long pausetimecode;
173 static long long GetCurrentSystemTime();
174 static void WaitUntil(long long time);
175 void FrameWaitforDisplay(long long pts);
176 bool FrameSkip(long long pts);
178 void AdjustAudioPTS(long long pts);
181 u4 DeliverMediaPacketOMX(MediaPacket packet, const u1* bulibaver, u4 *samplepos);
183 bool detectIFrame(const u1 *buffer, unsigned int length);
185 int PrepareInputBufsOMX();
186 int DestroyInputBufsOMX();
188 void AddOmxEvent(VPE_OMX_EVENT new_event);
189 void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver);
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);
197 int clearEventsForComponent(OMX_HANDLETYPE handle);
198 void checkForStalledBuffers();
201 int setClockExecutingandRunning();
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);
212 bool isClockPaused() { return clockpaused; }
215 std::condition_variable omx_event_ready_signal;
216 std::mutex omx_event_ready_signal_mutex;
218 void interlaceSwitch4Demux();
220 std::mutex clock_mutex; //clock mutex is now responsible for all omx stuff
221 long long cur_clock_time{};
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();
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{};
248 int AllocateCodecsOMX();
249 int DeAllocateCodecsOMX();
250 int FlushRenderingPipe();
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{};
257 void PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer);
260 bool omx_first_frame;
262 std::mutex omx_event_mutex;
264 std::list<VPE_OMX_EVENT> omx_events;
266 bool omx_mpeg2{true};
268 float xpos{0.f}, ypos{0.f};
272 void updateMode(); //called internally to adjust for different parameters
273 void selectVideoMode(int interlaced);
277 bool pendingmodechange;
279 bool mpeg2_supported{};
280 int outputinterlaced{};
284 std::vector<MediaPacket> mediapackets;
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];