1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#ifndef FFMPEGVIDEO_H
#define FFMPEGVIDEO_H
/*
* FFMpegVideo.h
* May 2012 Christopher Bruns
* The FFMpegVideo 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 FFMpegVideo.h and FFMpegVideo.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
*/
#ifdef USE_FFMPEG
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/pixfmt.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
}
//#include <QFile>
//#include <QNetworkAccessManager>
//#include <QMutex>
//#include <QUrl>
//#include <QBuffer>
#include <string>
#include <stdexcept>
#include <iostream>
// Translated to C++ by Christopher Bruns May 2012
// from ffmeg_adapt.c in whisk package by Nathan Clack, Mark Bolstadt, Michael Meeuwisse
class FFMpegVideo
{
public:
enum Channel {
RED = 0,
GRAY = 0,
GREEN = 1,
BLUE = 2,
ALPHA = 3
};
// Some libavcodec calls are not reentrant
//static QMutex mutex;
static void maybeInitFFMpegLib();
FFMpegVideo(PixelFormat pixelFormat=PIX_FMT_RGB24);
//FFMpegVideo(QUrl url, PixelFormat pixelFormat=PIX_FMT_RGB24);
virtual ~FFMpegVideo();
//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;
protected:
static bool b_is_one_time_inited;
void initialize();
bool open(string& fileName, enum PixelFormat formatParam);
bool openUsingInitializedContainer(enum PixelFormat formatParam);
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 FFMpegEncoder
{
public:
typedef FFMpegVideo::Channel Channel;
FFMpegEncoder(const char * file_name, int width, int height, enum CodecID codec_id = CODEC_ID_MPEG4);
virtual ~FFMpegEncoder();
void setPixelIntensity(int x, int y, int c, uint8_t value);
void write_frame();
protected:
AVFormatContext *container;
AVCodecContext *pCtx;
AVFrame *picture_yuv;
AVFrame *picture_rgb;
struct SwsContext *Sctx;
};
#endif // USE_FFMPEG
#endif // FFMPEGVIDEO_H
|