aboutsummaryrefslogtreecommitdiffstats
path: root/mediaplugin/src/mediaplugins/ffmpeg
diff options
context:
space:
mode:
authortobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-12-22 18:21:41 +0000
committertobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-12-22 18:21:41 +0000
commit1822c266c552a76cdbe75288515b5abfa9a41d5d (patch)
tree7c522487d3c1bdb54ec1d3fcb1220f6cc1abddd9 /mediaplugin/src/mediaplugins/ffmpeg
parent71e7b0bb663197c4bbc4aad55082dd6424e0fb33 (diff)
downloadusdx-1822c266c552a76cdbe75288515b5abfa9a41d5d.tar.gz
usdx-1822c266c552a76cdbe75288515b5abfa9a41d5d.tar.xz
usdx-1822c266c552a76cdbe75288515b5abfa9a41d5d.zip
support for video pixel format selection
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2767 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'mediaplugin/src/mediaplugins/ffmpeg')
-rw-r--r--mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.cpp20
-rw-r--r--mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.h1
-rw-r--r--mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp39
-rw-r--r--mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h29
4 files changed, 58 insertions, 31 deletions
diff --git a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.cpp b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.cpp
index d33af650..79f353e1 100644
--- a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.cpp
+++ b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.cpp
@@ -187,6 +187,26 @@ bool MediaCore_FFmpeg::convertFFmpegToAudioFormat(SampleFormat ffmpegFormat, aud
return true;
}
+bool MediaCore_FFmpeg::convertVideoFrameFormatToFFmpeg(videoFrameFormat_t format, enum PixelFormat *ffmpegFormat) const {
+ switch (format) {
+ case FRAME_FORMAT_RGB:
+ *ffmpegFormat = PIX_FMT_RGB24;
+ break;
+ case FRAME_FORMAT_RGBA:
+ *ffmpegFormat = PIX_FMT_RGB32; //PIX_FMT_RGBA;
+ break;
+ case FRAME_FORMAT_BGR:
+ *ffmpegFormat = PIX_FMT_BGR24;
+ break;
+ case FRAME_FORMAT_BGRA:
+ *ffmpegFormat = PIX_FMT_BGR32; //PIX_FMT_BGRA;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
/**
* UTF-8 Filename wrapper based on:
* http://www.mail-archive.com/libav-user@mplayerhq.hu/msg02460.html
diff --git a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.h b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.h
index 524e37b4..37b9067c 100644
--- a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.h
+++ b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_core.h
@@ -118,6 +118,7 @@ public:
bool findStreamIDs(AVFormatContext *formatCtx, int *firstVideoStream, int *firstAudioStream) const;
int findAudioStreamIndex(AVFormatContext *formatCtx) const;
bool convertFFmpegToAudioFormat(SampleFormat ffmpegFormat, audioSampleFormat_t *format) const;
+ bool convertVideoFrameFormatToFFmpeg(videoFrameFormat_t format, enum PixelFormat *ffmpegFormat) const;
public:
class AVCodecLock {
diff --git a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp
index 8107c1b2..ad34c7f3 100644
--- a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp
+++ b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp
@@ -67,6 +67,8 @@ FFmpegVideoDecodeStream::FFmpegVideoDecodeStream() :
_codec(NULL),
_avFrame(NULL),
_avFrameRGB(NULL),
+ _frameFormat(FRAME_FORMAT_UNKNOWN),
+ _pixelFormat(PIX_FMT_NONE),
_frameBuffer(NULL),
_frameTexValid(false),
#ifdef USE_SWSCALE
@@ -77,16 +79,18 @@ FFmpegVideoDecodeStream::FFmpegVideoDecodeStream() :
_frameTime(0),
_loopTime(0) {}
-FFmpegVideoDecodeStream* FFmpegVideoDecodeStream::open(const IPath &filename) {
+FFmpegVideoDecodeStream* FFmpegVideoDecodeStream::open(const IPath &filename,
+ videoFrameFormat_t format)
+{
FFmpegVideoDecodeStream *stream = new FFmpegVideoDecodeStream();
- if (!stream->_open(filename)) {
+ if (!stream->_open(filename, format)) {
delete stream;
return 0;
}
return stream;
}
-bool FFmpegVideoDecodeStream::_open(const IPath &filename) {
+bool FFmpegVideoDecodeStream::_open(const IPath &filename, videoFrameFormat_t format) {
std::stringstream ss;
// use custom 'ufile' protocol for UTF-8 support
@@ -169,10 +173,20 @@ bool FFmpegVideoDecodeStream::_open(const IPath &filename) {
logger.status(ss.str(), "");
#endif
+ _frameFormat = format;
+ // choose default (use BGR-format for accelerated colorspace conversion with swscale)
+ if (_frameFormat == FRAME_FORMAT_UNKNOWN)
+ _frameFormat = FRAME_FORMAT_BGR;
+ if (!ffmpegCore->convertVideoFrameFormatToFFmpeg(_frameFormat, &_pixelFormat)) {
+ logger.error("Invalid pixel format", "VideoPlayback_ffmpeg.Open");
+ close();
+ return false;
+ }
+
// allocate space for decoded frame and rgb frame
_avFrame = avcodec_alloc_frame();
_avFrameRGB = avcodec_alloc_frame();
- _frameBuffer = (uint8_t*) av_malloc(avpicture_get_size(PIXEL_FMT_FFMPEG,
+ _frameBuffer = (uint8_t*) av_malloc(avpicture_get_size(_pixelFormat,
_codecContext->width, _codecContext->height));
if (!_avFrame || !_avFrameRGB || !_frameBuffer) {
@@ -184,7 +198,7 @@ bool FFmpegVideoDecodeStream::_open(const IPath &filename) {
// TODO: pad data for OpenGL to GL_UNPACK_ALIGNMENT
// (otherwise video will be distorted if width/height is not a multiple of the alignment)
errnum = avpicture_fill((AVPicture*)_avFrameRGB, _frameBuffer,
- PIXEL_FMT_FFMPEG, _codecContext->width, _codecContext->height);
+ _pixelFormat, _codecContext->width, _codecContext->height);
if (errnum < 0) {
logger.error("avpicture_fill failed: " + ffmpegCore->getErrorString(errnum),
"VideoPlayback_ffmpeg.Open");
@@ -223,7 +237,7 @@ bool FFmpegVideoDecodeStream::_open(const IPath &filename) {
// could be observed in comparison to the RGB versions.
_swScaleContext = sws_getCachedContext(NULL,
_codecContext->width, _codecContext->height, _codecContext->pix_fmt,
- _codecContext->width, _codecContext->height, PIXEL_FMT_FFMPEG,
+ _codecContext->width, _codecContext->height, _pixelFormat,
SWS_FAST_BILINEAR,
NULL, NULL, NULL);
if (!_swScaleContext) {
@@ -503,7 +517,7 @@ uint8_t* FFmpegVideoDecodeStream::getFrame(long double time) {
// I think this should be removed, but am not sure whether there should
// be some other replacement or a warning, Therefore, I leave it for now.
// April 2009, mischi
- errnum = img_convert((AVPicture*)_avFrameRGB, PIXEL_FMT_FFMPEG,
+ errnum = img_convert((AVPicture*)_avFrameRGB, _pixelFormat,
(AVPicture*)_avFrame, _codecContext->pix_fmt,
_codecContext->width, _codecContext->height);
#endif
@@ -587,6 +601,10 @@ double FFmpegVideoDecodeStream::getFrameAspect() {
return _aspect;
}
+videoFrameFormat_t FFmpegVideoDecodeStream::getFrameFormat() {
+ return _frameFormat;
+}
+
/************************************
* C Interface
************************************/
@@ -601,8 +619,10 @@ static BOOL PLUGIN_CALL ffmpegVideoDecoder_finalize() {
return TRUE;
}
-static videoDecodeStream_t* PLUGIN_CALL ffmpegVideoDecoder_open(const char *filename) {
- return (videoDecodeStream_t*)FFmpegVideoDecodeStream::open(filename);
+static videoDecodeStream_t* PLUGIN_CALL ffmpegVideoDecoder_open(const char *filename,
+ videoFrameFormat_t format)
+{
+ return (videoDecodeStream_t*)FFmpegVideoDecodeStream::open(filename, format);
}
static void PLUGIN_CALL ffmpegVideoDecoder_close(videoDecodeStream_t *stream) {
@@ -632,6 +652,7 @@ static void PLUGIN_CALL ffmpegVideoDecoder_getFrameInfo(videoDecodeStream_t *str
info->width = s->getFrameWidth();
info->height = s->getFrameHeight();
info->aspect = s->getFrameAspect();
+ info->format = s->getFrameFormat();
}
static uint8_t* PLUGIN_CALL ffmpegVideoDecoder_getFrame(videoDecodeStream_t *stream, long double time) {
diff --git a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h
index 9b0df889..addf2a82 100644
--- a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h
+++ b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h
@@ -32,25 +32,6 @@
//#define DEBUG_DISPLAY
//#define DEBUG_FRAMES
-// use BGR-format for accelerated colorspace conversion with swscale
-#ifdef USE_SWSCALE
-# define PIXEL_FMT_BGR
-#endif
-
-#define PIXEL_FMT_BGR
-
-#ifdef PIXEL_FMT_BGR
-# define PIXEL_FMT_FFMPEG PIX_FMT_BGR24
-# define PIXEL_FMT_SIZE 3
-// looks strange on linux
-//# define PIXEL_FMT_FFMPEG PIX_FMT_BGR32;
-//# define PIXEL_FMT_SIZE 4;
-#else
-// looks strange on linux:
-# define PIXEL_FMT_FFMPEG PIX_FMT_RGB24
-# define PIXEL_FMT_SIZE 3
-#endif
-
extern const videoDecoderInfo_t videoDecoderInfo;
class FFmpegVideoDecodeStream : public VideoDecodeStream {
@@ -68,6 +49,9 @@ private:
AVFrame *_avFrame;
AVFrame *_avFrameRGB;
+
+ videoFrameFormat_t _frameFormat;
+ enum PixelFormat _pixelFormat;
uint8_t *_frameBuffer; //**< stores a FFmpeg video frame
bool _frameTexValid; //**< if true, fFrameTex contains the current frame
@@ -87,7 +71,7 @@ private:
bool decodeFrame();
void synchronizeTime(AVFrame *frame, double &pts);
- bool _open(const IPath &filename);
+ bool _open(const IPath &filename, videoFrameFormat_t format);
void close();
public:
@@ -95,7 +79,7 @@ public:
close();
}
- static FFmpegVideoDecodeStream* open(const IPath &filename);
+ static FFmpegVideoDecodeStream* open(const IPath &filename, videoFrameFormat_t format);
virtual void setLoop(bool enable);
virtual bool getLoop();
@@ -105,8 +89,9 @@ public:
virtual int getFrameWidth();
virtual int getFrameHeight();
-
virtual double getFrameAspect();
+ virtual videoFrameFormat_t getFrameFormat();
+
virtual uint8_t* getFrame(long double time);
};