diff options
author | Andreas Brachold <vdr07@deltab.de> | 2005-07-19 15:36:03 +0000 |
---|---|---|
committer | Andreas Brachold <vdr07@deltab.de> | 2005-07-19 15:36:03 +0000 |
commit | b8671ccffc526763a64d7f7614dd8ba66e6fb540 (patch) | |
tree | 7bfb52099e19383fb1d4117a08b738f9a60e07c0 | |
parent | f897f2aa7055c493db6391c50c8d19da970078e8 (diff) | |
download | vdr-plugin-image-b8671ccffc526763a64d7f7614dd8ba66e6fb540.tar.gz vdr-plugin-image-b8671ccffc526763a64d7f7614dd8ba66e6fb540.tar.bz2 |
- add alternative script (scripts/maverickplugin.sh) for image converting with imagemagick
- adjust encoding parameter for new ffmpeg-releases, downwards compatible
- remove linking with dlfcn at runtime of libavcodec.so, now are linked at compiled time
- some code refactoring, to enhance readability
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | image.c | 2 | ||||
-rw-r--r-- | liboutput/Makefile | 7 | ||||
-rw-r--r-- | liboutput/encode.c | 432 | ||||
-rw-r--r-- | liboutput/encode.h | 92 | ||||
-rw-r--r-- | liboutput/stillimage.c | 4 | ||||
-rwxr-xr-x | scripts/imageplugin.sh | 5 | ||||
-rwxr-xr-x | scripts/maverickplugin.sh | 161 |
8 files changed, 396 insertions, 321 deletions
@@ -41,20 +41,10 @@ PACKAGE = vdr-$(ARCHIVE) ### Includes and Defines (add further entries here): -INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -I. +INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -I. -I$(FFMDIR) DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' DEFINES += -D_GNU_SOURCE - - -LIBS += liboutput/liboutput.a libimage/libimage.a - -ifdef FFMPEG_STATIC - INCLUDES += -I$(FFMDIR) - DEFINES += -DHAVE_FFMPEG_STATIC - LIBS += -L$(FFMDIR)/libavcodec -lavcodec -lz -else - LIBS += -ldl -rdynamic -endif +LIBS += liboutput/liboutput.a libimage/libimage.a -L$(FFMDIR)/libavcodec -lavcodec -lz ### The object files (add further files here): @@ -36,7 +36,7 @@ #include "commands.h" #include "liboutput/encode.h" -static const char *VERSION = "0.2.3"; +static const char *VERSION = "0.2.4"; static const char *DESCRIPTION = "A Image Viewer plugin"; static const char *MAINMENUENTRY = "Image"; diff --git a/liboutput/Makefile b/liboutput/Makefile index acac360..1f975fd 100644 --- a/liboutput/Makefile +++ b/liboutput/Makefile @@ -21,13 +21,6 @@ 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 diff --git a/liboutput/encode.c b/liboutput/encode.c index 351e30f..cfdf72a 100644 --- a/liboutput/encode.c +++ b/liboutput/encode.c @@ -26,175 +26,54 @@ #include <string.h> #include <stdlib.h> -#ifndef HAVE_FFMPEG_STATIC -#include <dlfcn.h> -#endif - #include "encode.h" #include <vdr/device.h> #include <vdr/tools.h> -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_pImageFilled(NULL) +, m_pImageYUV(NULL) +, m_nNumberOfFramesToEncode(4) +, 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_bUsePAL = (cDevice::PrimaryDevice()->GetVideoSystem() == vsPAL); - m_nWidth = 720; - m_nHeight = m_bUsePAL ? 576 : 480; + m_pFrameSizes = new unsigned int[m_nNumberOfFramesToEncode]; + // Just a wild guess: 3 x output image size should be enough for the MPEG + m_nMaxMPEGSize = m_nWidth * m_nHeight * 3; - m_nMaxMPEGSize = m_nWidth*m_nHeight * 3; //It see for me 500kb are enough, therefore should the double really enough memory + AllocateBuffers(); - /* 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; + m_pavCodec = avcodec_find_encoder(CODEC_ID_MPEG2VIDEO); + if (!m_pavCodec) { + esyslog("imageplugin: Failed to find CODEC_ID_MPEG2VIDEO."); + return; + } } 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; + avcodec_init(); + 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 ); + if(m_pImageRGB) + memset(m_pImageRGB, 0, m_nWidth * m_nHeight * 3 ); } /******************************************************************************* @@ -202,18 +81,8 @@ void cEncode::ClearRGBMem() */ 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; + ReleaseBuffers(); + delete m_pFrameSizes; } /******************************************************************************* @@ -221,109 +90,174 @@ cEncode::~cEncode(void) */ 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; - } + bool bSuccess = false; - 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<m_nFrames && m_nData < m_nMaxMPEGSize; ++i) - { - int nFrameSize = fn_avcodec_encode_video(pAVCC, m_pMPEG + m_nData, m_nMaxMPEGSize - m_nData, pAVF); - if(nFrameSize < 0) + AVCodecContext *pAVCC = NULL; + AVFrame *pAVF = NULL; + + pAVCC = avcodec_alloc_context(); + if (! pAVCC) + { + esyslog("imageplugin: Failed to alloc memory for AVCodecContext."); + } + else + { + pAVF = avcodec_alloc_frame(); + if (! pAVF) + { + esyslog("imageplugin: Failed to alloc memory for AVFrame."); + } + else + { + SetupEncodingParameters(pAVCC); + + if (avcodec_open(pAVCC, m_pavCodec) < 0) + { + esyslog("imageplugin: Couldn't open Codec."); + } + else + { + if (ConvertImageToFrame(pAVF)) + { + bSuccess = EncodeFrames(pAVCC, pAVF); + } + avcodec_close(pAVCC); + } + av_free(pAVF); + } + av_free(pAVCC); + } + return bSuccess; +} + +void cEncode::SetupEncodingParameters(AVCodecContext *context) +{ + context->bit_rate=1000000; //1000kbit + context->width = m_nWidth; + context->height = m_nHeight; + + #if LIBAVCODEC_BUILD >= 4754 + context->time_base=(AVRational){1, GetFrameRate()}; + #else + context->frame_rate=GetFrameRate(); + context->frame_rate_base=1; + #endif + + //IPB //1 => Encode only I-Frames, bigger + context->gop_size=m_nNumberOfFramesToEncode-1; + + context->max_b_frames=1; + context->flags |= CODEC_FLAG_QSCALE; + context->pix_fmt = PIX_FMT_YUV420P; +} + +bool cEncode::ConvertImageToFrame(AVFrame *frame) +{ + int nSize = m_nWidth*m_nHeight; + + frame->data[0]=m_pImageYUV; + frame->data[1]=m_pImageYUV+nSize; + frame->data[2]=frame->data[1]+nSize/4; + frame->linesize[0]=m_nWidth; + frame->linesize[1]=frame->linesize[2]=m_nWidth/2; + frame->quality = 1; + + // Convert RGB to YUV + if(!avpicture_fill((AVPicture*)m_pImageFilled, + m_pImageRGB, + PIX_FMT_RGB24, m_nWidth, m_nHeight)) + { + esyslog("imageplugin: failed avpicture_fill"); + return false; + } + else { - esyslog("imageplugin: Failed add %d frame, insufficient memory.",i); - bSuccess = false; - break; + if(img_convert((AVPicture*)frame->data, PIX_FMT_YUV420P, + (AVPicture*)m_pImageFilled, PIX_FMT_RGB24, + m_nWidth, m_nHeight)) + { + esyslog("imageplugin: failed convert RGB to YUV"); + return false; + } } - bSuccess = true; - m_nData += nFrameSize; - *(m_pFramesSize + i) = nFrameSize; - } + return true; +} - if(bSuccess && m_nData < m_nMaxMPEGSize) // if sufficient place present - { - //add four bytes end sequnce - memcpy(m_pMPEG + m_nData,"\0x00\0x00\0x01\0xb7",4); - m_nData += 4; - *(m_pFramesSize + i - 1) += 4; - - } - else bSuccess = false; +bool cEncode::EncodeFrames(AVCodecContext *context, AVFrame *frame) +{ + unsigned int i; + + m_nMPEGSize = 0; + + // Encode m_nNumberOfFramesToEncode number of frames + for(i=0; (i < m_nNumberOfFramesToEncode) && (m_nMPEGSize < m_nMaxMPEGSize); + ++i) + { + int nFrameSize = avcodec_encode_video(context, m_pMPEG + m_nMPEGSize, + m_nMaxMPEGSize - m_nMPEGSize, frame); + if(nFrameSize < 0) + { + esyslog("imageplugin: Failed to add frame %d, insufficient memory.", + i); + return false; + } + m_nMPEGSize += nFrameSize; + *(m_pFrameSizes + i) = nFrameSize; + } - #ifdef TESTCODE - if(bSuccess) + // Add four bytes MPEG end sequence + if ((m_nMaxMPEGSize - m_nMPEGSize) >= 4) + { + memcpy(m_pMPEG + m_nMPEGSize,"\0x00\0x00\0x01\0xb7",4); + m_nMPEGSize += 4; + *(m_pFrameSizes + i - 1) += 4; + } + else + { + esyslog("imageplugin: Failed to add MPEG end sequence, " + "insufficient memory."); + return false; + } + +#ifdef TESTCODE + // Dump generate date to file Save("/tmp/imagetest.mpg"); - #endif +#endif -encexit: - if (pAVCC) - { - fn_avcodec_close(pAVCC); - free(pAVCC); - } - - if(pAVF) - { - free(pAVF); - } - return bSuccess; + return true; +} + +void cEncode::AllocateBuffers() +{ + 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; + } } +void cEncode::ReleaseBuffers() +{ + if(m_pImageYUV) + free(m_pImageYUV); + + if(m_pImageFilled) + free(m_pImageFilled); + + if(m_pImageRGB) + free(m_pImageRGB); + if(m_pMPEG) + free(m_pMPEG); +} #ifdef TESTCODE /******************************************************************************* - + Load a PNM Bitmap with 24bit 720x576 direct into encoder memory */ bool cEncode::Load(const char* szFileName) { @@ -340,7 +274,7 @@ bool cEncode::Load(const char* szFileName) } /******************************************************************************* - + Save encoder memory as file for diagnostics */ bool cEncode::Save(const char* szFileName) const { @@ -355,15 +289,15 @@ bool cEncode::Save(const char* szFileName) const } return false; } -#endif - -#if 0 -int main(){ +/* +// Standalone test of encoder + int main(){ cEncode e; e.Load("test.pnm"); e.Encode(); e.Save("test.mpg"); return 0; } +*/ #endif diff --git a/liboutput/encode.h b/liboutput/encode.h index 0491927..15dd28d 100644 --- a/liboutput/encode.h +++ b/liboutput/encode.h @@ -25,68 +25,64 @@ #ifndef _ENCODE_H #define _ENCODE_H -extern "C" -{ -#ifdef HAVE_FFMPEG_STATIC -# include <libavcodec/avcodec.h> -#else -# include <ffmpeg/avcodec.h> -//#include <libavcodec/avcodec.h> -#endif -} +#include <ffmpeg/avcodec.h> //#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; + AVCodec *m_pavCodec; + unsigned int m_nMaxMPEGSize; + uint8_t *m_pImageFilled; + uint8_t *m_pImageYUV; -#ifndef HAVE_FFMPEG_STATIC -private: - static void *m_hLibAvcodec; protected: - static bool InitLibAVCodec(void); - static void CloseLibAVCodec(void); -#endif - bool m_bLoaded; + const unsigned int m_nNumberOfFramesToEncode; + uint8_t *m_pMPEG; + uint8_t *m_pImageRGB; + bool m_bUsePAL; + unsigned int m_nMPEGSize; + unsigned int m_nWidth; + unsigned int m_nHeight; + unsigned int *m_pFrameSizes; + public: - cEncode(); - virtual ~cEncode(); + 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_nMPEGSize; } + inline unsigned int GetFrames() const { return m_nNumberOfFramesToEncode; } + inline unsigned int GetFrameRate() const { return m_bUsePAL?25:30; } - /*Load Shared Library and Register Codec*/ - static bool Register(); - /*UnLoad Shared*/ - static void UnRegister(); + inline unsigned int GetFrameSize(unsigned int nframeNumber) const + { return *(m_pFrameSizes + nframeNumber); } - 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 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; } + void ClearRGBMem (); - inline uint8_t *GetRGBMem() { return m_pImageRGB; } #ifdef TESTCODE - bool Load(const char* szFileName); - bool Save(const char* szFileName) const; + bool Load(const char* szFileName); + bool Save(const char* szFileName) const; #endif - void ClearRGBMem (); + +private: + void AllocateBuffers(); + void ReleaseBuffers(); + void SetupEncodingParameters(AVCodecContext *context); + bool ConvertImageToFrame(AVFrame *frame); + bool EncodeFrames(AVCodecContext *context, AVFrame *frame); }; #endif /* _ENCODE_H */ diff --git a/liboutput/stillimage.c b/liboutput/stillimage.c index 9058ff0..12bd902 100644 --- a/liboutput/stillimage.c +++ b/liboutput/stillimage.c @@ -131,13 +131,13 @@ void cStillImage::Action(void) /* Methode E ************************************************************/ - unsigned int nFrameSize = *(m_pFramesSize + nFrame); + unsigned int nFrameSize = GetFrameSize(nFrame); if(nFrameSize) // Skip empty Frames { BuildPesPacket(Data() + nFrameOff, nFrameSize,1); nFrameOff += nFrameSize; } - if(++nFrame>=m_nFrames) + if(++nFrame>=GetFrames()) { nFrame = 0; nFrameOff = 0; diff --git a/scripts/imageplugin.sh b/scripts/imageplugin.sh index 2afd734..73635c1 100755 --- a/scripts/imageplugin.sh +++ b/scripts/imageplugin.sh @@ -1,8 +1,9 @@ #!/bin/bash # script for vdr-imageplugin to convert the selected image to pnm-image -# needs : netpbm-progs > anytopnm pnmscale pnmfile pnmcut pnmflip +# needs : netpbm-progs > anytopnm pnmscalefixed pnmfile pnmcut pnmflip # # History: +# 2005-06-17 wrong lookup for pnmscale and really are pnmscalefixed used # 2004-08-12 Initalrelease, Andreas Brachold <vdr04-at-deltab.de> # base on prior work for convert.sh # by Onno Kreuzinger <o.kreuzinger-at-kreuzinger.biz> @@ -46,7 +47,7 @@ fi ASPECT_RATIO="${ASPECT_RATIO:-"4:3"}" # check requirement external programs - REQUIREMENTS="anytopnm pnmscale pnmfile pnmcut pnmflip" + REQUIREMENTS="anytopnm pnmscalefixed pnmfile pnmcut pnmflip" for i in $REQUIREMENTS do type "$i" > /dev/null 2>&1 diff --git a/scripts/maverickplugin.sh b/scripts/maverickplugin.sh new file mode 100755 index 0000000..848c46e --- /dev/null +++ b/scripts/maverickplugin.sh @@ -0,0 +1,161 @@ +#!/bin/bash +# script for vdr-imageplugin to convert the selected image to pnm-image +# needs : imagemagick > identify convert +# +# History: +# 2005-06-17 Reimplement with imagemagick, Andreas Brachold +# 2004-08-12 Initalrelease, Andreas Brachold <vdr04-at-deltab.de> +# base on prior work for convert.sh +# by Onno Kreuzinger <o.kreuzinger-at-kreuzinger.biz> +# Andreas Holzhammer and <Interpohl-at-vdr-portal.de> +# +################################################################################ +# Userconfig: +################################################################################ +# if your install external software like netpbm outside /bin:/usr/bin, adjust folder +PATH=/usr/local/bin:$PATH +# Set to "no" if this script work and your don't need success messages +VERBOSE=yes +# Set to "yes" if this script don't work, only usable if your self execute the script from shell +DEBUG=no + +################################################################################ +# and now the script +################################################################################ +[ "z$DEBUG" = "zyes" ] && set -xv +SCRIPTNAME=$(basename "$0") +{ +[ "z$VERBOSE" = "zyes" ] && echo "called '$SCRIPTNAME $*'" + +if [ $# -lt 7 ] ; then + echo "Usage: $SCRIPTNAME infile outfile WIDTH HEIGHT ZOOMFACTOR LEFTPOS TOPPOS [FLIPCMD]" 1>&2 + echo " e.g.: $SCRIPTNAME in.png out.pnm 720 576 0 0 0" 1>&2 + echo " or .: $SCRIPTNAME in.png out.pnm 720 576 3 360 360 left" 1>&2 + echo "" 1>&2 + echo "WIDTH - Width of TVScreen (720)" 1>&2 + echo "HEIGHT - Height of TVScreen (480..576)" 1>&2 + echo "ZOOMFACTOR - Zoomfactor (0....10)" 1>&2 + echo "LEFTPOS - Offset from left on Zoommode (0......)" 1>&2 + echo "TOPPOS - Offset from top on Zoommode (0......)" 1>&2 + echo "FLIPCMD - optional should image flip (left,right,original)" 1>&2 + exit 1 +fi + + # Defaultvalue, overwrite with env from plugin + ASPECT_RATIO="${ASPECT_RATIO:-"4:3"}" + + # check requirement external programs + REQUIREMENTS="identify convert" + for i in $REQUIREMENTS + do + type "$i" > /dev/null 2>&1 + [ $? -ne 0 ] && echo -e "$SCRIPTNAME: Error ! External required program: \"$i\" not found !\n Please adjust PATH or install it inside follow Folder \"$PATH\" \n" && exit 1 + done + + INFILE="$1" + OUTFILE="$2" + OUT_DISPLAY_X=$3 + OUT_DISPLAY_Y=$4 + ZOOMFACTOR=$5 + LEFTPOS=$6 + TOPPOS=$7 + FLIPCMD="$8" + + OUTDIR=$(dirname "$OUTFILE") + [ ! -d "$OUTDIR" ] && mkdir -p "$OUTDIR" + + PARFILE="$OUTFILE.par" + + # remove precreated files if called with flip "left","right" or "original" + [ -s "$OUTFILE" -a "$FLIPCMD" != "" ] && rm -f "$OUTFILE" + + if [ -s "$OUTFILE" ] ; then + [ "z$VERBOSE" = "zyes" ] && echo "Success! Convert not required, $OUTFILE exists already!" + exit 0 + else + + # Get image resolution + RES=`echo $( identify "$INFILE" | cut -d " " -f 3 )` # checked with imagemagick 6.0.6, + # Parse identify output image.jpg JPEG 3456x2304 DirectClass 4.7mb 3.720u 0:04 + X_RES=$(echo -e "$RES"| cut -d "x" -f 1) + Y_RES=$(echo -e "$RES"| cut -d "x" -f 2) + + # set flip command + case "$FLIPCMD" in + right ) + FLIP="-rotate 270" + SWAPRES=$X_RES;X_RES=$Y_RES;Y_RES=$SWAPRES + ;; + left ) + FLIP="-rotate 90"; + SWAPRES=$X_RES;X_RES=$Y_RES;Y_RES=$SWAPRES + ;; + *) + FLIP=""; + ;; + esac + # Save config for plugin as readable file + echo "$X_RES" "$Y_RES" "$FLIPCMD" > "$PARFILE" + + # define aspect ratio depends plugin setup + if [ $ASPECT_RATIO = "16:9" ] ; then + SCALE_MIN_ASP=163 + SCALE_MAX_ASP=178 + else + SCALE_MIN_ASP=125 + SCALE_MAX_ASP=133 + fi + + # if zoom image, zoom it with factor + if [ "$ZOOMFACTOR" -gt 0 ] ; then + + ZOOM_X=$(($X_RES*$ZOOMFACTOR)) + ZOOM_Y=$(($Y_RES*$ZOOMFACTOR)) + + if [ "$LEFTPOS" -ge 0 ] ; then + LEFTPOS=$(echo -e "+$(($LEFTPOS))") + fi + if [ "$TOPPOS" -ge 0 ] ; then + TOPPOS=$(echo -e "+$(($TOPPOS))") + fi + + convert "$INFILE" \ + -size $(($ZOOM_X))x$(($ZOOM_Y)) \ + -crop $(($OUT_DISPLAY_X/$ZOOMFACTOR))x$(($OUT_DISPLAY_Y/$ZOOMFACTOR))$LEFTPOS$TOPPOS \ + $FLIP \ + -filter "Box" \ + -resize $(($OUT_DISPLAY_X))x$(($OUT_DISPLAY_Y)) \ + "$OUTFILE" + + # else scale image to TV Screensize + else + + if [ "$((${X_RES}00 / ${Y_RES}))" -lt $SCALE_MIN_ASP ] ; then + OUT_DISPLAY_X=$((${OUT_DISPLAY_Y}000 / $Y_RES * $X_RES / 1000)) + elif [ "$((${X_RES}00 / ${Y_RES}))" -gt $SCALE_MAX_ASP ] ; then + OUT_DISPLAY_Y=$((${OUT_DISPLAY_X}000 / $X_RES * $Y_RES / 1000)) + fi + + convert -size $(($OUT_DISPLAY_X))x$(($OUT_DISPLAY_Y)) "$INFILE" \ + $FLIP \ + -filter "Box" \ + -resize $(($OUT_DISPLAY_X))x$(($OUT_DISPLAY_Y)) \ + "$OUTFILE" + fi + fi + + if [ -s "$OUTFILE" ] ; then + [ "z$VERBOSE" = "zyes" ] && echo "Success! Stopped with created $OUTFILE" + exit 0 # Creation seem success, tell it with 'exit 0' to plugin + fi + [ "z$VERBOSE" = "zyes" ] && echo "Error! Stopped without found created $OUTFILE, converting should failed !" + exit 1 # Hmm, created is failed tell it with 'exit 1' to plugin + + +###### >>>>>>> !!! Only one of the follow lines are allowed (begins always with 2>&1 ) !!! +### Dump any message to syslog to see use cat /var/log/messages | grep imageplugin +} 2>&1 | logger -s -t "$SCRIPTNAME" +### If your wish don't any message logging +# 2>&1 > /dev/null +### If your wish old style message logging +# 2>&1 > /tmp/image/convert.log |