]> git.vomp.tv Git - vompclient-marten.git/blob - videovpeogl.h
First timecode handling + Mpeg2 video hardware playback SD + HD
[vompclient-marten.git] / videovpeogl.h
1 /*\r
2     Copyright 2004-2005 Chris Tallon 2009 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 \r
21 \r
22 #ifndef VIDEOVPEOGL_H\r
23 #define VIDEOVPEOGL_H\r
24 \r
25 #include "mutex.h"\r
26 \r
27 \r
28 #include <stdio.h>\r
29 #include <unistd.h>\r
30 #include <fcntl.h>\r
31 #include <sys/ioctl.h>\r
32 #include <string.h>\r
33 \r
34 #include <stdint.h>\r
35 \r
36 #include <list>\r
37 #include <vector>\r
38 \r
39 #include "defines.h"\r
40 #include "video.h"\r
41 #include "threadsystem.h"\r
42 \r
43 \r
44 //#define EGL_EGLEXT_PROTOTYPES\r
45 \r
46 #include <GLES2/gl2.h>\r
47 #include <EGL/egl.h>\r
48 #include <EGL/eglext.h>\r
49 \r
50 #ifdef VPE_OMX_SUPPORT\r
51 \r
52 #include <IL/OMX_Core.h>\r
53 #include <IL/OMX_Types.h>\r
54 #include <IL/OMX_Component.h>\r
55 #include <IL/OMX_Broadcom.h>\r
56 \r
57 \r
58 struct VPE_OMX_EVENT {\r
59         OMX_IN OMX_HANDLETYPE handle;\r
60         OMX_IN OMX_PTR appdata;\r
61     OMX_IN OMX_EVENTTYPE event_type;\r
62     OMX_IN OMX_U32 data1;\r
63         OMX_IN OMX_U32 data2;\r
64         OMX_IN OMX_PTR event_data;\r
65 };\r
66 \r
67 #endif\r
68 \r
69 #if defined(VPE_LIBAV_MPEG2_TRANSCODING) || defined(VPE_LIBAV_SUPPORT)\r
70 extern "C" {\r
71 #include <libavcodec/avcodec.h>\r
72 #include <libavformat/avformat.h>\r
73 #include <libavutil/imgutils.h>\r
74 }\r
75 #endif\r
76 \r
77 #ifdef  VPE_LIBAV_MPEG2_TRANSCODING\r
78 extern "C" {\r
79 #include <libavcodec/transcode.h>\r
80 }\r
81 #if !defined(VPE_OMX_SUPPORT)\r
82 #error "VPE_LIBAV_MPEG2_TRANSCODING defined, and not VPE_OMX_SUPPORT defined!"\r
83 #endif\r
84 #endif\r
85 \r
86 #ifdef VPE_LIBAV_SUPPORT\r
87 \r
88 #include <stdint.h>\r
89 extern "C" {\r
90 #include <libavcodec/xvmc.h>\r
91 }\r
92 #include "glmocoshader.h"\r
93 \r
94 struct VPEOGLFrame;\r
95 \r
96 struct VPE_FrameBuf\r
97 { //This is a frame bulibaver, nothing fancy just plain memory\r
98         void *data[4];\r
99         unsigned int size[4];\r
100         unsigned int pict_num;\r
101         VPEOGLFrame *ogl_ref;\r
102         bool ogl_uploaded;\r
103         int width, height;\r
104         int stride;\r
105 };\r
106 \r
107 #endif\r
108 \r
109 struct VPEOGLFrame {\r
110         int type; //1 = YUV400, 2 YUV444\r
111         GLuint textures[3]; // 0=RGB or Y, 1=U 2=V\r
112         int width, height;\r
113         int stride;\r
114         unsigned int pict_num;\r
115 /*\r
116 #ifdef VPE_OMX_SUPPORT\r
117         //OMX\r
118         EGLImageKHR khr_image;\r
119         OMX_BUFFERHEADERTYPE *omx_buf;\r
120 #endif*/\r
121 };\r
122 \r
123 \r
124 \r
125 \r
126 \r
127 \r
128 class VideoVPEOGL : public Video, public Thread_TYPE\r
129 {\r
130   public:\r
131     VideoVPEOGL();\r
132     virtual ~VideoVPEOGL();\r
133 \r
134     int init(UCHAR format);\r
135     int shutdown();\r
136 \r
137     int setFormat(UCHAR format);\r
138     int setConnection(UCHAR connection);\r
139     int setAspectRatio(UCHAR aspectRatio);   // This one does the pin 8 scart widescreen switching\r
140     int setMode(UCHAR mode);\r
141     int setTVsize(UCHAR size);               // Is the TV a widescreen?\r
142     int setDefaultAspect();\r
143     int setSource();\r
144     int setPosition(int x, int y);\r
145     int sync();\r
146     int play();\r
147     int stop();\r
148     int pause();\r
149     int unPause();\r
150     int fastForward();\r
151     int unFastForward();\r
152     int reset();\r
153     int blank();\r
154     int signalOn();\r
155     int signalOff();\r
156     int attachFrameBuffer(); // What does this do?\r
157     ULONG timecodeToFrameNumber(ULLONG timecode);\r
158     ULLONG getCurrentTimestamp();\r
159     bool displayIFrame(const UCHAR* bulibaver, UINT length);\r
160 \r
161     virtual bool dtsTimefix(){return true;} //please we need dts time values\r
162 \r
163     // Writing Data to Videodevice\r
164     virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);\r
165     virtual UINT DeliverMediaSample(UCHAR* bulibaver, UINT* samplepos);\r
166 \r
167 \r
168         virtual bool supportsh264(){return true;};\r
169 \r
170         int WriteOutTS(const unsigned char *bulibaver,int length, int type);\r
171         void WriteOutPATPMT();\r
172 \r
173 \r
174         VPEOGLFrame *getReadyOGLFrame();\r
175         void returnOGLFrame(VPEOGLFrame *frame);\r
176         void recycleOGLRefFrames();\r
177 \r
178         virtual long long SetStartOffset(long long curreftime, bool *rsync);\r
179         long long SetStartAudioOffset(long long curreftime, bool *rsync);\r
180         virtual void ResetTimeOffsets();\r
181 \r
182         static long long GetCurrentSystemTime();\r
183         static void WaitUntil(long long time);\r
184         void FrameWaitforDisplay(long long pts);\r
185 \r
186 \r
187 \r
188 \r
189         int getLastPacketNum() {return lastpacketnum;}; \r
190 #ifdef DEV\r
191     int test();\r
192     int test2();\r
193 #endif\r
194 \r
195     int initUsingOSDObjects();\r
196     int shutdownUsingOSDObjects() {return shutdown();};\r
197 \r
198 #ifdef VPE_LIBAV_SUPPORT\r
199     int getlibavDecodingMode() {return decoding_mode;};\r
200 \r
201 \r
202 #endif\r
203 \r
204   private:\r
205            int EnterIframePlayback();\r
206            bool iframemode;\r
207 \r
208            UINT DeliverMediaPacket(MediaPacket packet,const UCHAR* bulibaver,UINT *samplepos);\r
209 \r
210            int decoding_backend; //1 omx, 2 libav, 3 omx through lib av transcoder\r
211 #define VPE_DECODER_OMX 1\r
212 #define VPE_DECODER_libav 2\r
213 #define VPE_DECODER_OMX_libav_TRANSCODE 3\r
214 \r
215 \r
216            bool offsetnotset;\r
217            bool offsetvideonotset;\r
218            bool offsetaudionotset;\r
219            long long startoffset;\r
220            long long lastrefvideotime;\r
221            long long lastrefaudiotime;\r
222            OMX_TICKS lastreftimeOMX;\r
223            ULLONG lastreftimePTS;\r
224 \r
225            long long playbacktimeoffset; //this is the offset between the media time and system clock\r
226            long long pausetimecode;\r
227            bool paused;\r
228 \r
229 \r
230 \r
231 \r
232 #ifdef VPE_OMX_SUPPORT\r
233            static OMX_ERRORTYPE EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,\r
234            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,\r
235            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data);\r
236            static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver);\r
237            static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver);\r
238 \r
239            UINT DeliverMediaPacketOMX(MediaPacket packet,\r
240                                                      const UCHAR* bulibaver,\r
241                                                      UINT *samplepos);\r
242 \r
243            int PrepareInputBufsOMX();\r
244            int DestroyInputBufsOMX();\r
245 \r
246            void AddOmxEvent(VPE_OMX_EVENT  new_event);\r
247            void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver);\r
248 \r
249            int ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type);\r
250            int CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2);\r
251            int EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait);\r
252            int DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait=true);\r
253 \r
254 \r
255 \r
256            OMX_HANDLETYPE omx_vid_dec;\r
257            OMX_HANDLETYPE omx_vid_sched;\r
258            OMX_HANDLETYPE omx_vid_rend;\r
259            OMX_HANDLETYPE omx_clock;\r
260 \r
261 \r
262            OMX_U32 omx_codec_input_port;\r
263            OMX_U32 omx_codec_output_port;\r
264            OMX_U32 omx_rend_input_port;\r
265            OMX_U32 omx_rend_output_port;\r
266            OMX_U32 omx_shed_input_port;\r
267            OMX_U32 omx_shed_output_port;\r
268            OMX_U32 omx_shed_clock_port;\r
269            OMX_U32 omx_clock_output_port;\r
270          //  OMX_NALUFORMATSTYPE omx_nalu_format;\r
271 \r
272 \r
273 \r
274            int AllocateCodecsOMX();\r
275            int DeAllocateCodecsOMX();\r
276 \r
277            vector<OMX_BUFFERHEADERTYPE*> input_bufs_omx_all;\r
278            list<OMX_BUFFERHEADERTYPE*> input_bufs_omx_free;\r
279            Mutex input_bufs_omx_mutex;\r
280            OMX_BUFFERHEADERTYPE* cur_input_buf_omx;\r
281 \r
282 \r
283            bool omx_running;\r
284            bool omx_first_frame;\r
285 \r
286            Mutex omx_event_mutex;\r
287 \r
288            list<VPE_OMX_EVENT> omx_events;\r
289 \r
290            bool omx_mpeg2;\r
291            bool omx_h264;\r
292 \r
293 \r
294 \r
295 \r
296 #endif\r
297 \r
298 #ifdef VPE_LIBAV_MPEG2_TRANSCODING\r
299          list<OMX_BUFFERHEADERTYPE*> input_bufs_omx_in_libav;\r
300          vector<transcode_pix_fmt*> pix_fmt_omx_all;\r
301          list<transcode_pix_fmt*> pix_fmt_omx_free;\r
302            // this is for\r
303          AVCodec *transcodecodec_libav;\r
304          AVCodecContext *transcodecodec_context_libav;\r
305          AVFrame transcode_frame_libav;\r
306 \r
307          static enum PixelFormat get_format_transcode(struct AVCodecContext *s, const enum PixelFormat *fmt);\r
308          static int reget_buffer_transcode(struct AVCodecContext *c, AVFrame *pic);\r
309          static int get_buffer_transcode(struct AVCodecContext *c, AVFrame *pic);\r
310          OMX_BUFFERHEADERTYPE* GetFreeOMXBufferforlibav(transcode_pix_fmt **pix_trans);\r
311          static void release_buffer_transcode(struct AVCodecContext *c, AVFrame *pic);\r
312          void ReturnEmptyOMXBuffer_libav(OMX_BUFFERHEADERTYPE* buffer,transcode_pix_fmt *pix_fmt);\r
313 \r
314 \r
315          UINT DeliverMediaPacketOMXTranscode(MediaPacket packet,const UCHAR* bulibaver,UINT *samplepos);\r
316          int DecodePacketOMXTranscode();\r
317          int InitTranscoderLibAV();\r
318          int DeInitTranscoderLibAV();\r
319 \r
320 \r
321 #endif\r
322 \r
323 #if defined(VPE_LIBAV_MPEG2_TRANSCODING) || defined(VPE_LIBAV_SUPPORT)\r
324          AVPacket incom_packet_libav;\r
325          int incom_packet_libav_size;\r
326 \r
327 \r
328 #endif\r
329 \r
330 #ifdef VPE_LIBAV_SUPPORT // this is the data for software decoding subject to removal\r
331 \r
332         const static int VPE_NO_XVMC=0;\r
333         const static int VPE_XVMC_MOCOMP=1;\r
334         const static int VPE_XVMC_IDCT=2;\r
335 \r
336         int decoding_mode;\r
337 \r
338         AVCodec *mpeg2codec_libav;\r
339         AVCodecContext *mpeg2codec_context_libav;\r
340         vector<AVFrame*> dec_frame_libav_all;\r
341         list<AVFrame*> dec_frame_libav_free;\r
342         list<AVFrame*> dec_frame_libav_upload_and_view_pending;\r
343         list<VPE_FrameBuf*> dec_frame_libav_upload_only_pending;\r
344         //AVFrame* dec_frame_libav_uploading;\r
345         VPE_FrameBuf* dec_frame_libav_uploading_framebuf;\r
346         AVFrame* dec_frame_libav_decoding;\r
347 \r
348         void add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data);\r
349 \r
350         vector<VPE_FrameBuf*> all_frame_bufs;\r
351         list<VPE_FrameBuf*> free_frame_bufs;\r
352         list<VPE_FrameBuf*> locked_libav_frame_buf;\r
353         list<VPE_FrameBuf*> locked_uploading_frame_buf;\r
354 \r
355         VPE_FrameBuf *getFrameBuf(unsigned int *size); //for libav\r
356         void releaseFrameBufLibav(VPE_FrameBuf*data);\r
357         void lockFrameBufUpload(VPE_FrameBuf* data);\r
358         void releaseFrameBufUpload(VPE_FrameBuf* data);\r
359 \r
360         unsigned int framebuf_framenum;\r
361 \r
362         Mutex vpe_framebuf_mutex;\r
363 \r
364 \r
365 \r
366 \r
367         Mutex dec_frame_libav_mutex;\r
368 \r
369 \r
370 \r
371         UINT DeliverMediaPacketlibav(MediaPacket packet,const UCHAR* bulibaver,UINT *samplepos);\r
372         int AllocateCodecsLibav();\r
373         int DeAllocateCodecsLibav();\r
374         int DecodePacketlibav();\r
375 \r
376         static enum PixelFormat get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt);\r
377         static int get_buffer_libav(struct AVCodecContext *c, AVFrame *pic);\r
378         static int reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic);\r
379         static void release_buffer_libav(struct AVCodecContext *c, AVFrame *pic);\r
380 \r
381         static void draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height);\r
382 \r
383         bool libav_running;\r
384         bool libav_hastime; // signals if a pts is now\r
385         long long libav_time;\r
386 \r
387         int libavwidth,libavheight,libavpixfmt;\r
388         GLMocoShader *moco_shader;\r
389 \r
390         \r
391 \r
392 \r
393         vector<VPEOGLFrame*> all_ogl_frames;\r
394         list<VPEOGLFrame*> free_ogl_frames;\r
395         list<VPEOGLFrame*> recycle_ref_ogl_frames;\r
396         list<VPEOGLFrame*> ready_ogl_frames;\r
397         int ogl_forward_ref_frame_num;\r
398         int ogl_backward_ref_frame_num;\r
399         VPEOGLFrame* ogl_forward_ref_frame;\r
400         VPEOGLFrame* ogl_backward_ref_frame;\r
401 \r
402         bool ogl_frame_outside;\r
403         Mutex ogl_frame_mutex;\r
404 \r
405         int AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride);\r
406         int AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride);\r
407 #endif\r
408 \r
409         virtual void threadMethod();\r
410         virtual void threadPostStopCleanup();\r
411 \r
412 \r
413 \r
414    bool firstsynched;\r
415    int lastpacketnum;\r
416 \r
417         EGLDisplay egl_display;\r
418         EGLSurface egl_surface;\r
419         EGLContext egl_context;\r
420 #ifdef BENCHMARK_FPS\r
421         unsigned int time_in_decoder;\r
422         unsigned int num_frames;\r
423         unsigned int time_in_decoder_gl;\r
424         unsigned int num_frames_gl;\r
425 #endif\r
426 \r
427     \r
428         MediaPacket mediapacket;\r
429 };\r
430 \r
431 #endif\r