summaryrefslogtreecommitdiff
path: root/rotord/src/libavwrapper.h
diff options
context:
space:
mode:
authorComment <tim@gray.(none)>2013-07-26 22:46:17 +0100
committerComment <tim@gray.(none)>2013-07-26 22:46:17 +0100
commitf4170d6bfb763ad0af4002277a37dcd1692534d5 (patch)
treedb32d9753de780063e3afeb64764e13e5c4f5087 /rotord/src/libavwrapper.h
parent3d7eea02aa7a155b84c8c74ecbfd55a1941a9297 (diff)
tidy files
Diffstat (limited to 'rotord/src/libavwrapper.h')
-rwxr-xr-xrotord/src/libavwrapper.h279
1 files changed, 279 insertions, 0 deletions
diff --git a/rotord/src/libavwrapper.h b/rotord/src/libavwrapper.h
new file mode 100755
index 0000000..656f885
--- /dev/null
+++ b/rotord/src/libavwrapper.h
@@ -0,0 +1,279 @@
+#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
+ */
+
+////////////////////////
+//now that we have guards
+//instead of crashing instantly when the 2nd thread tries to encode a frame, we get an error
+
+ //*** Error in `./rotord': corrupted double-linked list: 0x00007f3c31b1b630 ***
+
+ //or
+
+ //*** Error in `./rotord': double free or corruption (out): 0x00007f3bf8210080 ***
+ ///////////////////////
+
+
+//http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/
+//great to use c++11 features
+
+#ifndef UINT64_C
+#define UINT64_C(c) (c ## ULL)
+#endif
+
+#include "Poco/Mutex.h"
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libavutil/pixfmt.h>
+#include <libavutil/opt.h>
+#include <libavutil/imgutils.h>
+#include <libavutil/samplefmt.h>
+
+#include <libswscale/swscale.h> //?
+}
+
+/*
+#include <QFile>
+#include <QNetworkAccessManager>
+#include <QMutex>
+#include <QUrl>
+#include <QBuffer>
+*/
+
+
+#include <string>
+#include <stdexcept>
+#include <iostream>
+#include <fstream>
+#include <math.h>
+#include <vector>
+
+
+
+namespace libav {
+
+
+
+ static bool b_is_one_time_inited=false;
+ // Some libavcodec calls are not reentrant
+
+ 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);
+ void cleanup();
+ virtual ~decoder();
+ //bool open(QUrl url, enum PixelFormat formatParam = PIX_FMT_RGB24);
+ //bool open(QIODevice& fileStream, QString& fileName, enum PixelFormat formatParam = PIX_FMT_RGB24);
+ bool reinit_buffers_and_scaler();
+ bool init_buffers_and_scaler();
+ uint8_t getPixelIntensity(int x, int y, Channel c = GRAY) const;
+ bool fetchFrame(int targetFrameIndex = 0);
+ bool fetchFrame(int w,int h,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_H264);
+ 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;
+
+ AVStream *audio_st;
+ AVStream *video_st;
+
+ AVCodecContext *aCtx;
+ 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;
+
+ struct SwsContext *sws_ctx;
+
+ 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;
+
+
+ };
+
+ class audioloader{
+ public:
+ audioloader(){ready=false;sample_start=0;sample_end=0;};
+ bool setup(const std::string &filename);
+ AVFrame* get_frame();
+ uint16_t* get_samples(int num);
+ AVPacket* get_packet();
+ bool close();
+ bool ready;
+
+ AVCodecContext* codecContext;
+ AVFormatContext* formatContext;
+ int channels; //necessary to handle final packet -- unititialised after load/ problem?
+ private:
+ std::vector<uint16_t> buffer;
+ AVFrame* frame;
+
+ AVStream* audioStream;
+
+ AVPacket packet;
+ int sample_end;
+ int sample_start;
+ bool isPlanar;
+
+ };
+
+}
+
+
+
+#endif // libavwrapper_H