]> git.vomp.tv Git - vompclient.git/blob - videovpeogl.h
Custom libav + transcode patches + first mpeg2 playback through transcoding
[vompclient.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     // Writing Data to Videodevice\r
162     virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);\r
163     virtual UINT DeliverMediaSample(UCHAR* bulibaver, UINT* samplepos);\r
164     virtual long long SetStartOffset(long long curreftime, bool *rsync)\r
165     { *rsync=false; return 0; };\r
166     virtual void ResetTimeOffsets();\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 \r
179 \r
180 \r
181         int getLastPacketNum() {return lastpacketnum;}; \r
182 #ifdef DEV\r
183     int test();\r
184     int test2();\r
185 #endif\r
186 \r
187     int initUsingOSDObjects();\r
188     int shutdownUsingOSDObjects() {return shutdown();};\r
189 \r
190 #ifdef VPE_LIBAV_SUPPORT\r
191     int getlibavDecodingMode() {return decoding_mode;};\r
192 \r
193 \r
194 #endif\r
195 \r
196   private:\r
197            int EnterIframePlayback();\r
198            bool iframemode;\r
199 \r
200            UINT DeliverMediaPacket(MediaPacket packet,\r
201                                              const UCHAR* bulibaver,\r
202                                              UINT *samplepos);\r
203            int decoding_backend; //1 omx, 2 libav, 3 omx through lib av transcoder\r
204 #define VPE_DECODER_OMX 1\r
205 #define VPE_DECODER_libav 2\r
206 #define VPE_DECODER_OMX_libav_TRANSCODE 3\r
207 \r
208 #ifdef VPE_OMX_SUPPORT\r
209            static OMX_ERRORTYPE EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,\r
210            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,\r
211            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data);\r
212            static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver);\r
213            static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver);\r
214 \r
215            UINT DeliverMediaPacketOMX(MediaPacket packet,\r
216                                                      const UCHAR* bulibaver,\r
217                                                      UINT *samplepos);\r
218 \r
219            int PrepareInputBufsOMX();\r
220            int DestroyInputBufsOMX();\r
221 \r
222            void AddOmxEvent(VPE_OMX_EVENT  new_event);\r
223            void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver);\r
224 \r
225            int ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type);\r
226            int CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2);\r
227            int EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait);\r
228            int DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait=true);\r
229 \r
230 \r
231 \r
232            OMX_HANDLETYPE omx_vid_dec;\r
233            OMX_HANDLETYPE omx_vid_sched;\r
234            OMX_HANDLETYPE omx_vid_rend;\r
235            OMX_HANDLETYPE omx_clock;\r
236 \r
237 \r
238            OMX_U32 omx_codec_input_port;\r
239            OMX_U32 omx_codec_output_port;\r
240            OMX_U32 omx_rend_input_port;\r
241            OMX_U32 omx_rend_output_port;\r
242            OMX_U32 omx_shed_input_port;\r
243            OMX_U32 omx_shed_output_port;\r
244            OMX_U32 omx_shed_clock_port;\r
245            OMX_U32 omx_clock_output_port;\r
246          //  OMX_NALUFORMATSTYPE omx_nalu_format;\r
247 \r
248 \r
249 \r
250            int AllocateCodecsOMX();\r
251            int DeAllocateCodecsOMX();\r
252 \r
253            vector<OMX_BUFFERHEADERTYPE*> input_bufs_omx_all;\r
254            list<OMX_BUFFERHEADERTYPE*> input_bufs_omx_free;\r
255            Mutex input_bufs_omx_mutex;\r
256            OMX_BUFFERHEADERTYPE* cur_input_buf_omx;\r
257 \r
258 \r
259            bool omx_running;\r
260            bool omx_first_frame;\r
261 \r
262            Mutex omx_event_mutex;\r
263 \r
264            list<VPE_OMX_EVENT> omx_events;\r
265 \r
266            bool omx_mpeg2;\r
267            bool omx_h264;\r
268 \r
269 \r
270 \r
271 \r
272 #endif\r
273 \r
274 #ifdef VPE_LIBAV_MPEG2_TRANSCODING\r
275          list<OMX_BUFFERHEADERTYPE*> input_bufs_omx_in_libav;\r
276          vector<transcode_pix_fmt*> pix_fmt_omx_all;\r
277          list<transcode_pix_fmt*> pix_fmt_omx_free;\r
278            // this is for\r
279          AVCodec *transcodecodec_libav;\r
280          AVCodecContext *transcodecodec_context_libav;\r
281          AVFrame transcode_frame_libav;\r
282 \r
283          static enum PixelFormat get_format_transcode(struct AVCodecContext *s, const enum PixelFormat *fmt);\r
284          static int reget_buffer_transcode(struct AVCodecContext *c, AVFrame *pic);\r
285          static int get_buffer_transcode(struct AVCodecContext *c, AVFrame *pic);\r
286          OMX_BUFFERHEADERTYPE* GetFreeOMXBufferforlibav(transcode_pix_fmt **pix_trans);\r
287          static void release_buffer_transcode(struct AVCodecContext *c, AVFrame *pic);\r
288          void ReturnEmptyOMXBuffer_libav(OMX_BUFFERHEADERTYPE* buffer,transcode_pix_fmt *pix_fmt);\r
289 \r
290 \r
291          UINT DeliverMediaPacketOMXTranscode(MediaPacket packet,const UCHAR* bulibaver,UINT *samplepos);\r
292          int DecodePacketOMXTranscode();\r
293          int InitTranscoderLibAV();\r
294          int DeInitTranscoderLibAV();\r
295 \r
296 \r
297 #endif\r
298 \r
299 #if defined(VPE_LIBAV_MPEG2_TRANSCODING) || defined(VPE_LIBAV_SUPPORT)\r
300          AVPacket incom_packet_libav;\r
301          int incom_packet_libav_size;\r
302 \r
303 \r
304 #endif\r
305 \r
306 #ifdef VPE_LIBAV_SUPPORT // this is the data for software decoding subject to removal\r
307 \r
308         const static int VPE_NO_XVMC=0;\r
309         const static int VPE_XVMC_MOCOMP=1;\r
310         const static int VPE_XVMC_IDCT=2;\r
311 \r
312         int decoding_mode;\r
313 \r
314         AVCodec *mpeg2codec_libav;\r
315         AVCodecContext *mpeg2codec_context_libav;\r
316         vector<AVFrame*> dec_frame_libav_all;\r
317         list<AVFrame*> dec_frame_libav_free;\r
318         list<AVFrame*> dec_frame_libav_upload_and_view_pending;\r
319         list<VPE_FrameBuf*> dec_frame_libav_upload_only_pending;\r
320         //AVFrame* dec_frame_libav_uploading;\r
321         VPE_FrameBuf* dec_frame_libav_uploading_framebuf;\r
322         AVFrame* dec_frame_libav_decoding;\r
323 \r
324         void add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data);\r
325 \r
326         vector<VPE_FrameBuf*> all_frame_bufs;\r
327         list<VPE_FrameBuf*> free_frame_bufs;\r
328         list<VPE_FrameBuf*> locked_libav_frame_buf;\r
329         list<VPE_FrameBuf*> locked_uploading_frame_buf;\r
330 \r
331         VPE_FrameBuf *getFrameBuf(unsigned int *size); //for libav\r
332         void releaseFrameBufLibav(VPE_FrameBuf*data);\r
333         void lockFrameBufUpload(VPE_FrameBuf* data);\r
334         void releaseFrameBufUpload(VPE_FrameBuf* data);\r
335 \r
336         unsigned int framebuf_framenum;\r
337 \r
338         Mutex vpe_framebuf_mutex;\r
339 \r
340 \r
341 \r
342 \r
343         Mutex dec_frame_libav_mutex;\r
344 \r
345 \r
346 \r
347         UINT DeliverMediaPacketlibav(MediaPacket packet,const UCHAR* bulibaver,UINT *samplepos);\r
348         int AllocateCodecsLibav();\r
349         int DeAllocateCodecsLibav();\r
350         int DecodePacketlibav();\r
351 \r
352         static enum PixelFormat get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt);\r
353         static int get_buffer_libav(struct AVCodecContext *c, AVFrame *pic);\r
354         static int reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic);\r
355         static void release_buffer_libav(struct AVCodecContext *c, AVFrame *pic);\r
356 \r
357         static void draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height);\r
358 \r
359         bool libav_running;\r
360         bool libav_hastime; // signals if a pts is now\r
361         long long libav_time;\r
362 \r
363         int libavwidth,libavheight,libavpixfmt;\r
364         GLMocoShader *moco_shader;\r
365 \r
366         \r
367 \r
368 \r
369         vector<VPEOGLFrame*> all_ogl_frames;\r
370         list<VPEOGLFrame*> free_ogl_frames;\r
371         list<VPEOGLFrame*> recycle_ref_ogl_frames;\r
372         list<VPEOGLFrame*> ready_ogl_frames;\r
373         int ogl_forward_ref_frame_num;\r
374         int ogl_backward_ref_frame_num;\r
375         VPEOGLFrame* ogl_forward_ref_frame;\r
376         VPEOGLFrame* ogl_backward_ref_frame;\r
377 \r
378         bool ogl_frame_outside;\r
379         Mutex ogl_frame_mutex;\r
380 \r
381         int AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride);\r
382         int AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride);\r
383 #endif\r
384 \r
385         virtual void threadMethod();\r
386         virtual void threadPostStopCleanup();\r
387 \r
388 \r
389 \r
390    bool firstsynched;\r
391    int lastpacketnum;\r
392 \r
393         EGLDisplay egl_display;\r
394         EGLSurface egl_surface;\r
395         EGLContext egl_context;\r
396 #ifdef BENCHMARK_FPS\r
397         unsigned int time_in_decoder;\r
398         unsigned int num_frames;\r
399         unsigned int time_in_decoder_gl;\r
400         unsigned int num_frames_gl;\r
401 #endif\r
402 \r
403     \r
404         MediaPacket mediapacket;\r
405 };\r
406 \r
407 #endif\r