Encoder:
* Fleshed out the Encoder API to support parameter setters/getters and returning a BView for configuration. (Not yet sure if this is a good idea.) BMediaTrack: * Implemented all but one of the unimplemented methods in BMediaTrack. It should be working as far as that class is concerned, unless I missed some of the vision. ReplaceFrames() remains a stub, added a comment on why it probably stays that way. * Release the Encoder reference in the destructor. FFmpeg plugin: * Refactoring to delay opening the AVCodec until encoding the first chunk, so that we can still adjust parameters. * Support adjusting parameters via [Set|Get]EncodeParameters(). Currently, only quality is supported, added TODOs about supporting the bit_rate setup versus the automatically calculated bit_rate. * Extended EncoderDescription by a bit_rate scale. The Encoder calculates the raw bitrate needed by the current media format, and then divides that number by the specific codec's bit_rate_scale, while taking into account the desired quality. This seems to work very well already (tested with MPEG4), although a lot more parameters could be specified for libavcodec, depending on the desired quality. * Enabled the ogg muxer in libavformat, although it is currently still disabled in MuxerTable.cpp, because it rejects unknown codecs. Added TODO to this effect. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32124 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
048d05a613
commit
6780c24d36
@ -8,11 +8,10 @@
|
||||
|
||||
#include <MediaTrack.h>
|
||||
#include <MediaFormats.h>
|
||||
#include <View.h>
|
||||
#include "MediaPlugin.h"
|
||||
|
||||
|
||||
class AddOnManager;
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class PluginManager;
|
||||
@ -56,10 +55,20 @@ public:
|
||||
virtual status_t AddTrackInfo(uint32 code, const void* data,
|
||||
size_t size, uint32 flags = 0);
|
||||
|
||||
// Ownership of the BView and BParameterWeb remain with the Encoder.
|
||||
// A window embedding the view must remove it before it is destroyed.
|
||||
virtual BView* ParameterView();
|
||||
|
||||
virtual BParameterWeb* ParameterWeb();
|
||||
virtual status_t GetParameterValue(int32 id, void* value,
|
||||
size_t* size) const;
|
||||
virtual status_t SetParameterValue(int32 id, const void* value,
|
||||
size_t size);
|
||||
|
||||
virtual status_t GetEncodeParameters(
|
||||
encode_parameters* parameters) const;
|
||||
virtual status_t SetEncodeParameters(
|
||||
encode_parameters* parameters) const;
|
||||
encode_parameters* parameters);
|
||||
|
||||
virtual status_t Encode(const void* buffer, int64 frameCount,
|
||||
media_encode_info* info) = 0;
|
||||
@ -73,19 +82,36 @@ public:
|
||||
virtual status_t Perform(perform_code code, void* data);
|
||||
|
||||
private:
|
||||
virtual void _ReservedEncoder1();
|
||||
virtual void _ReservedEncoder2();
|
||||
virtual void _ReservedEncoder3();
|
||||
virtual void _ReservedEncoder4();
|
||||
virtual void _ReservedEncoder5();
|
||||
|
||||
ChunkWriter* fChunkWriter;
|
||||
|
||||
// needed for plug-in reference count management
|
||||
friend class PluginManager;
|
||||
MediaPlugin* fMediaPlugin;
|
||||
|
||||
uint32 fReserved[5];
|
||||
private:
|
||||
// FBC padding
|
||||
uint32 fReserved[20];
|
||||
|
||||
virtual void _ReservedEncoder1();
|
||||
virtual void _ReservedEncoder2();
|
||||
virtual void _ReservedEncoder3();
|
||||
virtual void _ReservedEncoder4();
|
||||
virtual void _ReservedEncoder5();
|
||||
virtual void _ReservedEncoder6();
|
||||
virtual void _ReservedEncoder7();
|
||||
virtual void _ReservedEncoder8();
|
||||
virtual void _ReservedEncoder9();
|
||||
virtual void _ReservedEncoder10();
|
||||
virtual void _ReservedEncoder11();
|
||||
virtual void _ReservedEncoder12();
|
||||
virtual void _ReservedEncoder13();
|
||||
virtual void _ReservedEncoder14();
|
||||
virtual void _ReservedEncoder15();
|
||||
virtual void _ReservedEncoder16();
|
||||
virtual void _ReservedEncoder17();
|
||||
virtual void _ReservedEncoder18();
|
||||
virtual void _ReservedEncoder19();
|
||||
virtual void _ReservedEncoder20();
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,12 +30,13 @@ extern "C" {
|
||||
static const size_t kDefaultChunkBufferSize = 2 * 1024 * 1024;
|
||||
|
||||
|
||||
AVCodecEncoder::AVCodecEncoder(uint32 codecID)
|
||||
AVCodecEncoder::AVCodecEncoder(uint32 codecID, int bitRateScale)
|
||||
:
|
||||
Encoder(),
|
||||
fBitRateScale(bitRateScale),
|
||||
fCodec(NULL),
|
||||
fContext(avcodec_alloc_context()),
|
||||
fCodecInitDone(false),
|
||||
fCodecInitStatus(CODEC_INIT_NEEDED),
|
||||
|
||||
fFrame(avcodec_alloc_frame()),
|
||||
fSwsContext(NULL),
|
||||
@ -52,6 +53,11 @@ AVCodecEncoder::AVCodecEncoder(uint32 codecID)
|
||||
memset(&fInputFormat, 0, sizeof(media_format));
|
||||
|
||||
av_fifo_init(&fAudioFifo, 0);
|
||||
|
||||
// Initial parameters, so we know if the user changed them
|
||||
fEncodeParameters.avg_field_size = 0;
|
||||
fEncodeParameters.max_field_size = 0;
|
||||
fEncodeParameters.quality = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
@ -59,8 +65,7 @@ AVCodecEncoder::~AVCodecEncoder()
|
||||
{
|
||||
TRACE("AVCodecEncoder::~AVCodecEncoder()\n");
|
||||
|
||||
if (fCodecInitDone)
|
||||
avcodec_close(fContext);
|
||||
_CloseCodecIfNeeded();
|
||||
|
||||
sws_freeContext(fSwsContext);
|
||||
|
||||
@ -119,15 +124,118 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
|
||||
if (inputFormat == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (fCodecInitDone) {
|
||||
fCodecInitDone = false;
|
||||
avcodec_close(fContext);
|
||||
}
|
||||
_CloseCodecIfNeeded();
|
||||
|
||||
fInputFormat = *inputFormat;
|
||||
fFramesWritten = 0;
|
||||
|
||||
return _Setup();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AVCodecEncoder::GetEncodeParameters(encode_parameters* parameters) const
|
||||
{
|
||||
TRACE("AVCodecEncoder::GetEncodeParameters(%p)\n", parameters);
|
||||
|
||||
// TODO: Implement maintaining an automatically calculated bit_rate versus
|
||||
// a user specified (via SetEncodeParameters()) bit_rate. At this point, the
|
||||
// fContext->bit_rate may not yet have been specified (_Setup() was never
|
||||
// called yet). So it cannot work like the code below, but in any case, it's
|
||||
// showing how to convert between the values (Albeit untested).
|
||||
// int avgBytesPerSecond = fContext->bit_rate / 8;
|
||||
// int maxBytesPerSecond = (fContext->bit_rate
|
||||
// + fContext->bit_rate_tolerance) / 8;
|
||||
//
|
||||
// if (fInputFormat.type == B_MEDIA_RAW_AUDIO) {
|
||||
// fEncodeParameters.avg_field_size = (int32)(avgBytesPerSecond
|
||||
// / fInputFormat.u.raw_audio.frame_rate);
|
||||
// fEncodeParameters.max_field_size = (int32)(maxBytesPerSecond
|
||||
// / fInputFormat.u.raw_audio.frame_rate);
|
||||
// } else if (fInputFormat.type == B_MEDIA_RAW_VIDEO) {
|
||||
// fEncodeParameters.avg_field_size = (int32)(avgBytesPerSecond
|
||||
// / fInputFormat.u.raw_video.field_rate);
|
||||
// fEncodeParameters.max_field_size = (int32)(maxBytesPerSecond
|
||||
// / fInputFormat.u.raw_video.field_rate);
|
||||
// }
|
||||
|
||||
parameters->quality = fEncodeParameters.quality;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AVCodecEncoder::SetEncodeParameters(encode_parameters* parameters)
|
||||
{
|
||||
TRACE("AVCodecEncoder::SetEncodeParameters(%p)\n", parameters);
|
||||
|
||||
if (fFramesWritten > 0)
|
||||
return B_NOT_SUPPORTED;
|
||||
|
||||
fEncodeParameters.quality = parameters->quality;
|
||||
TRACE(" quality: %.1f\n", parameters->quality);
|
||||
|
||||
// TODO: Auto-bit_rate versus user supplied. See above.
|
||||
// int avgBytesPerSecond = 0;
|
||||
// int maxBytesPerSecond = 0;
|
||||
//
|
||||
// if (fInputFormat.type == B_MEDIA_RAW_AUDIO) {
|
||||
// avgBytesPerSecond = (int)(parameters->avg_field_size
|
||||
// * fInputFormat.u.raw_audio.frame_rate);
|
||||
// maxBytesPerSecond = (int)(parameters->max_field_size
|
||||
// * fInputFormat.u.raw_audio.frame_rate);
|
||||
// } else if (fInputFormat.type == B_MEDIA_RAW_VIDEO) {
|
||||
// avgBytesPerSecond = (int)(parameters->avg_field_size
|
||||
// * fInputFormat.u.raw_video.field_rate);
|
||||
// maxBytesPerSecond = (int)(parameters->max_field_size
|
||||
// * fInputFormat.u.raw_video.field_rate);
|
||||
// }
|
||||
//
|
||||
// if (maxBytesPerSecond < avgBytesPerSecond)
|
||||
// maxBytesPerSecond = avgBytesPerSecond;
|
||||
//
|
||||
// // Reset these, so we can tell the difference between uninitialized
|
||||
// // and initialized...
|
||||
// if (avgBytesPerSecond > 0) {
|
||||
// fContext->bit_rate = avgBytesPerSecond * 8;
|
||||
// fContext->bit_rate_tolerance = (maxBytesPerSecond
|
||||
// - avgBytesPerSecond) * 8;
|
||||
// fBitRateControlledByUser = true;
|
||||
// }
|
||||
|
||||
return _Setup();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AVCodecEncoder::Encode(const void* buffer, int64 frameCount,
|
||||
media_encode_info* info)
|
||||
{
|
||||
TRACE("AVCodecEncoder::Encode(%p, %lld, %p)\n", buffer, frameCount, info);
|
||||
|
||||
if (!_OpenCodecIfNeeded())
|
||||
return B_NO_INIT;
|
||||
|
||||
if (fInputFormat.type == B_MEDIA_RAW_AUDIO)
|
||||
return _EncodeAudio(buffer, frameCount, info);
|
||||
else if (fInputFormat.type == B_MEDIA_RAW_VIDEO)
|
||||
return _EncodeVideo(buffer, frameCount, info);
|
||||
else
|
||||
return B_NO_INIT;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
AVCodecEncoder::_Setup()
|
||||
{
|
||||
TRACE("AVCodecEncoder::_Setup\n");
|
||||
|
||||
if (fInputFormat.type == B_MEDIA_RAW_VIDEO) {
|
||||
TRACE(" B_MEDIA_RAW_VIDEO\n");
|
||||
// frame rate
|
||||
fContext->time_base.den = (int)fInputFormat.u.raw_video.field_rate;
|
||||
fContext->time_base.num = 1;
|
||||
@ -144,7 +252,15 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
|
||||
// fContext->rc_max_rate = 0;
|
||||
// fContext->rc_min_rate = 0;
|
||||
// TODO: Try to calculate a good bit rate...
|
||||
fContext->bit_rate = 800000;
|
||||
int rawBitRate = (int)(fContext->width * fContext->height * 2
|
||||
* fInputFormat.u.raw_video.field_rate) * 8;
|
||||
int wantedBitRate = (int)(rawBitRate / fBitRateScale
|
||||
* fEncodeParameters.quality);
|
||||
TRACE(" rawBitRate: %d, wantedBitRate: %d (%.1f)\n", rawBitRate,
|
||||
wantedBitRate, fEncodeParameters.quality);
|
||||
// TODO: Support letting the user overwrite this via
|
||||
// SetEncodeParameters(). See comments there...
|
||||
fContext->bit_rate = wantedBitRate;
|
||||
|
||||
// Pixel aspect ratio
|
||||
fContext->sample_aspect_ratio.num
|
||||
@ -188,6 +304,7 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
|
||||
fContext->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
|
||||
|
||||
} else if (fInputFormat.type == B_MEDIA_RAW_AUDIO) {
|
||||
TRACE(" B_MEDIA_RAW_AUDIO\n");
|
||||
// frame rate
|
||||
fContext->sample_rate = (int)fInputFormat.u.raw_audio.frame_rate;
|
||||
// NOTE: From the output_example.c, it looks like we are not supposed
|
||||
@ -252,6 +369,7 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
|
||||
fContext->channel_layout = fInputFormat.u.raw_audio.channel_mask;
|
||||
}
|
||||
} else {
|
||||
TRACE(" UNSUPPORTED MEDIA TYPE!\n");
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@ -266,55 +384,46 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
|
||||
fContext->mb_decision = 2;
|
||||
}
|
||||
|
||||
// Unfortunately, we may fail later, when we try to open the codec
|
||||
// for real... but we need to delay this because we still allow
|
||||
// parameter/quality changes.
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AVCodecEncoder::_OpenCodecIfNeeded()
|
||||
{
|
||||
if (fCodecInitStatus == CODEC_INIT_DONE)
|
||||
return true;
|
||||
|
||||
if (fCodecInitStatus == CODEC_INIT_FAILED)
|
||||
return false;
|
||||
|
||||
// Open the codec
|
||||
int result = avcodec_open(fContext, fCodec);
|
||||
fCodecInitDone = (result >= 0);
|
||||
if (result >= 0)
|
||||
fCodecInitStatus = CODEC_INIT_DONE;
|
||||
else
|
||||
fCodecInitStatus = CODEC_INIT_FAILED;
|
||||
|
||||
TRACE(" avcodec_open(): %d\n", result);
|
||||
|
||||
return fCodecInitDone ? B_OK : B_ERROR;
|
||||
return fCodecInitStatus == CODEC_INIT_DONE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AVCodecEncoder::GetEncodeParameters(encode_parameters* parameters) const
|
||||
void
|
||||
AVCodecEncoder::_CloseCodecIfNeeded()
|
||||
{
|
||||
TRACE("AVCodecEncoder::GetEncodeParameters(%p)\n", parameters);
|
||||
|
||||
return B_NOT_SUPPORTED;
|
||||
if (fCodecInitStatus == CODEC_INIT_DONE) {
|
||||
avcodec_close(fContext);
|
||||
fCodecInitStatus = CODEC_INIT_NEEDED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AVCodecEncoder::SetEncodeParameters(encode_parameters* parameters) const
|
||||
{
|
||||
TRACE("AVCodecEncoder::SetEncodeParameters(%p)\n", parameters);
|
||||
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AVCodecEncoder::Encode(const void* buffer, int64 frameCount,
|
||||
media_encode_info* info)
|
||||
{
|
||||
TRACE("AVCodecEncoder::Encode(%p, %lld, %p)\n", buffer, frameCount, info);
|
||||
|
||||
if (!fCodecInitDone)
|
||||
return B_NO_INIT;
|
||||
|
||||
if (fInputFormat.type == B_MEDIA_RAW_AUDIO)
|
||||
return _EncodeAudio(buffer, frameCount, info);
|
||||
else if (fInputFormat.type == B_MEDIA_RAW_VIDEO)
|
||||
return _EncodeVideo(buffer, frameCount, info);
|
||||
else
|
||||
return B_NO_INIT;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static const int64 kNoPTSValue = 0x8000000000000000LL;
|
||||
// NOTE: For some reasons, I have trouble with the avcodec.h define:
|
||||
// #define AV_NOPTS_VALUE INT64_C(0x8000000000000000)
|
||||
|
@ -19,7 +19,8 @@ extern "C" {
|
||||
|
||||
class AVCodecEncoder : public Encoder {
|
||||
public:
|
||||
AVCodecEncoder(uint32 codecID);
|
||||
AVCodecEncoder(uint32 codecID,
|
||||
int bitRateScale);
|
||||
|
||||
virtual ~AVCodecEncoder();
|
||||
|
||||
@ -32,7 +33,7 @@ public:
|
||||
virtual status_t GetEncodeParameters(
|
||||
encode_parameters* parameters) const;
|
||||
virtual status_t SetEncodeParameters(
|
||||
encode_parameters* parameters) const;
|
||||
encode_parameters* parameters);
|
||||
|
||||
virtual status_t Encode(const void* buffer, int64 frameCount,
|
||||
media_encode_info* info);
|
||||
@ -42,6 +43,11 @@ public:
|
||||
// codec buffer size.
|
||||
|
||||
private:
|
||||
status_t _Setup();
|
||||
|
||||
bool _OpenCodecIfNeeded();
|
||||
void _CloseCodecIfNeeded();
|
||||
|
||||
status_t _EncodeAudio(const void* buffer,
|
||||
int64 frameCount,
|
||||
media_encode_info* info);
|
||||
@ -55,12 +61,20 @@ private:
|
||||
|
||||
private:
|
||||
media_format fInputFormat;
|
||||
encode_parameters fEncodeParameters;
|
||||
int fBitRateScale;
|
||||
|
||||
// FFmpeg related members
|
||||
// TODO: Refactor common base class from AVCodec[De|En]Coder!
|
||||
AVCodec* fCodec;
|
||||
AVCodecContext* fContext;
|
||||
bool fCodecInitDone;
|
||||
|
||||
enum {
|
||||
CODEC_INIT_NEEDED = 0,
|
||||
CODEC_INIT_DONE,
|
||||
CODEC_INIT_FAILED
|
||||
};
|
||||
uint32 fCodecInitStatus;
|
||||
|
||||
// For video (color space conversion):
|
||||
AVPicture fSrcFrame;
|
||||
|
@ -22,7 +22,8 @@ const EncoderDescription gEncoderTable[] = {
|
||||
},
|
||||
B_ANY_FORMAT_FAMILY, // TODO: Hm, actually not really /any/ family...
|
||||
B_MEDIA_RAW_VIDEO,
|
||||
B_MEDIA_ENCODED_VIDEO
|
||||
B_MEDIA_ENCODED_VIDEO,
|
||||
23
|
||||
},
|
||||
{
|
||||
{
|
||||
@ -34,7 +35,8 @@ const EncoderDescription gEncoderTable[] = {
|
||||
},
|
||||
B_MPEG_FORMAT_FAMILY,
|
||||
B_MEDIA_RAW_VIDEO,
|
||||
B_MEDIA_ENCODED_VIDEO
|
||||
B_MEDIA_ENCODED_VIDEO,
|
||||
10
|
||||
},
|
||||
{
|
||||
{
|
||||
@ -46,7 +48,8 @@ const EncoderDescription gEncoderTable[] = {
|
||||
},
|
||||
B_MPEG_FORMAT_FAMILY,
|
||||
B_MEDIA_RAW_VIDEO,
|
||||
B_MEDIA_ENCODED_VIDEO
|
||||
B_MEDIA_ENCODED_VIDEO,
|
||||
15
|
||||
},
|
||||
{
|
||||
{
|
||||
@ -58,7 +61,8 @@ const EncoderDescription gEncoderTable[] = {
|
||||
},
|
||||
B_ANY_FORMAT_FAMILY,
|
||||
B_MEDIA_RAW_AUDIO,
|
||||
B_MEDIA_ENCODED_AUDIO
|
||||
B_MEDIA_ENCODED_AUDIO,
|
||||
1
|
||||
},
|
||||
{
|
||||
{
|
||||
@ -70,7 +74,8 @@ const EncoderDescription gEncoderTable[] = {
|
||||
},
|
||||
B_ANY_FORMAT_FAMILY,
|
||||
B_MEDIA_RAW_AUDIO,
|
||||
B_MEDIA_ENCODED_AUDIO
|
||||
B_MEDIA_ENCODED_AUDIO,
|
||||
10
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,6 +14,7 @@ struct EncoderDescription {
|
||||
media_format_family format_family;
|
||||
media_type input_type;
|
||||
media_type output_type;
|
||||
int bit_rate_scale;
|
||||
};
|
||||
|
||||
|
||||
|
@ -134,7 +134,13 @@ FFmpegPlugin::GetSupportedFileFormats(const media_file_format** _fileFormats,
|
||||
Encoder*
|
||||
FFmpegPlugin::NewEncoder(const media_codec_info& codecInfo)
|
||||
{
|
||||
return new(std::nothrow)AVCodecEncoder(codecInfo.sub_id);
|
||||
for (size_t i = 0; i < gEncoderCount; i++) {
|
||||
if (codecInfo.sub_id == gEncoderTable[i].codec_info.sub_id) {
|
||||
return new(std::nothrow)AVCodecEncoder(codecInfo.sub_id,
|
||||
gEncoderTable[i].bit_rate_scale);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,6 +38,23 @@ const media_file_format gMuxerTable[] = {
|
||||
"mpg",
|
||||
{ 0 }
|
||||
},
|
||||
// TODO: This one rejects unknown codecs. We probably need to define
|
||||
// a media_format_family for it so that Encoders can announce their support
|
||||
// for it specifically.
|
||||
// {
|
||||
// media_file_format::B_WRITABLE
|
||||
// | media_file_format::B_KNOWS_ENCODED_VIDEO
|
||||
// | media_file_format::B_KNOWS_ENCODED_AUDIO,
|
||||
// { 0 },
|
||||
// B_AVI_FORMAT_FAMILY,
|
||||
// 100,
|
||||
// { 0 },
|
||||
// "application/ogg",
|
||||
// "Ogg (Xiph.Org Foundation)",
|
||||
// "ogg",
|
||||
// "ogg",
|
||||
// { 0 }
|
||||
// },
|
||||
};
|
||||
|
||||
const size_t gMuxerCount = sizeof(gMuxerTable) / sizeof(media_file_format);
|
||||
|
@ -686,7 +686,7 @@
|
||||
#define CONFIG_MXF_D10_MUXER 0
|
||||
#define CONFIG_NULL_MUXER 0
|
||||
#define CONFIG_NUT_MUXER 0
|
||||
#define CONFIG_OGG_MUXER 0
|
||||
#define CONFIG_OGG_MUXER 1
|
||||
#define CONFIG_PCM_ALAW_MUXER 0
|
||||
#define CONFIG_PCM_MULAW_MUXER 0
|
||||
#define CONFIG_PCM_F64BE_MUXER 0
|
||||
|
@ -26,6 +26,9 @@ Encoder::~Encoder()
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Convenience stubs
|
||||
|
||||
|
||||
status_t
|
||||
Encoder::AddTrackInfo(uint32 code, const void* data, size_t size, uint32 flags)
|
||||
{
|
||||
@ -33,6 +36,34 @@ Encoder::AddTrackInfo(uint32 code, const void* data, size_t size, uint32 flags)
|
||||
}
|
||||
|
||||
|
||||
BView*
|
||||
Encoder::ParameterView()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
BParameterWeb*
|
||||
Encoder::ParameterWeb()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Encoder::GetParameterValue(int32 id, void* value, size_t* size) const
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Encoder::SetParameterValue(int32 id, const void* value, size_t size)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Encoder::GetEncodeParameters(encode_parameters* parameters) const
|
||||
{
|
||||
@ -41,12 +72,15 @@ Encoder::GetEncodeParameters(encode_parameters* parameters) const
|
||||
|
||||
|
||||
status_t
|
||||
Encoder::SetEncodeParameters(encode_parameters* parameters) const
|
||||
Encoder::SetEncodeParameters(encode_parameters* parameters)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
Encoder::WriteChunk(const void* chunkBuffer, size_t chunkSize,
|
||||
media_encode_info* encodeInfo)
|
||||
@ -63,6 +97,9 @@ Encoder::SetChunkWriter(ChunkWriter* writer)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - FBC padding
|
||||
|
||||
|
||||
status_t
|
||||
Encoder::Perform(perform_code code, void* data)
|
||||
{
|
||||
@ -75,9 +112,24 @@ void Encoder::_ReservedEncoder2() {}
|
||||
void Encoder::_ReservedEncoder3() {}
|
||||
void Encoder::_ReservedEncoder4() {}
|
||||
void Encoder::_ReservedEncoder5() {}
|
||||
void Encoder::_ReservedEncoder6() {}
|
||||
void Encoder::_ReservedEncoder7() {}
|
||||
void Encoder::_ReservedEncoder8() {}
|
||||
void Encoder::_ReservedEncoder9() {}
|
||||
void Encoder::_ReservedEncoder10() {}
|
||||
void Encoder::_ReservedEncoder11() {}
|
||||
void Encoder::_ReservedEncoder12() {}
|
||||
void Encoder::_ReservedEncoder13() {}
|
||||
void Encoder::_ReservedEncoder14() {}
|
||||
void Encoder::_ReservedEncoder15() {}
|
||||
void Encoder::_ReservedEncoder16() {}
|
||||
void Encoder::_ReservedEncoder17() {}
|
||||
void Encoder::_ReservedEncoder18() {}
|
||||
void Encoder::_ReservedEncoder19() {}
|
||||
void Encoder::_ReservedEncoder20() {}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// #pragma mark - EncoderPlugin
|
||||
|
||||
|
||||
EncoderPlugin::EncoderPlugin()
|
||||
|
@ -76,6 +76,7 @@ BMediaTrack::~BMediaTrack()
|
||||
CALLED();
|
||||
_plugin_manager.DestroyDecoder(fRawDecoder);
|
||||
_plugin_manager.DestroyDecoder(fDecoder);
|
||||
_plugin_manager.DestroyDecoder(fEncoder);
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
@ -321,28 +322,31 @@ BMediaTrack::ReadFrames(void *out_buffer,
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::ReplaceFrames(const void *in_buffer,
|
||||
int64 *io_frameCount,
|
||||
const media_header *mh)
|
||||
BMediaTrack::ReplaceFrames(const void* inBuffer, int64* inOutFrameCount,
|
||||
const media_header* mediaHeader)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
|
||||
return B_OK;
|
||||
// TODO: Actually, a file is either open for reading or writing at the
|
||||
// moment. Since the chunk size of encoded media data will change,
|
||||
// implementing this call will only be possible for raw media tracks.
|
||||
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::SeekToTime(bigtime_t *inout_time, int32 flags)
|
||||
BMediaTrack::SeekToTime(bigtime_t* inOutTime, int32 flags)
|
||||
{
|
||||
CALLED();
|
||||
if (!fDecoder || !fExtractor)
|
||||
return B_NO_INIT;
|
||||
if (!inout_time)
|
||||
if (!inOutTime)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
uint32 seekTo = (flags & B_MEDIA_SEEK_DIRECTION_MASK)
|
||||
| B_MEDIA_SEEK_TO_TIME;
|
||||
bigtime_t seekTime = *inout_time;
|
||||
bigtime_t seekTime = *inOutTime;
|
||||
|
||||
int64 frame = 0;
|
||||
bigtime_t time = seekTime;
|
||||
@ -355,7 +359,7 @@ BMediaTrack::SeekToTime(bigtime_t *inout_time, int32 flags)
|
||||
// TODO: Codecs cannot actually "seek" in the stream, all they
|
||||
// can do is "reset" their decoder state, since they are made
|
||||
// aware of the fact that there will be a jump in the data. Maybe
|
||||
// rename the codec method?
|
||||
// rename the Decoder method?
|
||||
result = fDecoder->Seek(seekTo, 0, &frame, seekTime, &time);
|
||||
if (result != B_OK) {
|
||||
ERROR("BMediaTrack::SeekToTime: decoder seek failed\n");
|
||||
@ -370,11 +374,12 @@ BMediaTrack::SeekToTime(bigtime_t *inout_time, int32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
*inout_time = time;
|
||||
*inOutTime = time;
|
||||
fCurFrame = frame;
|
||||
fCurTime = time;
|
||||
|
||||
PRINT(1, "BMediaTrack::SeekToTime finished, requested %.6f, result %.6f\n", seekTime / 1000000.0, *inout_time / 1000000.0);
|
||||
PRINT(1, "BMediaTrack::SeekToTime finished, requested %.6f, result %.6f\n",
|
||||
seekTime / 1000000.0, *inOutTime / 1000000.0);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -589,102 +594,142 @@ BMediaTrack::Flush()
|
||||
BParameterWeb*
|
||||
BMediaTrack::Web()
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
BParameterWeb* web;
|
||||
if (GetParameterWeb(&web) == B_OK)
|
||||
return web;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// returns a copy of the parameter web
|
||||
status_t
|
||||
BMediaTrack::GetParameterWeb(BParameterWeb** outWeb)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
if (outWeb == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (fEncoder == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
// TODO: This method is new in Haiku. The header mentions it returns a
|
||||
// copy. But how could it even do that? How can one clone a web and make
|
||||
// it point to the same BControllable?
|
||||
*outWeb = fEncoder->ParameterWeb();
|
||||
if (*outWeb != NULL)
|
||||
return B_OK;
|
||||
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::GetParameterValue(int32 id, void* value, size_t* size)
|
||||
{
|
||||
if (value == NULL || size == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (fEncoder == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fEncoder->GetParameterValue(id, value, size);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::SetParameterValue(int32 id, const void* value, size_t size)
|
||||
{
|
||||
if (value == NULL || size == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (fEncoder == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fEncoder->SetParameterValue(id, value, size);
|
||||
}
|
||||
|
||||
|
||||
BView*
|
||||
BMediaTrack::GetParameterView()
|
||||
{
|
||||
if (fEncoder == NULL)
|
||||
return NULL;
|
||||
|
||||
return fEncoder->ParameterView();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::GetQuality(float* quality)
|
||||
{
|
||||
if (quality == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
encode_parameters parameters;
|
||||
status_t ret = GetEncodeParameters(¶meters);
|
||||
if (ret != B_OK)
|
||||
return ret;
|
||||
|
||||
*quality = parameters.quality;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::GetParameterValue(int32 id,
|
||||
void *valu,
|
||||
size_t *size)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::SetParameterValue(int32 id,
|
||||
const void *valu,
|
||||
size_t size)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
BView *
|
||||
BMediaTrack::GetParameterView()
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::GetQuality(float *quality)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::SetQuality(float quality)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
encode_parameters parameters;
|
||||
status_t ret = GetEncodeParameters(¶meters);
|
||||
if (ret != B_OK)
|
||||
return ret;
|
||||
|
||||
return B_ERROR;
|
||||
if (quality < 0.0f)
|
||||
quality = 0.0f;
|
||||
if (quality > 1.0f)
|
||||
quality = 1.0f;
|
||||
|
||||
parameters.quality = quality;
|
||||
|
||||
return SetEncodeParameters(¶meters);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::GetEncodeParameters(encode_parameters *parameters) const
|
||||
BMediaTrack::GetEncodeParameters(encode_parameters* parameters) const
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
if (parameters == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return B_ERROR;
|
||||
if (fEncoder == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fEncoder->GetEncodeParameters(parameters);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::SetEncodeParameters(encode_parameters *parameters)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
if (parameters == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return B_ERROR;
|
||||
if (fEncoder == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fEncoder->SetEncodeParameters(parameters);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaTrack::Perform(int32 selector,
|
||||
void *data)
|
||||
BMediaTrack::Perform(int32 selector, void* data)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
|
||||
return B_ERROR;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* private BMediaTrack
|
||||
*************************************************************/
|
||||
// #pragma mark - private
|
||||
|
||||
BMediaTrack::BMediaTrack(BPrivate::media::MediaExtractor *extractor,
|
||||
int32 stream)
|
||||
|
||||
BMediaTrack::BMediaTrack(BPrivate::media::MediaExtractor* extractor,
|
||||
int32 stream)
|
||||
{
|
||||
CALLED();
|
||||
fWorkaroundFlags = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user