#ifndef libavwrapper_H #define libavwrapper_H /* * libavwrapper.h * May 2012 Christopher Bruns * The libavwrapper class is a C++ wrapper around the poorly documented * libavcodec movie API used by ffmpeg. I made extensive use of Nathan * Clack's implemention in the whisk project. * * The libavwrapper.h and libavwrapper.cpp files depend only on the libavcodec * and allied sets of libraries. To compartmentalize and reduce dependencies * I placed the Vaa3d specific use of this class into a separate set of * source files: loadV3dFFMpeg.h/cpp */ #ifndef UINT64_C #define UINT64_C(c) (c ## ULL) #endif extern "C" { #include #include #include #include #include #include //? } /* #include #include #include #include #include */ #include #include #include #include namespace libav { static bool b_is_one_time_inited=false; // Some libavcodec calls are not reentrant //static QMutex mutex; void maybeInitFFMpegLib(); static int sws_flags = SWS_BICUBIC; // Translated to C++ by Christopher Bruns May 2012 // from ffmeg_adapt.c in whisk package by Nathan Clack, Mark Bolstadt, Michael Meeuwisse class decoder { public: enum Channel { RED = 0, GRAY = 0, GREEN = 1, BLUE = 2, ALPHA = 3 }; decoder(PixelFormat pixelFormat=PIX_FMT_RGB24); //decoder(QUrl url, PixelFormat pixelFormat=PIX_FMT_RGB24); virtual ~decoder(); //bool open(QUrl url, enum PixelFormat formatParam = PIX_FMT_RGB24); //bool open(QIODevice& fileStream, QString& fileName, enum PixelFormat formatParam = PIX_FMT_RGB24); uint8_t getPixelIntensity(int x, int y, Channel c = GRAY) const; bool fetchFrame(int targetFrameIndex = 0); int getNumberOfFrames() const; int getWidth() const; int getHeight() const; int getNumberOfChannels() const; bool readNextFrame(int targetFrameIndex = 0); bool readNextFrameWithPacket(int targetFrameIndex, AVPacket& packet, AVFrame* pYuv); int seekToFrame(int targetFrameIndex = 0); // make certain members public, for use by Fast3DTexture class AVFrame *pFrameRGB; AVFrame *pRaw; AVFormatContext *container; AVCodecContext *pCtx; int videoStream; int previousFrameIndex; bool isOpen; bool open(std::string& fileName, enum PixelFormat formatParam = PIX_FMT_RGB24); bool open(char* fileName, enum PixelFormat formatParam = PIX_FMT_RGB24); protected: void initialize(); bool openUsingInitializedContainer(enum PixelFormat formatParam = PIX_FMT_RGB24 ); static bool avtry(int result, const std::string& msg); AVCodec *pCodec; uint8_t *buffer, *blank; //struct SwsContext *Sctx; int width, height; PixelFormat format; size_t numBytes; int numFrames; int sc; // number of color channels // For loading from URL /* static const int ioBufferSize = 32768; unsigned char * ioBuffer; QNetworkAccessManager networkManager; AVIOContext* avioContext; QFile fileStream; QNetworkReply* reply; QBuffer fileBuffer; QByteArray byteArray; */ }; // TODO - finish refactoring based on // http://svn.gnumonks.org/trunk/21c3-video/ffmpeg/ffmpeg-0.4.9-pre1/output_example.c class encoder { public: //typedef encoder::Channel Channel; encoder(const char * file_name, int width, int height, float _framerate=25.0f, enum AVCodecID codec_id = CODEC_ID_MPEG4); virtual ~encoder(); void setPixelIntensity(int x, int y, int c, uint8_t value); void write_frame(float seconds,uint8_t *rgbdata); void write_frame(float seconds,uint16_t *audiodata); int get_audio_framesize(){ return audio_input_frame_size; } float get_audio_step(){return audiostep;}; protected: AVFormatContext *container; AVCodecContext *pCtx; AVFrame *picture_yuv; AVFrame *picture_rgb; AVFrame *audio_frame; float timebase; struct SwsContext *Sctx; int audio_input_frame_size; float audiostep; }; class exporter { public: virtual ~exporter(); bool setup(int w,int h, int bitRate, int frameRate, std::string container); bool record(std::string filename); bool encodeFrame(unsigned char *pixels, uint16_t *samples); bool encodeFrame(unsigned char *pixels,AVPacket *audiopkt); //is possible to just copy the packets? bool encodeFrame(unsigned char *pixels); bool encodeFrame(uint16_t *samples); void finishRecord(); int get_audio_framesize(){return audioframesize;}; float get_audio_step(){return audiostep;}; AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,enum AVCodecID codec_id); void open_video(AVFormatContext *oc, AVCodec *codec, AVStream *st); int open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st); void write_audio_frame(AVFormatContext *oc, AVStream *st,uint16_t *samples); void write_audio_frame(AVFormatContext *oc, AVStream *st,AVPacket *pkt); void close_audio(AVFormatContext *oc, AVStream *st); void write_video_frame(AVFormatContext *oc, AVStream *st, uint8_t *pixels); void close_video(AVFormatContext *oc, AVStream *st); private: AVOutputFormat *fmt; AVFormatContext *oc; AVStream *audio_st, *video_st; AVCodec *audio_codec, *video_codec; double audio_pts, video_pts; int audioframesize; float audiostep; int w; int h; int bitRate; int frameRate; std::string container; int outputframe; // video output // AVFrame *frame; AVPicture src_picture, dst_picture; int frame_count; uint8_t *outPixels; //************************************************************// // audio output // float t, tincr, tincr2; int audio_input_frame_size; }; } #endif // libavwrapper_H