Author: stippi Date: 2010-01-07 01:55:55 +0100 (Thu, 07 Jan 2010) New Revision: 34923 Changeset: http://dev.haiku-os.org/changeset/34923/haiku Modified: haiku/trunk/headers/os/media/MediaTrack.h haiku/trunk/src/kits/media/MediaTrack.cpp Log: * Indentation and naming cleanup in the header * Small coding style cleanups in the .cpp * When reading raw chunks, keep fCurrentFrame updated anyway * When decoding frames and chunks, don't change the meaning of fCurrentTime, it's supposed to be the start time of the next chunk/frame, same as CurrentFrame(), not the time of the frame/chunk we just decoded/read. BMediaTrack::CurrentFrame() is actually documented like this in the BeBook, but CurrentTime() is not. However, when seeking to a specific time, it is understood that this is the time of the next frame/chunk. If we decode/read it and set fCurrentTime to the start_time as specified in the media_header, it would actually not change for the first frame/chunk after seeking. To be able to know the duration of chunks, fWriterFormat had to be changed to just fFormat and is now used for decoding as well. * Simplified handling of media_header in some methods, saves one assignment. These changes are not so well tested, yet. Modified: haiku/trunk/headers/os/media/MediaTrack.h =================================================================== --- haiku/trunk/headers/os/media/MediaTrack.h 2010-01-07 00:13:03 UTC (rev 34922) +++ haiku/trunk/headers/os/media/MediaTrack.h 2010-01-07 00:55:55 UTC (rev 34923) @@ -1,13 +1,11 @@ /* - * Copyright 2002-2009, Haiku, Inc. All rights reserved. - * Distributed under the terms of the MIT license. + * Copyright 2002-2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. */ #ifndef _MEDIA_TRACK_H #define _MEDIA_TRACK_H -#include <SupportDefs.h> -#include <MediaDefs.h> #include <MediaFormats.h> @@ -65,13 +63,14 @@ status_t InitCheck() const; // Get information about the codec being used. - status_t GetCodecInfo(media_codec_info* _codecInfo) const; + status_t GetCodecInfo( + media_codec_info* _codecInfo) const; // EncodedFormat returns information about the track's // "native" encoded format. - status_t EncodedFormat(media_format* _format) const; + status_t EncodedFormat(media_format* _format) const; // DecodedFormat is used to negotiate the format that the codec will // use when decoding the track's data. You pass in the format that @@ -82,20 +81,20 @@ // The data returned through ReadFrames() will be in the format that's // returned by this function. - status_t DecodedFormat(media_format* _inOutFormat, - uint32 flags = 0); + status_t DecodedFormat(media_format* _inOutFormat, + uint32 flags = 0); // CountFrames and Duration return the total number of frame and the // total duration (expressed in microseconds) of a track. - int64 CountFrames() const; - bigtime_t Duration() const; + int64 CountFrames() const; + bigtime_t Duration() const; // CurrentFrame and CurrentTime return the current position (expressed in // microseconds) within the track, expressed in frame index and time. - int64 CurrentFrame() const; - bigtime_t CurrentTime() const; + int64 CurrentFrame() const; + bigtime_t CurrentTime() const; // ReadFrames() fills a buffer with the next frames/samples. For a video // track, it decodes the next frame of video in the passed buffer. For @@ -106,16 +105,16 @@ // frame/samples returned, and the start time for the frame, expressed // in microseconds, is in the media_header structure. - status_t ReadFrames(void* _buffer, int64* _frameCount, - media_header* mediaHeader = NULL); + status_t ReadFrames(void* buffer, int64* _frameCount, + media_header* mediaHeader = NULL); - status_t ReadFrames(void* _buffer, int64* _frameCount, - media_header* mediaHeader, - media_decode_info* info); + status_t ReadFrames(void* buffer, int64* _frameCount, + media_header* mediaHeader, + media_decode_info* info); - status_t ReplaceFrames(const void* buffer, - int64* _inOutFrameCount, - const media_header* mediaHeader); + status_t ReplaceFrames(const void* buffer, + int64* _inOutFrameCount, + const media_header* mediaHeader); // SeekToTime and SeekToFrame are used for seeking to a particular @@ -129,76 +128,79 @@ // frame or _after_ this frame, pass B_MEDIA_SEEK_CLOSEST_FORWARD or // B_MEDIA_SEEK_CLOSEST_BACKWARD as the flags field. - status_t SeekToTime(bigtime_t* _inOutTime, int32 flags = 0); - status_t SeekToFrame(int64* _inOutFrame, int32 flags = 0); + status_t SeekToTime(bigtime_t* _inOutTime, + int32 flags = 0); + status_t SeekToFrame(int64* _inOutFrame, + int32 flags = 0); - status_t FindKeyFrameForTime(bigtime_t* _inOutTime, - int32 flags = 0) const; - status_t FindKeyFrameForFrame(int64* _inOutFrame, - int32 flags = 0) const; + status_t FindKeyFrameForTime(bigtime_t* _inOutTime, + int32 flags = 0) const; + status_t FindKeyFrameForFrame(int64* _inOutFrame, + int32 flags = 0) const; - // ReadChunk returns, in out_buffer, the next out_size bytes of + // ReadChunk returns, in _buffer, the next _size bytes of // data from the track. The data is not decoded -- it will be // in its native encoded format (as specified by EncodedFormat()). // You can not mix calling ReadChunk() and ReadFrames() -- either // you access the track raw (i.e. with ReadChunk) or you access // it with ReadFrames. - status_t ReadChunk(char** _buffer, int32* _size, - media_header* mediaHeader = NULL); + status_t ReadChunk(char** _buffer, int32* _size, + media_header* mediaHeader = NULL); // // Write-only Functions // - status_t AddCopyright(const char* copyright); - status_t AddTrackInfo(uint32 code, const void* data, - size_t size, uint32 flags = 0); + status_t AddCopyright(const char* copyright); + status_t AddTrackInfo(uint32 code, const void* data, + size_t size, uint32 flags = 0); - // Write num_frames of data to the track. This data is passed + // Write frameCount of data to the track. This data is passed // through the encoder that was specified when the MediaTrack // was constructed. // Pass B_MEDIA_KEY_FRAME for flags if it is. - status_t WriteFrames(const void* data, int32 frameCount, - int32 flags = 0); - status_t WriteFrames(const void* data, int64 frameCount, - media_encode_info* info); + status_t WriteFrames(const void* data, int32 frameCount, + int32 flags = 0); + status_t WriteFrames(const void* data, int64 frameCount, + media_encode_info* info); // Write a raw chunk of (presumably already encoded data) to // the file. // Pass B_MEDIA_KEY_FRAME for flags if it is. - status_t WriteChunk(const void* data, size_t size, - uint32 flags = 0); - status_t WriteChunk(const void* data, size_t size, - media_encode_info* info); + status_t WriteChunk(const void* data, size_t size, + uint32 flags = 0); + status_t WriteChunk(const void* data, size_t size, + media_encode_info* info); // Flush all buffered encoded datas to disk. You should call it after // writing the last frame to be sure all datas are flushed at the right // offset into the file. - status_t Flush(); + status_t Flush(); // These are for controlling the underlying encoder and track parameters // returns a copy of the parameter web - status_t GetParameterWeb(BParameterWeb** _web); - status_t GetParameterValue(int32 id, void* value, - size_t* size); - status_t SetParameterValue(int32 id, const void* value, - size_t size); - BView* GetParameterView(); + status_t GetParameterWeb(BParameterWeb** _web); + status_t GetParameterValue(int32 id, void* value, + size_t* size); + status_t SetParameterValue(int32 id, const void* value, + size_t size); + BView* GetParameterView(); // This is a simplified control API, only one parameter low=0.0, high=1.0 // Return B_ERROR if it's not supported by the current encoder. - status_t GetQuality(float* _quality); - status_t SetQuality(float quality); + status_t GetQuality(float* _quality); + status_t SetQuality(float quality); - status_t GetEncodeParameters( - encode_parameters* parameters) const; - status_t SetEncodeParameters(encode_parameters* parameters); + status_t GetEncodeParameters( + encode_parameters* parameters) const; + status_t SetEncodeParameters( + encode_parameters* parameters); - virtual status_t Perform(int32 code, void* data); + virtual status_t Perform(int32 code, void* data); private: friend class BMediaFile; @@ -207,104 +209,107 @@ BParameterWeb* Web(); // Does nothing, returns B_ERROR, for Zeta compatiblity only - status_t ControlCodec(int32 selector, void* _inOutData, - size_t size); + status_t ControlCodec(int32 selector, void* _inOutData, + size_t size); // For read-only access to a BMediaTrack - BMediaTrack( - BPrivate::media::MediaExtractor* extractor, - int32 streamIndex); + BMediaTrack( + BPrivate::media::MediaExtractor* extractor, + int32 streamIndex); // For write-only access to a BMediaTrack - BMediaTrack(BPrivate::media::MediaWriter* writer, - int32 streamIndex, - const media_format* format, - const media_codec_info* codecInfo); + BMediaTrack( + BPrivate::media::MediaWriter* writer, + int32 streamIndex, + const media_format* format, + const media_codec_info* codecInfo); - void SetupWorkaround(); - bool SetupFormatTranslation(const media_format& from, - media_format* _to); + void SetupWorkaround(); + bool SetupFormatTranslation( + const media_format& from, + media_format* _to); private: - status_t fErr; + status_t fInitStatus; BPrivate::media::Decoder* fDecoder; BPrivate::media::Decoder* fRawDecoder; BPrivate::media::MediaExtractor* fExtractor; - int32 fStream; - int64 fCurFrame; - bigtime_t fCurTime; + int32 fStream; + int64 fCurrentFrame; + bigtime_t fCurrentTime; - media_codec_info fMCI; + media_codec_info fCodecInfo; BPrivate::media::Encoder* fEncoder; - int32 fEncoderID; + int32 fEncoderID; BPrivate::media::MediaWriter* fWriter; - media_format fWriterFormat; + media_format fFormat; - uint32 fWorkaroundFlags; + uint32 fWorkaroundFlags; protected: - int32 EncoderID() { return fEncoderID; }; + int32 EncoderID() { return fEncoderID; }; private: + BMediaTrack(); + BMediaTrack(const BMediaTrack&); + BMediaTrack& operator=(const BMediaTrack&); - BMediaTrack(); - BMediaTrack(const BMediaTrack&); - BMediaTrack& operator=(const BMediaTrack&); + double _FrameRate() const; // FBC data and virtuals - uint32 _reserved_BMediaTrack_[31]; + uint32 _reserved_BMediaTrack_[31]; - virtual status_t _Reserved_BMediaTrack_0(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_1(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_2(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_3(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_4(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_5(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_6(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_7(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_8(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_9(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_10(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_11(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_12(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_13(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_14(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_15(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_16(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_17(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_18(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_19(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_20(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_21(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_22(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_23(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_24(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_25(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_26(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_27(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_28(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_29(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_30(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_31(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_32(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_33(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_34(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_35(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_36(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_37(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_38(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_39(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_40(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_41(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_42(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_43(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_44(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_45(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_46(int32 arg, ...); - virtual status_t _Reserved_BMediaTrack_47(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_0(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_1(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_2(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_3(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_4(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_5(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_6(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_7(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_8(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_9(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_10(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_11(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_12(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_13(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_14(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_15(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_16(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_17(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_18(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_19(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_20(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_21(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_22(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_23(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_24(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_25(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_26(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_27(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_28(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_29(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_30(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_31(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_32(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_33(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_34(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_35(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_36(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_37(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_38(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_39(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_40(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_41(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_42(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_43(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_44(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_45(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_46(int32 arg, ...); + virtual status_t _Reserved_BMediaTrack_47(int32 arg, ...); }; -#endif +#endif // _MEDIA_TRACK_H Modified: haiku/trunk/src/kits/media/MediaTrack.cpp =================================================================== --- haiku/trunk/src/kits/media/MediaTrack.cpp 2010-01-07 00:13:03 UTC (rev 34922) +++ haiku/trunk/src/kits/media/MediaTrack.cpp 2010-01-07 00:55:55 UTC (rev 34923) @@ -1,5 +1,5 @@ /* - * Copyright 2009, Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2009-2010, Stephan Aßmus <superstippi@xxxxxx> * Copyright 2002-2007, Marcus Overhagen <marcus@xxxxxxxxxxxx> * All rights reserved. Distributed under the terms of the MIT license. */ @@ -23,19 +23,20 @@ //#define TRACE_MEDIA_TRACK #ifdef TRACE_MEDIA_TRACK - #ifndef TRACE - #define TRACE printf - #endif +# ifndef TRACE +# define TRACE printf +# endif #else - #ifndef TRACE - #define TRACE(a...) - #endif +# ifndef TRACE +# define TRACE(a...) +# endif #endif #define ERROR(a...) fprintf(stderr, a) -#define CONVERT_TO_INT32 0 // XXX test! this triggers a few bugs! +#define CONVERT_TO_INT32 0 + // TODO: Test! This triggers a few bugs! // flags used for workarounds enum { @@ -49,21 +50,24 @@ IGNORE_ENCODED_VIDEO = 0x2000, }; -#define B_MEDIA_DISABLE_FORMAT_TRANSLATION 0x4000 // XXX move this (after name change?) to MediaDefs.h +#define B_MEDIA_DISABLE_FORMAT_TRANSLATION 0x4000 + // TODO: move this (after name change?) to MediaDefs.h -class RawDecoderChunkProvider : public ChunkProvider -{ + +class RawDecoderChunkProvider : public ChunkProvider { public: - RawDecoderChunkProvider(Decoder *decoder, int buffer_size, int frame_size); + RawDecoderChunkProvider(Decoder* decoder, int buffer_size, + int frame_size); virtual ~RawDecoderChunkProvider(); - status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, media_header *mediaHeader); + status_t GetNextChunk(const void** chunkBuffer, size_t* chunkSize, + media_header* mediaHeader); private: - Decoder *fDecoder; - void *fBuffer; - int fBufferSize; - int fFrameSize; + Decoder* fDecoder; + void* fBuffer; + int fBufferSize; + int fFrameSize; }; @@ -87,19 +91,19 @@ BMediaTrack::InitCheck() const { CALLED(); - return fErr; + return fInitStatus; } status_t -BMediaTrack::GetCodecInfo(media_codec_info *mci) const +BMediaTrack::GetCodecInfo(media_codec_info* mci) const { CALLED(); if (!fDecoder) return B_NO_INIT; - *mci = fMCI; - strlcpy(mci->pretty_name, fMCI.pretty_name, sizeof(mci->pretty_name)); + *mci = fCodecInfo; + strlcpy(mci->pretty_name, fCodecInfo.pretty_name, sizeof(mci->pretty_name)); return B_OK; } @@ -145,7 +149,7 @@ return B_NO_INIT; _plugin_manager.DestroyDecoder(fRawDecoder); - fRawDecoder = 0; + fRawDecoder = NULL; #ifdef TRACE_MEDIA_TRACK char s[200]; @@ -177,7 +181,7 @@ printf("BMediaTrack::DecodedFormat: req2: %s\n", s); #endif - media_format requested_format = *inout_format; + fFormat = *inout_format; status_t res; @@ -210,16 +214,18 @@ } if (0 == (flags & B_MEDIA_DISABLE_FORMAT_TRANSLATION)) { - if (requested_format.type == B_MEDIA_RAW_AUDIO + if (fFormat.type == B_MEDIA_RAW_AUDIO && inout_format->type == B_MEDIA_RAW_AUDIO - && requested_format.u.raw_audio.format != 0 - && requested_format.u.raw_audio.format != inout_format->u.raw_audio.format) { - if (SetupFormatTranslation(*inout_format, &requested_format)) { - *inout_format = requested_format; + && fFormat.u.raw_audio.format != 0 + && fFormat.u.raw_audio.format != inout_format->u.raw_audio.format) { + if (SetupFormatTranslation(*inout_format, &fFormat)) { + *inout_format = fFormat; } } } + fFormat = *inout_format; + // string_for_format(*inout_format, s, sizeof(s)); // printf("BMediaTrack::DecodedFormat: res: %s\n", s); @@ -250,14 +256,14 @@ int64 BMediaTrack::CurrentFrame() const { - return fCurFrame; + return fCurrentFrame; } bigtime_t BMediaTrack::CurrentTime() const { - return fCurTime; + return fCurrentTime; } // BMediaTrack::ReadFrames(char *, long long *, media_header *) @@ -276,46 +282,49 @@ #endif // __GNUC__ < 3 status_t -BMediaTrack::ReadFrames(void *out_buffer, - int64 *out_frameCount, - media_header *mh) +BMediaTrack::ReadFrames(void* buffer, int64* _frameCount, + media_header* mediaHeader) { - return ReadFrames(out_buffer, out_frameCount, mh, 0); + return ReadFrames(buffer, _frameCount, mediaHeader, NULL); } status_t -BMediaTrack::ReadFrames(void *out_buffer, - int64 *out_frameCount, - media_header *mh /* = 0 */, - media_decode_info *info /* = 0 */) +BMediaTrack::ReadFrames(void* buffer, int64* _frameCount, + media_header* _header, media_decode_info* info) { // CALLED(); if (!fDecoder) return B_NO_INIT; - if (!out_buffer || !out_frameCount) + if (!buffer || !_frameCount) return B_BAD_VALUE; - status_t result; media_header header; + if (_header == NULL) + _header = &header; - memset(&header, 0, sizeof(header)); // always clear it first, as the decoder doesn't set all fields + // Always clear the header first, as the decoder may not set all fields. + memset(_header, 0, sizeof(media_header)); + status_t result; if (fRawDecoder) - result = fRawDecoder->Decode(out_buffer, out_frameCount, &header, info); + result = fRawDecoder->Decode(buffer, _frameCount, _header, info); else - result = fDecoder->Decode(out_buffer, out_frameCount, &header, info); + result = fDecoder->Decode(buffer, _frameCount, _header, info); if (result == B_OK) { - fCurFrame += *out_frameCount; - fCurTime = header.start_time; + fCurrentFrame += *_frameCount; +printf("ReadFrames() - next frame: %lld\n", fCurrentFrame); + fCurrentTime = _header->start_time + + *_frameCount * 1000000LL / _FrameRate(); } else { - ERROR("BMediaTrack::ReadFrames: decoder returned error 0x%08lx (%s)\n", result, strerror(result)); - *out_frameCount = 0; + ERROR("BMediaTrack::ReadFrames: decoder returned error 0x%08lx (%s)\n", + result, strerror(result)); + *_frameCount = 0; } - if (mh) - *mh = header; -// PRINT(1, "BMediaTrack::ReadFrames: stream %ld, start-time %5Ld.%06Ld, %Ld frames\n", fStream, header.start_time / 1000000, header.start_time % 1000000, *out_frameCount); +// PRINT(1, "BMediaTrack::ReadFrames: stream %ld, start-time %5Ld.%06Ld, " +// "%Ld frames\n", fStream, _header->start_time / 1000000, +// _header->start_time % 1000000, *out_frameCount); return result; } @@ -375,8 +384,8 @@ } *inOutTime = time; - fCurFrame = frame; - fCurTime = time; + fCurrentFrame = frame; + fCurrentTime = time; PRINT(1, "BMediaTrack::SeekToTime finished, requested %.6f, result %.6f\n", seekTime / 1000000.0, *inOutTime / 1000000.0); @@ -425,8 +434,8 @@ } *inout_frame = frame; - fCurFrame = frame; - fCurTime = time; + fCurrentFrame = frame; + fCurrentTime = time; PRINT(1, "BMediaTrack::SeekToTime SeekToFrame, requested %Ld, result %Ld\n", seekFrame, *inout_frame); @@ -488,30 +497,38 @@ status_t -BMediaTrack::ReadChunk(char **out_buffer, - int32 *out_size, - media_header *mh /* = 0 */) +BMediaTrack::ReadChunk(char** _buffer, int32* _size, media_header* _header) { CALLED(); - if (!fExtractor) + if (fExtractor == NULL) return B_NO_INIT; - if (!out_buffer || !out_size) + if (_buffer == NULL || _size == NULL) return B_BAD_VALUE; - status_t result; media_header header; - const void *buffer; + if (_header == NULL) + _header = &header; + + // Always clear the header first, as the extractor may not set all fields. + memset(_header, 0, sizeof(media_header)); + + const void* buffer; size_t size; + status_t result = fExtractor->GetNextChunk(fStream, &buffer, &size, + _header); - memset(&header, 0, sizeof(header)); // always clear it first, as the reader doesn't set all fields - - result = fExtractor->GetNextChunk(fStream, &buffer, &size, &header); if (result == B_OK) { - *out_buffer = const_cast<char *>(static_cast<const char *>(buffer)); // yes this *is* ugly - *out_size = size; - fCurTime = header.start_time; - if (mh) - *mh = header; + *_buffer = const_cast<char*>(static_cast<const char*>(buffer)); + // TODO: Change the pointer type when we break the API. + *_size = size; + // Several chunks may belong to the same frame. If the start time is + // different from the previous chunk's time, the next chunk will belong + // to the next frame. + if (fCurrentTime != _header->start_time) { + fCurrentFrame++; +printf("ReadChunk() - next frame: %lld\n", fCurrentFrame); + fCurrentTime = _header->start_time + 1000000LL / _FrameRate(); + } } return result; @@ -737,20 +754,20 @@ fRawDecoder = NULL; fExtractor = extractor; fStream = stream; - fErr = B_OK; + fInitStatus = B_OK; SetupWorkaround(); - status_t ret = fExtractor->CreateDecoder(fStream, &fDecoder, &fMCI); + status_t ret = fExtractor->CreateDecoder(fStream, &fDecoder, &fCodecInfo); if (ret != B_OK) { TRACE("BMediaTrack::BMediaTrack: Error: creating decoder failed: " "%s\n", strerror(ret)); - // We do not set fErr here, because ReadChunk should still work. + // We do not set fInitStatus here, because ReadChunk should still work. fDecoder = NULL; } - fCurFrame = 0; - fCurTime = 0; + fCurrentFrame = 0; + fCurrentTime = 0; // not used: fEncoder = NULL; @@ -770,9 +787,9 @@ fEncoderID = -1; // TODO: Not yet sure what this was needed for... fWriter = writer; - fWriterFormat = *format; + fFormat = *format; fStream = streamIndex; - fErr = B_OK; + fInitStatus = B_OK; SetupWorkaround(); @@ -781,17 +798,17 @@ if (ret != B_OK) { TRACE("BMediaTrack::BMediaTrack: Error: creating decoder failed: " "%s\n", strerror(ret)); - // We do not set fErr here, because WriteChunk should still work. + // We do not set fInitStatus here, because WriteChunk should still work. fEncoder = NULL; } else { - fMCI = *codecInfo; - fErr = fEncoder->SetUp(&fWriterFormat); + fCodecInfo = *codecInfo; + fInitStatus = fEncoder->SetUp(&fFormat); } } // not used: - fCurFrame = 0; - fCurTime = 0; + fCurrentFrame = 0; + fCurrentTime = 0; fDecoder = NULL; fRawDecoder = NULL; fExtractor = NULL; @@ -825,7 +842,8 @@ printf("BMediaTrack::SetupWorkaround: MediaPlayer workaround active\n"); } -#if CONVERT_TO_INT32 // XXX test +#if CONVERT_TO_INT32 + // TODO: Test if (!(fWorkaroundFlags & FORCE_RAW_AUDIO_INT16_FORMAT)) fWorkaroundFlags |= FORCE_RAW_AUDIO_INT32_FORMAT; #endif @@ -897,6 +915,24 @@ return false; } + +double +BMediaTrack::_FrameRate() const +{ + switch (fFormat.type) { + case B_MEDIA_RAW_VIDEO: + return fFormat.u.raw_video.field_rate; + case B_MEDIA_ENCODED_VIDEO: + return fFormat.u.encoded_video.output.field_rate; + case B_MEDIA_RAW_AUDIO: + return fFormat.u.raw_audio.frame_rate; + case B_MEDIA_ENCODED_AUDIO: + return fFormat.u.encoded_audio.output.frame_rate; + default: + return 1.0; + } +} + /* // unimplemented BMediaTrack::BMediaTrack()