* Optionally use libswscale for color space conversion. Have not done any

performance tests, but I wrote this code before David got around to improve
   his color space assembler code and didn't want to throw it away. Turned
   off for the time being, since David's version works fine.
 * Supply a codec sub_id in the media_codec_info. This allows matching
   decoders to encoders, which comes in handy for Smart Rendering in Clockwerk.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34931 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2010-01-07 01:18:32 +00:00
parent 856d0bbf95
commit dfddb9f479
2 changed files with 63 additions and 0 deletions
@@ -36,6 +36,8 @@
static int sDumpedPackets = 0;
#endif
#define USE_SWS_FOR_COLOR_SPACE_CONVERSION 0
struct wave_format_ex {
uint16 format_tag;
@@ -72,7 +74,11 @@ AVCodecDecoder::AVCodecDecoder()
fCodecInitDone(false),
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
fSwsContext(NULL),
#else
fFormatConversionFunc(NULL),
#endif
fExtraData(NULL),
fExtraDataSize(0),
@@ -115,6 +121,11 @@ AVCodecDecoder::~AVCodecDecoder()
free(fInputPicture);
free(fContext);
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
if (fSwsContext != NULL)
sws_freeContext(fSwsContext);
#endif
delete[] fExtraData;
delete[] fOutputBuffer;
}
@@ -126,6 +137,8 @@ AVCodecDecoder::GetCodecInfo(media_codec_info* mci)
sprintf(mci->short_name, "ff:%s", fCodec->name);
sprintf(mci->pretty_name, "%s (libavcodec %s)",
gCodecTable[fCodecIndexInTable].prettyname, fCodec->name);
mci->id = 0;
mci->sub_id = gCodecTable[fCodecIndexInTable].id;
}
@@ -453,7 +466,11 @@ AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat)
// time using another pixel-format that is supported by the decoder.
// But libavcodec doesn't seem to offer any way to tell the decoder
// which format it should use.
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
fSwsContext = NULL;
#else
fFormatConversionFunc = 0;
#endif
// Iterate over supported codec formats
for (int i = 0; i < 1; i++) {
// close any previous instance
@@ -465,11 +482,19 @@ AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat)
if (avcodec_open(fContext, fCodec) >= 0) {
fCodecInitDone = true;
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
fSwsContext = sws_getContext(fContext->width, fContext->height,
fContext->pix_fmt, fContext->width, fContext->height,
colorspace_to_pixfmt(fOutputVideoFormat.display.format),
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
#else
fFormatConversionFunc = resolve_colorspace(
fOutputVideoFormat.display.format, fContext->pix_fmt);
}
if (fFormatConversionFunc != NULL)
break;
#endif
}
if (!fCodecInitDone) {
@@ -477,10 +502,17 @@ AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat)
return B_ERROR;
}
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
if (fSwsContext == NULL) {
TRACE("No SWS Scale context or decoder has not set the pixel format "
"yet!\n");
}
#else
if (fFormatConversionFunc == NULL) {
TRACE("no pixel format conversion function found or decoder has "
"not set the pixel format yet!\n");
}
#endif
if (fOutputVideoFormat.display.format == B_YCbCr422) {
fOutputVideoFormat.display.bytes_per_row
@@ -707,15 +739,29 @@ AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount,
// pixfmt_to_string(fContext->pix_fmt));
// Some decoders do not set pix_fmt until they have decoded 1 frame
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
if (fSwsContext == NULL) {
fSwsContext = sws_getContext(fContext->width, fContext->height,
fContext->pix_fmt, fContext->width, fContext->height,
colorspace_to_pixfmt(fOutputVideoFormat.display.format),
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
#else
if (fFormatConversionFunc == NULL) {
fFormatConversionFunc = resolve_colorspace(
fOutputVideoFormat.display.format, fContext->pix_fmt);
}
#endif
fOutputPicture->data[0] = (uint8_t*)outBuffer;
fOutputPicture->linesize[0]
= fOutputVideoFormat.display.bytes_per_row;
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
if (fSwsContext != NULL) {
#else
if (fFormatConversionFunc != NULL) {
#endif
if (useDeinterlacedPicture) {
AVFrame inputFrame;
inputFrame.data[0] = deinterlacedPicture.data[0];
@@ -727,11 +773,23 @@ AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount,
inputFrame.linesize[2] = deinterlacedPicture.linesize[2];
inputFrame.linesize[3] = deinterlacedPicture.linesize[3];
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
sws_scale(fSwsContext, inputFrame.data,
inputFrame.linesize, 0, fContext->height,
fOutputPicture->data, fOutputPicture->linesize);
#else
(*fFormatConversionFunc)(&inputFrame,
fOutputPicture, width, height);
#endif
} else {
#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
sws_scale(fSwsContext, fInputPicture->data,
fInputPicture->linesize, 0, fContext->height,
fOutputPicture->data, fOutputPicture->linesize);
#else
(*fFormatConversionFunc)(fInputPicture, fOutputPicture,
width, height);
#endif
}
}
if (fInputPicture->interlaced_frame)
@@ -14,6 +14,10 @@
#include <MediaFormats.h>
extern "C" {
#include "swscale.h"
}
#include "DecoderPlugin.h"
#include "ReaderPlugin.h"
@@ -80,6 +84,7 @@ private:
bool fCodecInitDone;
gfx_convert_func fFormatConversionFunc;
SwsContext* fSwsContext;
char* fExtraData;
int fExtraDataSize;