codec output format negotiation has been moved into NegotiateOutputFormat,

Setup is now only called once


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5596 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-12-06 23:21:23 +00:00
parent abf9e66abe
commit 2530523976
9 changed files with 99 additions and 46 deletions
+1 -1
View File
@@ -343,7 +343,7 @@ static BMediaRoster * CurrentRoster(); // won't create it if there isn't one
int32 channel_count,
uint32 sample_format,
float frame_rate,
bus_type bus_kind);
bus_type bus_kind = B_UNKNOWN_BUS);
/* Use MediaFlags to inquire about specific features of the Media Kit. */
/* Returns < 0 for "not present", positive size for output data size. */
+3 -2
View File
@@ -15,8 +15,9 @@ public:
virtual ~Decoder();
// Setup get's called with the info data from Reader::GetStreamInfo
virtual status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
const void *infoBuffer, int32 infoSize) = 0;
virtual status_t Setup(media_format *ioEncodedFormat, const void *infoBuffer, int32 infoSize) = 0;
virtual status_t NegotiateOutputFormat(media_format *ioDecodedFormat) = 0;
virtual status_t Seek(uint32 seekTo,
int64 seekFrame, int64 *frame,
+1 -3
View File
@@ -28,11 +28,9 @@ public:
int32 StreamCount();
media_format * EncodedFormat(int32 stream);
const media_format * EncodedFormat(int32 stream);
int64 CountFrames(int32 stream) const;
bigtime_t Duration(int32 stream) const;
void * InfoBuffer(int32 stream) const;
int32 InfoBufferSize(int32 stream) const;
status_t Seek(int32 stream, uint32 seekTo,
int64 *frame, bigtime_t *time);
@@ -2,6 +2,7 @@
#include <DataIO.h>
#include <Locker.h>
#include <MediaFormats.h>
#include <MediaRoster.h>
#include "mp3DecoderPlugin.h"
#define TRACE_THIS 1
@@ -11,7 +12,6 @@
#define TRACE(a...)
#endif
#define OUTPUT_BUFFER_SIZE (8 * 1024)
#define DECODE_BUFFER_SIZE (32 * 1024)
mp3Decoder::mp3Decoder()
@@ -20,7 +20,12 @@ mp3Decoder::mp3Decoder()
fResidualBytes = 0;
fResidualBuffer = 0;
fDecodeBuffer = new uint8 [DECODE_BUFFER_SIZE];
fStartTime = 0;
fFrameSize = 0;
fFrameRate = 0;
fBitRate = 0;
fChannelCount = 0;
fOutputBufferSize = 0;
}
@@ -32,19 +37,56 @@ mp3Decoder::~mp3Decoder()
status_t
mp3Decoder::Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
mp3Decoder::Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize)
{
memset(ioDecodedFormat, 0, sizeof(*ioDecodedFormat));
// decode first chunk to initialize mpeg library
if (B_OK != DecodeNextChunk()) {
printf("mp3Decoder::Setup failed, can't decode first chunk\n");
return B_ERROR;
}
// initialize fBitRate, fFrameRate and fChannelCount from mpg decode library values of first header
extern int tabsel_123[2][3][16];
extern long freqs[9];
fBitRate = tabsel_123[fMpgLibPrivate.fr.lsf][fMpgLibPrivate.fr.lay-1][fMpgLibPrivate.fr.bitrate_index] * 1000;
fFrameRate = freqs[fMpgLibPrivate.fr.sampling_frequency];
fChannelCount = fMpgLibPrivate.fr.stereo;
printf("mp3Decoder::Setup: channels %d, bitrate %d, framerate %d\n", fChannelCount, fBitRate, fFrameRate);
// put some more useful info into the media_format describing our input format
ioEncodedFormat->u.encoded_audio.bit_rate = fBitRate;
return B_OK;
}
status_t
mp3Decoder::NegotiateOutputFormat(media_format *ioDecodedFormat)
{
// fFrameRate and fChannelCount are already valid here
// BeBook says: The codec will find and return in ioFormat its best matching format
// => This means, we never return an error, and always change the format values
// that we don't support to something more applicable
ioDecodedFormat->type = B_MEDIA_RAW_AUDIO;
ioDecodedFormat->u.raw_audio.frame_rate = 44100;
ioDecodedFormat->u.raw_audio.channel_count = 2;
ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_LITTLE_ENDIAN;
ioDecodedFormat->u.raw_audio.buffer_size = OUTPUT_BUFFER_SIZE;
ioDecodedFormat->u.raw_audio.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
fFrameSize = 4;
fFps = 44100;
ioDecodedFormat->u.raw_audio.frame_rate = fFrameRate;
ioDecodedFormat->u.raw_audio.channel_count = fChannelCount;
ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT; // XXX should support other formats, too
ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; // XXX should support other endain, too
if (ioDecodedFormat->u.raw_audio.buffer_size < 512 || ioDecodedFormat->u.raw_audio.buffer_size > 65536)
ioDecodedFormat->u.raw_audio.buffer_size = BMediaRoster::Roster()->AudioBufferSizeFor(
fChannelCount,
ioDecodedFormat->u.raw_audio.format,
fFrameRate);
if (ioDecodedFormat->u.raw_audio.channel_mask == 0)
ioDecodedFormat->u.raw_audio.channel_mask = (fChannelCount == 1) ? B_CHANNEL_LEFT : B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
// setup rest of the needed variables
fFrameSize = (ioDecodedFormat->u.raw_audio.format & 0xf) * fChannelCount;
fOutputBufferSize = ioDecodedFormat->u.raw_audio.buffer_size;
return B_OK;
}
@@ -66,7 +108,7 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
media_header *mediaHeader, media_decode_info *info /* = 0 */)
{
uint8 * out_buffer = static_cast<uint8 *>(buffer);
int32 out_bytes_needed = OUTPUT_BUFFER_SIZE;
int32 out_bytes_needed = fOutputBufferSize;
mediaHeader->start_time = fStartTime;
//TRACE("mp3Decoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
@@ -80,7 +122,7 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
out_buffer += bytes;
out_bytes_needed -= bytes;
fStartTime += (1000000LL * (bytes / fFrameSize)) / fFps;
fStartTime += (1000000LL * (bytes / fFrameSize)) / fFrameRate;
//TRACE("mp3Decoder: fStartTime inc'd to %.6f\n", fStartTime / 1000000.0);
continue;
@@ -90,10 +132,10 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
break;
}
*frameCount = (OUTPUT_BUFFER_SIZE - out_bytes_needed) / fFrameSize;
*frameCount = (fOutputBufferSize - out_bytes_needed) / fFrameSize;
// XXX this doesn't guarantee that we always return B_LAST_BUFFER_ERROR bofore returning B_ERROR
return (out_bytes_needed == 0) ? B_OK : (out_bytes_needed == OUTPUT_BUFFER_SIZE) ? B_ERROR : B_LAST_BUFFER_ERROR;
return (out_bytes_needed == 0) ? B_OK : (out_bytes_needed == fOutputBufferSize) ? B_ERROR : B_LAST_BUFFER_ERROR;
}
status_t
@@ -8,9 +8,11 @@ public:
mp3Decoder();
~mp3Decoder();
status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
status_t Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize);
status_t NegotiateOutputFormat(media_format *ioDecodedFormat);
status_t Seek(uint32 seekTo,
int64 seekFrame, int64 *frame,
bigtime_t seekTime, bigtime_t *time);
@@ -26,9 +28,12 @@ private:
int32 fResidualBytes;
uint8 * fResidualBuffer;
uint8 * fDecodeBuffer;
int32 fFrameSize;
int32 fFps;
bigtime_t fStartTime;
int fFrameSize;
int fFrameRate;
int fBitRate;
int fChannelCount;
int fOutputBufferSize;
};
@@ -7,24 +7,36 @@
#if TRACE_THIS
#define TRACE printf
#else
#define TRACE ((void)0)
#define TRACE TRACE(a...)
#endif
status_t
RawDecoder::Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
RawDecoder::Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize)
{
if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO)
return B_ERROR;
fInputFormat = *ioEncodedFormat;
if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO)
fFrameSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row;
else
fFrameSize = (ioEncodedFormat->u.raw_audio.format & 0xf) * ioEncodedFormat->u.raw_audio.channel_count;
*ioDecodedFormat = *ioEncodedFormat;
return B_OK;
}
status_t
RawDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat)
{
// BeBook says: The codec will find and return in ioFormat its best matching format
// => This means, we never return an error, and always change the format values
// that we don't support to something more applicable
*ioDecodedFormat = fInputFormat;
return B_OK;
}
@@ -3,8 +3,10 @@
class RawDecoder : public Decoder
{
public:
status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
status_t Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize);
status_t NegotiateOutputFormat(media_format *ioDecodedFormat);
status_t Seek(uint32 seekTo,
int64 seekFrame, int64 *frame,
@@ -13,7 +15,8 @@ public:
status_t Decode(void *buffer, int64 *frameCount,
media_header *mediaHeader, media_decode_info *info);
private:
int32 fFrameSize;
int32 fFrameSize;
media_format fInputFormat;
};
+8 -15
View File
@@ -90,7 +90,7 @@ MediaExtractor::StreamCount()
return fStreamCount;
}
media_format *
const media_format *
MediaExtractor::EncodedFormat(int32 stream)
{
return &fStreamInfo[stream].encodedFormat;
@@ -126,18 +126,6 @@ MediaExtractor::Duration(int32 stream) const
return duration;
}
void *
MediaExtractor::InfoBuffer(int32 stream) const
{
return fStreamInfo[stream].infoBuffer;
}
int32
MediaExtractor::InfoBufferSize(int32 stream) const
{
return fStreamInfo[stream].infoBufferSize;
}
status_t
MediaExtractor::Seek(int32 stream, uint32 seekTo,
int64 *frame, bigtime_t *time)
@@ -178,8 +166,13 @@ MediaExtractor::CreateDecoder(int32 stream, Decoder **decoder, media_codec_info
return B_ERROR;
}
(*decoder)->Setup(this, stream);
(*decoder)->Setup(this, stream);
return B_OK;
status_t res;
res = (*decoder)->Setup(&fStreamInfo[stream].encodedFormat, fStreamInfo[stream].infoBuffer , fStreamInfo[stream].infoBufferSize);
if (res != B_OK) {
printf("MediaExtractor::CreateDecoder Setup failed for stream %ld\n", stream);
}
return res;
}
+1 -2
View File
@@ -69,8 +69,7 @@ BMediaTrack::DecodedFormat(media_format *inout_format)
if (!fExtractor || !fDecoder)
return B_NO_INIT;
return fDecoder->Setup(fExtractor->EncodedFormat(fStream), inout_format,
fExtractor->InfoBuffer(fStream), fExtractor->InfoBufferSize(fStream));
return fDecoder->NegotiateOutputFormat(inout_format);
}