]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Add input buffer for ffmpeg, fix broken decoding
authorMarten Richter <marten.richter@freenet.de>
Sat, 9 Jun 2012 12:24:25 +0000 (14:24 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sat, 9 Jun 2012 12:24:25 +0000 (14:24 +0200)
GNUmakefile
videovpeogl.cc
videovpeogl.h

index 680bc08191ea110ff14446b6c0d6774aa6d7e9e6..3508184b81b0312193e2f61ea90d37cc27ca034e 100755 (executable)
@@ -48,7 +48,8 @@ LIBS = -lpthread -lrt
 OBJECTS += main.o threadp.o remotemvp.o ledmvp.o mtdmvp.o videomvp.o audiomvp.o osdmvp.o surfacemvp.o vmedialist.o vcolourtuner.o vmediaview.o vvideomedia.o \r
 TIOBJECT = ticonfig.o\r
 CROSSLIBS = ../jpeg/jpeg-6b/libjpeg.a\r
-INCLUDES = -I../jpeg/jpeg-6b -DVOMP_PLATTFORM_MVP\r
+INCLUDES = -I../jpeg/jpeg-6b  -DVOMP_PLATTFORM_MVP \r
+\r
 \r
 endif\r
 \r
@@ -61,6 +62,8 @@ OBJECTS += main.o threadp.o osdopengl.o surfaceopengl.o ledraspberry.o mtdraspbe
 LIBS+= -ljpeg\r
 CROSSLIBS =\r
 INCLUDES = -DVOMP_PLATTFORM_RASPBERRY   -I/opt/vc/include \r
+CXXFLAGS_DEV += -D__STDC_CONSTANT_MACROS\r
+CXXFLAGS_REL += -D__STDC_CONSTANT_MACROS\r
 \r
 endif\r
 \r
index c4ec0c5d20d3fa5d0a4fe76ec3418da6a146f601..d5bc781bd25331a50b0dd91ab971185323626e61 100755 (executable)
@@ -48,7 +48,7 @@ VideoVPEOGL::VideoVPEOGL()
   dec_frame_ff_decoding=NULL;
   ogl_frame_outside=false;
 #endif
-  
+
 #ifdef BENCHMARK_FPS
        time_in_decoder=0;
     num_frames=0;
@@ -1345,9 +1345,11 @@ int VideoVPEOGL::AllocateCodecsFFMPEG()
                Log::getInstance()->log("Video", Log::DEBUG, "Opening ffmpeg codec  failed");
                return 0;
        }
-       Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg mark1");
+       memset(&incom_packet_ff,0,sizeof(incom_packet_ff));
+       incom_packet_ff_size=200000;
+       incom_packet_ff.data=(uint8_t*)av_malloc(incom_packet_ff_size+FF_INPUT_BUFFER_PADDING_SIZE);
+
        dec_frame_ff_mutex.Lock();
-       Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg mark2");
        for (int i=0;i<3;i++) {
                        AVFrame *dec_frame_ff=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
                        if (!dec_frame_ff) {
@@ -1358,7 +1360,6 @@ int VideoVPEOGL::AllocateCodecsFFMPEG()
                        dec_frame_ff_free.push_back(dec_frame_ff);
        }
        dec_frame_ff_decoding=NULL;
-       Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg mark 3");
        dec_frame_ff_mutex.Unlock();
 
        ogl_frame_mutex.Lock();
@@ -1402,6 +1403,11 @@ int VideoVPEOGL::DeAllocateCodecsFFMPEG()
        }
 
        dec_frame_ff_all.clear();
+
+       av_free(incom_packet_ff.data);
+       incom_packet_ff.data=NULL;
+       incom_packet_ff_size=0;
+
        dec_frame_ff_mutex.Unlock();
        dec_frame_ff_decoding=NULL;
        while (ogl_frame_outside) {
@@ -1463,7 +1469,7 @@ int VideoVPEOGL::stop()
 
 #endif
 
-  
+
 
 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
   return 1;
@@ -1472,7 +1478,7 @@ int VideoVPEOGL::stop()
 int VideoVPEOGL::reset()
 {
   if (!initted) return 0;
+
 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
   return 1;
 }
@@ -1775,6 +1781,70 @@ UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
 
 
 #ifdef VPE_FFMPEG_SUPPORT
+int VideoVPEOGL::DecodePacketFFMPEG()
+{
+       unsigned int haveToCopy=incom_packet_ff.size;
+       if (incom_packet_ff.size==0) return 1; // we are already empty
+       while (haveToCopy>0) {
+               int dec_bytes=0;
+               int frame_ready=0;
+
+       //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
+
+#ifdef BENCHMARK_FPS
+           int cur_time=getTimeMS();
+#endif
+
+               dec_bytes=avcodec_decode_video2(mpeg2codec_context_ff, dec_frame_ff_decoding,
+                               &frame_ready, &incom_packet_ff);
+#ifdef BENCHMARK_FPS
+               time_in_decoder+=getTimeMS()-cur_time;
+               if (frame_ready) num_frames++;
+               if ((num_frames%100)==0) {
+                       float fps=1000./(float)(time_in_decoder);
+                       fps*=((float)num_frames);
+                       Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
+               }
+#endif
+               if (dec_bytes<0) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
+                       return 0;
+               }
+               haveToCopy-=dec_bytes;
+               if (frame_ready) {
+               //      Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
+
+                       dec_frame_ff_mutex.Lock();
+                       ffwidth=mpeg2codec_context_ff->width;
+                       ffheight=mpeg2codec_context_ff->height;
+                       ffpixfmt=mpeg2codec_context_ff->pix_fmt;
+               //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",ffwidth,ffheight,ffpixfmt);
+
+                       dec_frame_ff_upload_pending.push_back(dec_frame_ff_decoding);
+                       dec_frame_ff_decoding=NULL;
+                       if (dec_frame_ff_free.size()>0) {
+                               dec_frame_ff_decoding=dec_frame_ff_free.front();
+                               dec_frame_ff_free.pop_front();
+                               dec_frame_ff_mutex.Unlock();
+                               threadSignal();
+                               ffmpeg_hastime=false;
+                       } else {
+                               ffmpeg_hastime=false;
+                               dec_frame_ff_mutex.Unlock();
+                               // No free Buffers
+                               return 0;
+                       }
+
+
+               }
+
+       }
+       incom_packet_ff.size=0;
+       return 1;
+
+}
+
+
 UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet,
                const UCHAR* buffer,
                UINT *samplepos)
@@ -1795,16 +1865,10 @@ UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet,
        }
 
        UINT headerstrip=0;
-/*     if (packet.disconti) {
+       if (packet.disconti) {
                firstsynched=false;
-               if (cur_input_buf_omx) {
-                       OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
-                       if (error!=OMX_ErrorNone){
-                               Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
-                       }
-                       cur_input_buf_omx=NULL;
-               }
-       }*/
+               if (!DecodePacketFFMPEG()) return 0;
+       }
 
        /*Inspect PES-Header */
        if (!dec_frame_ff_decoding) {
@@ -1828,14 +1892,8 @@ UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet,
                *samplepos+=headerstrip;
                if ( packet.synched ) {
 
-                       /*if (cur_input_buf_omx) {
-                               OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
-                               if (error!=OMX_ErrorNone){
-                                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
-                               }
+                       if (!DecodePacketFFMPEG()) return 0; // WriteOut old Data
 
-                               cur_input_buf_omx=NULL;//write out old data
-                       }*/
                        ffmpeg_time=packet.presentation_time;
                        ffmpeg_hastime=true;
                //      reftime1=packet.presentation_time;
@@ -1879,61 +1937,19 @@ UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet,
 
        }*/
        unsigned int haveToCopy=packet.length-*samplepos;
-       while (haveToCopy>0) {
-               int dec_bytes=0;
-               int frame_ready=0;
-
-       //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
-
-#ifdef BENCHMARK_FPS
-           int cur_time=getTimeMS();
-#endif
-
-               dec_bytes=avcodec_decode_video(mpeg2codec_context_ff, dec_frame_ff_decoding,
-                               &frame_ready, buffer+packet.pos_buffer+*samplepos, haveToCopy);
-#ifdef BENCHMARK_FPS
-               time_in_decoder+=getTimeMS()-cur_time;
-               if (frame_ready) num_frames++;
-               if ((num_frames%100)==0) {
-                       float fps=1000./(float)(time_in_decoder);
-                       fps*=((float)num_frames);
-                       Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
-               }
-#endif
-               if (dec_bytes<0) {
-                       Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
-                       return *samplepos;
-               }
-               *samplepos+=dec_bytes;
-               haveToCopy-=dec_bytes;
-               if (frame_ready) {
-               //      Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
 
-                       dec_frame_ff_mutex.Lock();
-                       ffwidth=mpeg2codec_context_ff->width;
-                       ffheight=mpeg2codec_context_ff->height;
-                       ffpixfmt=mpeg2codec_context_ff->pix_fmt;
-               //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",ffwidth,ffheight,ffpixfmt);
-
-                       dec_frame_ff_upload_pending.push_back(dec_frame_ff_decoding);
-                       dec_frame_ff_decoding=NULL;
-                       if (dec_frame_ff_free.size()>0) {
-                               dec_frame_ff_decoding=dec_frame_ff_free.front();
-                               dec_frame_ff_free.pop_front();
-                               dec_frame_ff_mutex.Unlock();
-                               threadSignal();
-                               ffmpeg_hastime=false;
-                       } else {
-                               ffmpeg_hastime=false;
-                               dec_frame_ff_mutex.Unlock();
-                               // No free Buffers
-                               return *samplepos;
-                       }
+       if  ((incom_packet_ff_size-incom_packet_ff.size)< haveToCopy) {
+               // if the buffer is to small reallocate
+               incom_packet_ff_size+=haveToCopy;
+               incom_packet_ff.data=(uint8_t*)av_realloc(incom_packet_ff.data,incom_packet_ff_size+FF_INPUT_BUFFER_PADDING_SIZE);
+               Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_ff_size);
+       }
+       memcpy(incom_packet_ff.data,buffer+packet.pos_buffer+*samplepos,haveToCopy);
+       incom_packet_ff.size+=haveToCopy;
 
+       *samplepos+=haveToCopy;
 
-               }
 
-       }
        return *samplepos;
 
 
@@ -1955,7 +1971,7 @@ bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
   //write(fdVideo, buffer, length);
        if (!iframemode) EnterIframePlayback();
 //     WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
+
   lastpacketnum=-1;
   return true;
 }
index 3c722e63da77c06700479918532dd83461aadb08..c127a33b2d90878c75b8e642e0d0aa3d69e9980a 100755 (executable)
@@ -66,7 +66,10 @@ struct VPE_OMX_EVENT {
 #endif\r
 \r
 #ifdef VPE_FFMPEG_SUPPORT\r
+\r
+#include <stdint.h>\r
 extern "C" {\r
+\r
 #include <libavcodec/avcodec.h>\r
 #include <libavformat/avformat.h>\r
 }\r
@@ -236,6 +239,9 @@ class VideoVPEOGL : public Video, public Thread_TYPE
        list<AVFrame*> dec_frame_ff_upload_pending;\r
        AVFrame* dec_frame_ff_uploading;\r
        AVFrame* dec_frame_ff_decoding;\r
+\r
+       AVPacket incom_packet_ff;\r
+       int incom_packet_ff_size;\r
        Mutex dec_frame_ff_mutex;\r
 \r
 \r
@@ -243,6 +249,7 @@ class VideoVPEOGL : public Video, public Thread_TYPE
        UINT DeliverMediaPacketFFMPEG(MediaPacket packet,const UCHAR* buffer,UINT *samplepos);\r
        int AllocateCodecsFFMPEG();\r
        int DeAllocateCodecsFFMPEG();\r
+       int DecodePacketFFMPEG();\r
        bool ffmpeg_running;\r
        bool ffmpeg_hastime; // signals if a pts is now\r
        long long ffmpeg_time;\r