summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Brachold <vdr07@deltab.de>2005-07-19 15:36:03 +0000
committerAndreas Brachold <vdr07@deltab.de>2005-07-19 15:36:03 +0000
commitb8671ccffc526763a64d7f7614dd8ba66e6fb540 (patch)
tree7bfb52099e19383fb1d4117a08b738f9a60e07c0
parentf897f2aa7055c493db6391c50c8d19da970078e8 (diff)
downloadvdr-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--Makefile14
-rw-r--r--image.c2
-rw-r--r--liboutput/Makefile7
-rw-r--r--liboutput/encode.c432
-rw-r--r--liboutput/encode.h92
-rw-r--r--liboutput/stillimage.c4
-rwxr-xr-xscripts/imageplugin.sh5
-rwxr-xr-xscripts/maverickplugin.sh161
8 files changed, 396 insertions, 321 deletions
diff --git a/Makefile b/Makefile
index 24b86d4..28c7a71 100644
--- a/Makefile
+++ b/Makefile
@@ -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):
diff --git a/image.c b/image.c
index fae80ca..95998b0 100644
--- a/image.c
+++ b/image.c
@@ -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