From f897f2aa7055c493db6391c50c8d19da970078e8 Mon Sep 17 00:00:00 2001 From: Andreas Brachold Date: Tue, 19 Jul 2005 15:09:05 +0000 Subject: Initial import with release 0.2.3 --- liboutput/Makefile | 58 +++++++ liboutput/encode.c | 369 ++++++++++++++++++++++++++++++++++++++++++ liboutput/encode.h | 92 +++++++++++ liboutput/stillimage-player.c | 61 +++++++ liboutput/stillimage-player.h | 55 +++++++ liboutput/stillimage.c | 210 ++++++++++++++++++++++++ liboutput/stillimage.h | 54 +++++++ 7 files changed, 899 insertions(+) create mode 100644 liboutput/Makefile create mode 100644 liboutput/encode.c create mode 100644 liboutput/encode.h create mode 100644 liboutput/stillimage-player.c create mode 100644 liboutput/stillimage-player.h create mode 100644 liboutput/stillimage.c create mode 100644 liboutput/stillimage.h (limited to 'liboutput') diff --git a/liboutput/Makefile b/liboutput/Makefile new file mode 100644 index 0000000..acac360 --- /dev/null +++ b/liboutput/Makefile @@ -0,0 +1,58 @@ +# +# Makefile for a Video Disk Recorder plugin +# +# $Id$ + +VDRDIR = ../../../.. +DVBDIR = ../../../../../DVB +FFMDIR = ../../../../../ffmpeg + +### The C++ compiler and options: + +CXX ?= g++ +CXXFLAGS ?= -O0 -g -Wall -Woverloaded-virtual + +-include $(VDRDIR)/Make.config + +### The directory environment: + + +INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include + +DEFINES += -D_GNU_SOURCE + +LIBS += + +ifdef FFMPEG_STATIC + INCLUDES += -I$(FFMDIR) + DEFINES += -DHAVE_FFMPEG_STATIC +endif + +### The object files (add further files here): + +OBJS = encode.o stillimage.o stillimage-player.o + +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Targets: + +all: liboutput.a + +liboutput.a : $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) +# $(CXX) $(CXXFLAGS) -shared $(OBJS) $(LIBS) -o $@ + +clean: + @-rm -f $(OBJS) $(DEPFILE) *.a *.so *.tgz core* *~ diff --git a/liboutput/encode.c b/liboutput/encode.c new file mode 100644 index 0000000..351e30f --- /dev/null +++ b/liboutput/encode.c @@ -0,0 +1,369 @@ +/*************************************************************************** + * encode.c + * + * (C) Copyright 2004 Andreas Brachold + * Created: Thu Aug 5 2004 + * + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#ifndef HAVE_FFMPEG_STATIC +#include +#endif + +#include "encode.h" +#include +#include + +typedef void (*f_avcodec_init)(void); +typedef void (*f_avcodec_register_all)(void); +typedef AVCodec *(*f_avcodec_find_encoder)(enum CodecID id); +typedef AVCodecContext *(*f_avcodec_alloc_context)(void); +typedef AVFrame *(*f_avcodec_alloc_frame)(void); +typedef int (*f_avcodec_open)(AVCodecContext *avctx, AVCodec *codec); +typedef int (*f_avcodec_close)(AVCodecContext *avctx); +typedef int (*f_avcodec_encode_video)(AVCodecContext *avctx, uint8_t *buf, int buf_size,const AVFrame *pict); +typedef int (*f_avpicture_fill)(AVPicture *picture, uint8_t *ptr, int pix_fmt, int width, int height); + +#if FFMPEG_VERSION_INT <= 0x000408 +typedef int (*f_img_convert)(AVPicture *dst, int dst_pix_fmt,AVPicture *src, int pix_fmt,int width, int height); +#elif FFMPEG_VERSION_INT >= 0x000409 +typedef int (*f_img_convert)(AVPicture *dst, int dst_pix_fmt,const AVPicture *src, int pix_fmt,int width, int height); +#else + #error "there is a unknow ffmpeg version or FFMPEG_VERSION_INT isnt defined" +#endif + +#ifdef HAVE_FFMPEG_STATIC + +static f_avcodec_init fn_avcodec_init=avcodec_init; +static f_avcodec_register_all fn_avcodec_register_all=avcodec_register_all; +static f_avcodec_find_encoder fn_avcodec_find_encoder=avcodec_find_encoder; +static f_avcodec_alloc_context fn_avcodec_alloc_context=avcodec_alloc_context; +static f_avcodec_alloc_frame fn_avcodec_alloc_frame=avcodec_alloc_frame; +static f_avcodec_open fn_avcodec_open=avcodec_open; +static f_avcodec_close fn_avcodec_close=avcodec_close; +static f_avcodec_encode_video fn_avcodec_encode_video=&avcodec_encode_video; +static f_avpicture_fill fn_avpicture_fill=avpicture_fill; +static f_img_convert fn_img_convert=img_convert; + +#else + +static f_avcodec_init fn_avcodec_init; +static f_avcodec_register_all fn_avcodec_register_all; +static f_avcodec_find_encoder fn_avcodec_find_encoder; +static f_avcodec_alloc_context fn_avcodec_alloc_context; +static f_avcodec_alloc_frame fn_avcodec_alloc_frame; +static f_avcodec_open fn_avcodec_open; +static f_avcodec_close fn_avcodec_close; +static f_avcodec_encode_video fn_avcodec_encode_video; +static f_avpicture_fill fn_avpicture_fill; +static f_img_convert fn_img_convert; + + +#define DLSYM(cast,sym,func) \ + sym=(cast)dlsym(m_hLibAvcodec, func); \ + bSuccess &= (sym != NULL); \ + if(sym == NULL) \ + esyslog("imageplugin: Link to function %s failed", func); + +void *cEncode::m_hLibAvcodec = NULL; + + +/******************************************************************************* + +*/ +bool cEncode::InitLibAVCodec(void){ + + bool bSuccess=false; + // Let ld.so search the libary + const char* szLibary = "libavcodec.so"; + m_hLibAvcodec=dlopen(szLibary, RTLD_LAZY); + if(!m_hLibAvcodec) + { + esyslog("imageplugin: Loading %s failed : %s", szLibary,dlerror()); + } + /* map the lib's syms to our wrapper */ + else { + + bSuccess=true; + DLSYM(f_avcodec_init,fn_avcodec_init,"avcodec_init"); + DLSYM(f_avcodec_init,fn_avcodec_register_all,"avcodec_register_all"); + DLSYM(f_avcodec_find_encoder,fn_avcodec_find_encoder,"avcodec_find_encoder"); + DLSYM(f_avcodec_alloc_context,fn_avcodec_alloc_context,"avcodec_alloc_context"); + DLSYM(f_avcodec_alloc_frame,fn_avcodec_alloc_frame,"avcodec_alloc_frame"); + DLSYM(f_avcodec_open,fn_avcodec_open,"avcodec_open"); + DLSYM(f_avcodec_close,fn_avcodec_close,"avcodec_close"); + DLSYM(f_avcodec_encode_video,fn_avcodec_encode_video,"avcodec_encode_video"); + DLSYM(f_avpicture_fill,fn_avpicture_fill,"avpicture_fill"); + DLSYM(f_img_convert,fn_img_convert,"img_convert"); + } + + return(bSuccess); +} + +/******************************************************************************* + +*/ +void cEncode::CloseLibAVCodec(void){ + + if (m_hLibAvcodec) + dlclose(m_hLibAvcodec); + m_hLibAvcodec = NULL; +} +#endif + +/******************************************************************************* + +*/ +cEncode::cEncode() +: m_pavCodec(NULL) +, m_pImageFilled(NULL) +, m_pImageYUV(NULL) +, m_nFrames(4) +, m_nData(0) +, m_pMPEG(NULL) +, m_pImageRGB(NULL) +{ + m_bLoaded = false; + m_pFramesSize = new unsigned int[m_nFrames]; + + m_bUsePAL = (cDevice::PrimaryDevice()->GetVideoSystem() == vsPAL); + m_nWidth = 720; + m_nHeight = m_bUsePAL ? 576 : 480; + + + m_nMaxMPEGSize = m_nWidth*m_nHeight * 3; //It see for me 500kb are enough, therefore should the double really enough memory + + /* Allocate bufers */ + if(NULL == (m_pMPEG=(uint8_t *)malloc(m_nMaxMPEGSize*3)) //~1200kb + || NULL == (m_pImageRGB=(uint8_t *)malloc(m_nWidth*m_nHeight*3)) //~1200kb + || NULL == (m_pImageFilled=(uint8_t *)malloc(m_nWidth*m_nHeight*3)) //~1200kb + || NULL == (m_pImageYUV=(uint8_t *)malloc(m_nWidth*m_nHeight*3/2))) //~600kb + { + esyslog("imageplugin: Failed to alloc memory for bitmaps."); + return; + } + + m_pavCodec = fn_avcodec_find_encoder(CODEC_ID_MPEG2VIDEO); + if (!m_pavCodec) { + esyslog("imageplugin: Failed to find CODEC_ID_MPEG2VIDEO."); + return; + } + m_bLoaded = true; +} + +bool cEncode::Register() +{ + #ifndef HAVE_FFMPEG_STATIC + if(!InitLibAVCodec()) { + esyslog("imageplugin: Failed to InitLibAVCodec."); + return false; + } + #endif + fn_avcodec_init(); + fn_avcodec_register_all(); + return true; +} + +void cEncode::UnRegister() +{ +#ifndef HAVE_FFMPEG_STATIC + CloseLibAVCodec(); +#endif +} + +void cEncode::ClearRGBMem() +{ + if(m_pImageRGB && m_bLoaded) + memset(m_pImageRGB,0,m_nWidth*m_nHeight*3 ); +} + +/******************************************************************************* + +*/ +cEncode::~cEncode(void) +{ + if(m_pImageYUV) + free(m_pImageYUV); + + if(m_pImageFilled) + free(m_pImageFilled); + + if(m_pImageRGB) + free(m_pImageRGB); + + if(m_pMPEG) + free(m_pMPEG); + delete m_pFramesSize; +} + +/******************************************************************************* + +*/ +bool cEncode::Encode() +{ + m_nData = 0; + + if (!m_bLoaded){ + dsyslog("imageplugin: libavcodec is'nt successful loaded."); + return false; + } + + bool bSuccess = false; + unsigned int i; + AVCodecContext *pAVCC = NULL; + AVFrame *pAVF = NULL; + int nSize=m_nWidth*m_nHeight; + + if(NULL == (pAVCC = fn_avcodec_alloc_context()) + || NULL == (pAVF = fn_avcodec_alloc_frame())) { + esyslog("imageplugin: Failed to alloc memory for AVCODEC and CONTEXT."); + goto encexit; + } + + pAVCC->bit_rate=1000000; //1000kbit + pAVCC->width = m_nWidth; + pAVCC->height = m_nHeight; + pAVCC->frame_rate=GetFrameRate(); + pAVCC->frame_rate_base=1; + pAVCC->gop_size=m_nFrames-1; //IPB //1 => Encode only I-Frames, bigger + pAVCC->max_b_frames=1; + pAVCC->flags |= CODEC_FLAG_QSCALE; + + if (fn_avcodec_open(pAVCC, m_pavCodec)<0) { + esyslog("imageplugin: Coldn't open Codec."); + goto encexit; + } + + pAVF->data[0]=m_pImageYUV; + pAVF->data[1]=m_pImageYUV+nSize; + pAVF->data[2]=pAVF->data[1]+nSize/4; + pAVF->linesize[0]=m_nWidth; + pAVF->linesize[1]=pAVF->linesize[2]=m_nWidth/2; + pAVF->quality = 1; + + // Convert RGB to YUV + if(!fn_avpicture_fill((AVPicture*)m_pImageFilled, m_pImageRGB, PIX_FMT_RGB24, + m_nWidth, m_nHeight)) { + esyslog("imageplugin: failed avpicture_fill"); + goto encexit; + } + + if(fn_img_convert((AVPicture*)pAVF->data, PIX_FMT_YUV420P, + (AVPicture*)m_pImageFilled, PIX_FMT_RGB24, m_nWidth, m_nHeight)) { + esyslog("imageplugin: failed convert RGB to YUV"); + goto encexit; + } + + // Encode Frames which defined with m_nFrames + for(i=0; i + * Created: Thu Aug 5 2004 + * + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _ENCODE_H +#define _ENCODE_H + +extern "C" +{ +#ifdef HAVE_FFMPEG_STATIC +# include +#else +# include +//#include +#endif +} + +//#define TESTCODE + +class cEncode +{ + AVCodec *m_pavCodec; + unsigned int m_nMaxMPEGSize; + uint8_t *m_pImageFilled; + uint8_t *m_pImageYUV; +protected: + const unsigned int m_nFrames; + unsigned int m_nData; + uint8_t *m_pMPEG; + uint8_t *m_pImageRGB; + bool m_bUsePAL; + unsigned int m_nWidth; + unsigned int m_nHeight; + unsigned int* m_pFramesSize; + +#ifndef HAVE_FFMPEG_STATIC +private: + static void *m_hLibAvcodec; +protected: + static bool InitLibAVCodec(void); + static void CloseLibAVCodec(void); +#endif + bool m_bLoaded; +public: + cEncode(); + virtual ~cEncode(); + + /*Load Shared Library and Register Codec*/ + static bool Register(); + /*UnLoad Shared*/ + static void UnRegister(); + + bool Encode(); + inline const uint8_t *Data() const { return m_pMPEG; } + inline unsigned int Size() const { return m_nData; } + inline unsigned int GetFrames() const { return m_nFrames; } + inline unsigned int GetFrameRate() const { return m_bUsePAL?25:30; } + + inline unsigned int GetHeight() const { return m_nHeight; } + inline unsigned int GetWidth() const { return m_nWidth; } + inline unsigned int GetBorderHeight() const { return 16; } + inline unsigned int GetBorderWidth() const { return 16; } + + inline uint8_t *GetRGBMem() { return m_pImageRGB; } +#ifdef TESTCODE + bool Load(const char* szFileName); + bool Save(const char* szFileName) const; +#endif + void ClearRGBMem (); +}; + +#endif /* _ENCODE_H */ diff --git a/liboutput/stillimage-player.c b/liboutput/stillimage-player.c new file mode 100644 index 0000000..947157e --- /dev/null +++ b/liboutput/stillimage-player.c @@ -0,0 +1,61 @@ +/*************************************************************************** + * stillimage-player.c + * (C) Copyright 2004 Andreas Brachold + * Created: Thu Aug 5 2004 + * + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "stillimage-player.h" +#include "stillimage.h" + +cStillImagePlayer::cStillImagePlayer(ePlayMode PlayMode) + : cPlayer(PlayMode) + , m_bActive(false) + , m_StillImage(this) +{ +} + +cStillImagePlayer::~cStillImagePlayer() +{ + Detach(); +} + +void cStillImagePlayer::Activate(bool On) { + if (On) { + m_bActive=m_StillImage.Init(); + } else { + if (m_bActive) { + m_StillImage.Stop(); + m_bActive=false; + } + } +} + +void cStillImagePlayer::Play(const uchar *Data, int Length) { +#if VDRVERSNUM < 10318 + PlayVideo(Data, Length); +#else + PlayPes(Data, Length,true); +#endif +} + +bool cStillImagePlayer::Wait() { + cPoller Poller; + return DevicePoll(Poller, 100); +} diff --git a/liboutput/stillimage-player.h b/liboutput/stillimage-player.h new file mode 100644 index 0000000..b3aa712 --- /dev/null +++ b/liboutput/stillimage-player.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * stillimage-player.h + * (C) Copyright 2004 Andreas Brachold + * Created: Thu Aug 5 2004 + * + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef STILLIMAGEPLAYER_H +#define STILLIMAGEPLAYER_H + +#include +#include + +#include "stillimage.h" + +class cStillImagePlayer + : public cPlayer { + friend class cStillImage; + bool m_bActive; +protected: + cStillImage m_StillImage; +public: + cStillImagePlayer(ePlayMode PlayMode); + virtual ~cStillImagePlayer(); + + inline unsigned int UseWidth() const + { return m_StillImage.GetWidth() - (m_StillImage.GetBorderWidth()*2); } + inline unsigned int UseHeight() const + { return m_StillImage.GetHeight() - (m_StillImage.GetBorderHeight()*2); } +protected: + virtual void Activate(bool On); + void Play(const uchar *Data, int Length); + bool Wait(); + + virtual bool Worker(bool bDoIt) = 0; +}; + + +#endif diff --git a/liboutput/stillimage.c b/liboutput/stillimage.c new file mode 100644 index 0000000..9058ff0 --- /dev/null +++ b/liboutput/stillimage.c @@ -0,0 +1,210 @@ +/*************************************************************************** + * stillimage.c + * (C) Copyright 2004 + * Created: Thu Aug 5 2004 + * + * parts of the code (c) Peter Seyringer + * (c) Marcel Wiesweg + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include +#include + +#include "stillimage.h" +#include "stillimage-player.h" + + + +cStillImage::cStillImage(cStillImagePlayer *pl) +{ + m_bThreadRun=false; + m_bEncodeRequired = false; + player=pl; +} + +cStillImage::~cStillImage() +{ + +} + +bool cStillImage::Init() +{ + return Start(); +} + +void cStillImage::Stop() +{ + if (!m_bThreadRun) + return; + m_bThreadRun=false; + + Cancel(3); +} + +void cStillImage::Action(void) +{ + m_bThreadRun=true; + bool bMPEGValid = false; + bool bQueueEmpty = false; + bool bFreeze = true; + + unsigned int nFrame = 0,nFrameOff=0; + int nMircoSekWait; + while (m_bThreadRun) { + + nMircoSekWait = 10000; + bQueueEmpty = player->Worker(false); + if(!bQueueEmpty) + { + if(!bFreeze) + { + player->DeviceFreeze(); + bFreeze = true; + } + player->Worker(true); + } + + if(m_bEncodeRequired + && bQueueEmpty) + { + //convert data to MPEG + Lock(); + bMPEGValid = Encode(); + Unlock(); + + if (!m_bThreadRun) + break; + m_bEncodeRequired = false; + nFrame = 0; + nFrameOff=0; + if(bFreeze) + { + player->DevicePlay(); + bFreeze = false; + } + + } + + + if(bMPEGValid + && bQueueEmpty) + { + /* Methode A ************************************************************/ + /*timeval timenow,diff,timestart; + gettimeofday(×tart, 0); + + for (int i=1;i<=25 && player->active;i++) { + gettimeofday(&timenow, 0); + timersub(&timenow, ×tart, &diff); + BuildPesPacket(Data(), Size(),(int)(diff.tv_sec*90000.0 + (diff.tv_usec*90000.0)/1000000.0)); + player->Wait(); + }*/ + + /* Methode B ************************************************************/ + //for (int i=1;i<= 25 && player->m_bActive;i++) { + // BuildPesPacket(Data(), Size(),i); + //} + + /* Methode C ************************************************************/ + //BuildPesPacket(Data(), Size(),1); + + /* Methode D ************************************************************/ + //player->DeviceStillPicture(Data(), Size()); + + /* Methode E ************************************************************/ + + + unsigned int nFrameSize = *(m_pFramesSize + nFrame); + if(nFrameSize) // Skip empty Frames + { + BuildPesPacket(Data() + nFrameOff, nFrameSize,1); + nFrameOff += nFrameSize; + } + if(++nFrame>=m_nFrames) + { + nFrame = 0; + nFrameOff = 0; + } + + nMircoSekWait = (1000000/(GetFrameRate()*4)); // Wait duration off 1/4 frame + + if (!m_bThreadRun) + break; + } + //Reduce CPU load!!! + usleep(max(10000,nMircoSekWait)); + } + m_bThreadRun=false; +} + + +//taken from mp1osd.c +void cStillImage::BuildPesPacket(const unsigned char *data, int len, int timestamp) { +#define PES_MAX_SIZE 2048 + int ptslen = timestamp ? 5 : 1; + static unsigned char pes_header[PES_MAX_SIZE]; + + // startcode: + pes_header[0] = pes_header[1] = 0; + pes_header[2] = 1; + pes_header[3] = 0xe0; + + while (len > 0) + { + int payload_size = len; // data + PTS + + if (6 + ptslen + payload_size > PES_MAX_SIZE) + payload_size = PES_MAX_SIZE - (6 + ptslen); + + // construct PES header: (code from ffmpeg's libav) + // packetsize: + pes_header[4] = (ptslen + payload_size) >> 8; + pes_header[5] = (ptslen + payload_size) & 255; + + if (ptslen == 5) + { + int x; + + // presentation time stamp: + x = (0x02 << 4) | (((timestamp >> 30) & 0x07) << 1) | 1; + pes_header[8] = x; + x = ((((timestamp >> 15) & 0x7fff) << 1) | 1); + pes_header[7] = x >> 8; + pes_header[8] = x & 255; + x = ((((timestamp) & 0x7fff) << 1) | 1); + pes_header[9] = x >> 8; + pes_header[10] = x & 255; + } + else + { + // stuffing and header bits: + pes_header[6] = 0x0f; + } + + memcpy (&pes_header[6 + ptslen], data, payload_size); + player->Wait(); + player->Play(pes_header, 6 + ptslen + payload_size); + + len -= payload_size; + data += payload_size; + ptslen = 1; // store PTS only once, at first packet! + + } +} diff --git a/liboutput/stillimage.h b/liboutput/stillimage.h new file mode 100644 index 0000000..453692c --- /dev/null +++ b/liboutput/stillimage.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * stillimage.h + * (C) Copyright 2004 Andreas Brachold + * Created: Thu Aug 5 2004 + * + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef STILLIMAGE_H +#define STILLIMAGE_H + +#include +#include "encode.h" + +class cStillImagePlayer; + + +class cStillImage +: public cThread +, public cEncode { + + cStillImagePlayer *player; + volatile bool m_bThreadRun; + volatile bool m_bEncodeRequired; +protected: + virtual void Action(void); + void BuildPesPacket(const unsigned char *data, int len, int timestamp); + +public: + cStillImage(cStillImagePlayer *); + virtual ~cStillImage(); + + bool Init(); + void Stop(); + bool EncodeRequired() const {return m_bEncodeRequired;} + void EncodeRequired(bool b) {m_bEncodeRequired = b;} +}; + +#endif -- cgit v1.2.3