/**
 *  GraphTFT plugin for the Video Disk Recorder 
 * 
 *  mpeg2decoder.c - A plugin for the Video Disk Recorder
 *
 *  (c) 2004 Lars Tegeler, Sascha Volkenandt  
 *
 * This code is distributed under the terms and conditions of the
 * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
 *
 * $Id: mpeg2decoder.h,v 1.3 2007/11/10 09:14:27 root Exp $
 *
 **/

//The most part of this Code is from the Softdevice Plugin:

#ifndef __GTFT_MPEG2DECODER_H
#define __GTFT_MPEG2DECODER_H

extern "C"
{
#include <avcodec.h>
}
#include <vdr/plugin.h>
#include <vdr/ringbuffer.h>
#define MAX_HDR_LEN 0xFF

extern void *(* fast_memcpy)(void *to, const void *from, size_t len);

// Output device handler

class cStreamDecoder  
{
   private:

      unsigned int streamID; // stream to filter
      unsigned int syncword;
      int payload;
      int state;
      int headerLength;
      unsigned char * hdr_ptr;

   protected:
      uint64_t *cPTS;
      int64_t pts;
      int frame;
      bool validPTS;
      unsigned char header[MAX_HDR_LEN];     
      AVCodec *codec;
      AVCodecContext *context;
      int ParseStream(uchar *Data, int Length);

   public:

      virtual int DecodeData(uchar *Data, int Length) = 0;
      virtual void Write(uchar *Data, int Length) = 0;

      cStreamDecoder(unsigned int StreamID);
      virtual ~cStreamDecoder();
      void SyncPTS(uint64_t spts);
};


class cAudioStreamDecoder : public cStreamDecoder 
{
   private:

      uint8_t * audiosamples;

   public:

      virtual int DecodeData(uchar *Data, int Length);
      cAudioStreamDecoder(unsigned int StreamID, /*cAudioOut *AudioOut,*/ uint64_t *commonPTS);
      ~cAudioStreamDecoder();
      virtual void Write(uchar *Data, int Length);

};

class cVideoStreamDecoder : public cStreamDecoder , cThread 
{
   private:

      AVFrame *picture;
      uint8_t *rgbpic_dat;
      AVPicture rgbpic;
      //cVideoOut *videoOut;
      uint64_t vpts;
      int avgOffset;
      cRingBufferLinear *ringBuffer;
      unsigned char *_frame_buffer;
      int _res_x, _res_y, _fb_type;
      bool active;
      bool running;
      void resetCodec(void);

   protected:

      virtual void Action(void);

   public:

      virtual int DecodeData(uchar *Data, int Length);
      cVideoStreamDecoder(unsigned int StreamID, unsigned char *frame_buffer, int fb_type, int res_x, int res_y ,/* cVideoOut *VideoOut,*/ uint64_t *commonPTS);
      ~cVideoStreamDecoder();
      virtual void Write(uchar *Data, int Length);
};


class cMpeg2Decoder 
{

   private:

      uint8_t * audiosamples;
      int  state, payload, streamtype;
      unsigned char header[6];     
      unsigned int syncword;
      cStreamDecoder *vout, *aout;
      //cAudioOut *audioOut;
      //cVideoOut *videoOut;
      uint64_t commonPTS;
      bool running;
      bool decoding;
      unsigned char *_frame_buffer;
      int _res_x, _res_y, _fb_type;

   public:

      cMpeg2Decoder(unsigned char *frame_buffer, int fb_type, int res_x, int res_y /*cAudioOut *AudioOut, cVideoOut *VideoOut*/);
      ~cMpeg2Decoder();
      int Decode(const uchar *Data, int Length);
      void Start(void);
      void Stop(void);
};

#endif // __GTFT_MPEG2DECODER_H
