* 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:
Stephan Aßmus 2009-08-05 10:21:36 +00:00
parent 048d05a613
commit 6780c24d36
10 changed files with 412 additions and 137 deletions

View File

@ -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();
};

View File

@ -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)

View File

@ -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;

View File

@ -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
}
};

View File

@ -14,6 +14,7 @@ struct EncoderDescription {
media_format_family format_family;
media_type input_type;
media_type output_type;
int bit_rate_scale;
};

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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()

View File

@ -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(&parameters);
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(&parameters);
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(&parameters);
}
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;