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, int32 channel_count,
uint32 sample_format, uint32 sample_format,
float frame_rate, 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. */ /* Use MediaFlags to inquire about specific features of the Media Kit. */
/* Returns < 0 for "not present", positive size for output data size. */ /* Returns < 0 for "not present", positive size for output data size. */
+3 -2
View File
@@ -15,8 +15,9 @@ public:
virtual ~Decoder(); virtual ~Decoder();
// Setup get's called with the info data from Reader::GetStreamInfo // Setup get's called with the info data from Reader::GetStreamInfo
virtual status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat, virtual status_t Setup(media_format *ioEncodedFormat, const void *infoBuffer, int32 infoSize) = 0;
const void *infoBuffer, int32 infoSize) = 0;
virtual status_t NegotiateOutputFormat(media_format *ioDecodedFormat) = 0;
virtual status_t Seek(uint32 seekTo, virtual status_t Seek(uint32 seekTo,
int64 seekFrame, int64 *frame, int64 seekFrame, int64 *frame,
+1 -3
View File
@@ -28,11 +28,9 @@ public:
int32 StreamCount(); int32 StreamCount();
media_format * EncodedFormat(int32 stream); const media_format * EncodedFormat(int32 stream);
int64 CountFrames(int32 stream) const; int64 CountFrames(int32 stream) const;
bigtime_t Duration(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, status_t Seek(int32 stream, uint32 seekTo,
int64 *frame, bigtime_t *time); int64 *frame, bigtime_t *time);
@@ -2,6 +2,7 @@
#include <DataIO.h> #include <DataIO.h>
#include <Locker.h> #include <Locker.h>
#include <MediaFormats.h> #include <MediaFormats.h>
#include <MediaRoster.h>
#include "mp3DecoderPlugin.h" #include "mp3DecoderPlugin.h"
#define TRACE_THIS 1 #define TRACE_THIS 1
@@ -11,7 +12,6 @@
#define TRACE(a...) #define TRACE(a...)
#endif #endif
#define OUTPUT_BUFFER_SIZE (8 * 1024)
#define DECODE_BUFFER_SIZE (32 * 1024) #define DECODE_BUFFER_SIZE (32 * 1024)
mp3Decoder::mp3Decoder() mp3Decoder::mp3Decoder()
@@ -20,7 +20,12 @@ mp3Decoder::mp3Decoder()
fResidualBytes = 0; fResidualBytes = 0;
fResidualBuffer = 0; fResidualBuffer = 0;
fDecodeBuffer = new uint8 [DECODE_BUFFER_SIZE]; fDecodeBuffer = new uint8 [DECODE_BUFFER_SIZE];
fStartTime = 0;
fFrameSize = 0; fFrameSize = 0;
fFrameRate = 0;
fBitRate = 0;
fChannelCount = 0;
fOutputBufferSize = 0;
} }
@@ -32,19 +37,56 @@ mp3Decoder::~mp3Decoder()
status_t status_t
mp3Decoder::Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat, mp3Decoder::Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize) 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->type = B_MEDIA_RAW_AUDIO;
ioDecodedFormat->u.raw_audio.frame_rate = 44100; ioDecodedFormat->u.raw_audio.frame_rate = fFrameRate;
ioDecodedFormat->u.raw_audio.channel_count = 2; ioDecodedFormat->u.raw_audio.channel_count = fChannelCount;
ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT; 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_LITTLE_ENDIAN; ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; // XXX should support other endain, too
ioDecodedFormat->u.raw_audio.buffer_size = OUTPUT_BUFFER_SIZE; if (ioDecodedFormat->u.raw_audio.buffer_size < 512 || ioDecodedFormat->u.raw_audio.buffer_size > 65536)
ioDecodedFormat->u.raw_audio.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; ioDecodedFormat->u.raw_audio.buffer_size = BMediaRoster::Roster()->AudioBufferSizeFor(
fFrameSize = 4; fChannelCount,
fFps = 44100; 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; return B_OK;
} }
@@ -66,7 +108,7 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
media_header *mediaHeader, media_decode_info *info /* = 0 */) media_header *mediaHeader, media_decode_info *info /* = 0 */)
{ {
uint8 * out_buffer = static_cast<uint8 *>(buffer); uint8 * out_buffer = static_cast<uint8 *>(buffer);
int32 out_bytes_needed = OUTPUT_BUFFER_SIZE; int32 out_bytes_needed = fOutputBufferSize;
mediaHeader->start_time = fStartTime; mediaHeader->start_time = fStartTime;
//TRACE("mp3Decoder: Decoding start time %.6f\n", fStartTime / 1000000.0); //TRACE("mp3Decoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
@@ -80,7 +122,7 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
out_buffer += bytes; out_buffer += bytes;
out_bytes_needed -= 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); //TRACE("mp3Decoder: fStartTime inc'd to %.6f\n", fStartTime / 1000000.0);
continue; continue;
@@ -90,10 +132,10 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
break; 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 // 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 status_t
@@ -8,9 +8,11 @@ public:
mp3Decoder(); mp3Decoder();
~mp3Decoder(); ~mp3Decoder();
status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat, status_t Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize); const void *infoBuffer, int32 infoSize);
status_t NegotiateOutputFormat(media_format *ioDecodedFormat);
status_t Seek(uint32 seekTo, status_t Seek(uint32 seekTo,
int64 seekFrame, int64 *frame, int64 seekFrame, int64 *frame,
bigtime_t seekTime, bigtime_t *time); bigtime_t seekTime, bigtime_t *time);
@@ -26,9 +28,12 @@ private:
int32 fResidualBytes; int32 fResidualBytes;
uint8 * fResidualBuffer; uint8 * fResidualBuffer;
uint8 * fDecodeBuffer; uint8 * fDecodeBuffer;
int32 fFrameSize;
int32 fFps;
bigtime_t fStartTime; bigtime_t fStartTime;
int fFrameSize;
int fFrameRate;
int fBitRate;
int fChannelCount;
int fOutputBufferSize;
}; };
@@ -7,24 +7,36 @@
#if TRACE_THIS #if TRACE_THIS
#define TRACE printf #define TRACE printf
#else #else
#define TRACE ((void)0) #define TRACE TRACE(a...)
#endif #endif
status_t status_t
RawDecoder::Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat, RawDecoder::Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize) const void *infoBuffer, int32 infoSize)
{ {
if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO) if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO)
return B_ERROR; return B_ERROR;
fInputFormat = *ioEncodedFormat;
if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO) if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO)
fFrameSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row; fFrameSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row;
else else
fFrameSize = (ioEncodedFormat->u.raw_audio.format & 0xf) * ioEncodedFormat->u.raw_audio.channel_count; 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; return B_OK;
} }
@@ -3,9 +3,11 @@
class RawDecoder : public Decoder class RawDecoder : public Decoder
{ {
public: public:
status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat, status_t Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize); const void *infoBuffer, int32 infoSize);
status_t NegotiateOutputFormat(media_format *ioDecodedFormat);
status_t Seek(uint32 seekTo, status_t Seek(uint32 seekTo,
int64 seekFrame, int64 *frame, int64 seekFrame, int64 *frame,
bigtime_t seekTime, bigtime_t *time); bigtime_t seekTime, bigtime_t *time);
@@ -13,7 +15,8 @@ public:
status_t Decode(void *buffer, int64 *frameCount, status_t Decode(void *buffer, int64 *frameCount,
media_header *mediaHeader, media_decode_info *info); media_header *mediaHeader, media_decode_info *info);
private: private:
int32 fFrameSize; int32 fFrameSize;
media_format fInputFormat;
}; };
+7 -14
View File
@@ -90,7 +90,7 @@ MediaExtractor::StreamCount()
return fStreamCount; return fStreamCount;
} }
media_format * const media_format *
MediaExtractor::EncodedFormat(int32 stream) MediaExtractor::EncodedFormat(int32 stream)
{ {
return &fStreamInfo[stream].encodedFormat; return &fStreamInfo[stream].encodedFormat;
@@ -126,18 +126,6 @@ MediaExtractor::Duration(int32 stream) const
return duration; return duration;
} }
void *
MediaExtractor::InfoBuffer(int32 stream) const
{
return fStreamInfo[stream].infoBuffer;
}
int32
MediaExtractor::InfoBufferSize(int32 stream) const
{
return fStreamInfo[stream].infoBufferSize;
}
status_t status_t
MediaExtractor::Seek(int32 stream, uint32 seekTo, MediaExtractor::Seek(int32 stream, uint32 seekTo,
int64 *frame, bigtime_t *time) int64 *frame, bigtime_t *time)
@@ -180,6 +168,11 @@ MediaExtractor::CreateDecoder(int32 stream, Decoder **decoder, media_codec_info
(*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) if (!fExtractor || !fDecoder)
return B_NO_INIT; return B_NO_INIT;
return fDecoder->Setup(fExtractor->EncodedFormat(fStream), inout_format, return fDecoder->NegotiateOutputFormat(inout_format);
fExtractor->InfoBuffer(fStream), fExtractor->InfoBufferSize(fStream));
} }