diff --git a/src/add-ons/media/plugins/Jamfile b/src/add-ons/media/plugins/Jamfile index 05333e53a0..89e56dfd1f 100644 --- a/src/add-ons/media/plugins/Jamfile +++ b/src/add-ons/media/plugins/Jamfile @@ -22,8 +22,6 @@ SubInclude HAIKU_TOP src add-ons media plugins speex ; SubInclude HAIKU_TOP src add-ons media plugins mov_reader ; SubInclude HAIKU_TOP src add-ons media plugins mp4_reader ; -SubInclude HAIKU_TOP src add-ons media plugins asf_reader ; - # The following add-ons are GPL licensed, and can only be used with # software whose license is GPL compatible. To include these GPL # licensed add-ons, you need to run configure with the --include-gpl-addons diff --git a/src/add-ons/media/plugins/avcodec/Jamfile b/src/add-ons/media/plugins/avcodec/Jamfile index 09f3507b90..c201001f3d 100644 --- a/src/add-ons/media/plugins/avcodec/Jamfile +++ b/src/add-ons/media/plugins/avcodec/Jamfile @@ -8,14 +8,12 @@ SubDirHdrs [ FDirName $(SUBDIR) libavcodec ] ; SubDirHdrs [ FDirName $(SUBDIR) libavutil ] ; SubDirHdrs [ FDirName $(SUBDIR) libswscale ] ; -SubDirCcFlags -fomit-frame-pointer -DPIC -fno-common ; - Addon avcodec : avcodec.cpp codectbl.cpp gfx_conv_c.cpp gfx_conv_c_lookup.cpp - gfx_conv_mmx.cpp +# gfx_conv_mmx.cpp gfx_util.cpp : libavcodec.a diff --git a/src/add-ons/media/plugins/avcodec/avcodec.cpp b/src/add-ons/media/plugins/avcodec/avcodec.cpp index f4843bdd49..a5dcf412a1 100644 --- a/src/add-ons/media/plugins/avcodec/avcodec.cpp +++ b/src/add-ons/media/plugins/avcodec/avcodec.cpp @@ -466,18 +466,12 @@ avCodec::Decode(void *out_buffer, int64 *out_frameCount, if (fChunkBufferSize == 0) { media_header chunk_mh; status_t err; - printf("Asking for more data after %Ld frames\n",fFrame); err = GetNextChunk(&fChunkBuffer, &fChunkBufferSize, &chunk_mh); - if (err == B_LAST_BUFFER_ERROR) { - printf("Last Chunk with chunk size %ld\n",fChunkBufferSize); - return err; - } if (err != B_OK || fChunkBufferSize < 0) { - printf("GetNextChunk error %ld\n",fChunkBufferSize); + TRACE("GetNextChunk error %ld\n",fChunkBufferSize); fChunkBufferSize = 0; break; } - printf("Got a Chunk with start time of %Ld\n",chunk_mh.start_time); fChunkBufferOffset = 0; fStartTime = chunk_mh.start_time; if (*out_frameCount == 0) diff --git a/src/add-ons/media/plugins/avcodec/codectbl.cpp b/src/add-ons/media/plugins/avcodec/codectbl.cpp index 9e35fd22e4..294c201b47 100644 --- a/src/add-ons/media/plugins/avcodec/codectbl.cpp +++ b/src/add-ons/media/plugins/avcodec/codectbl.cpp @@ -69,7 +69,6 @@ const struct codec_table gCodecTable[] = { {CODEC_ID_WMAV1, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x160, "MS WMA v1"}, {CODEC_ID_WMAV2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x161, "MS WMA v2"}, - {CODEC_ID_VOXWARE, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x75, "Voxware"}, {CODEC_ID_CINEPAK, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('cvid'), "Cinepak Video"}, {CODEC_ID_CINEPAK, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'cvid', "Cinepak Video"}, diff --git a/src/add-ons/media/plugins/avcodec/gfx_conv_mmx.cpp b/src/add-ons/media/plugins/avcodec/gfx_conv_mmx.cpp deleted file mode 100644 index 293ca0f5a2..0000000000 --- a/src/add-ons/media/plugins/avcodec/gfx_conv_mmx.cpp +++ /dev/null @@ -1,38 +0,0 @@ -extern "C" { -#include "libavcodec/imgconvert.h" -} - -void gfx_conv_null_mmx(AVFrame *in, AVFrame *out, int width, int height) { - memcpy(out->data[0], in->data[0], height * in->linesize[0]); -} - -void gfx_conv_yuv410p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height) -{ - img_convert((AVPicture *)out,PIX_FMT_YUV422P,(const AVPicture *)in,PIX_FMT_YUV410P,width,height); -} - -void gfx_conv_yuv411p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height) -{ - img_convert((AVPicture *)out,PIX_FMT_YUV422P,(const AVPicture *)in,PIX_FMT_YUV411P,width,height); -} - -void gfx_conv_yuv420p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height) -{ - img_convert((AVPicture *)out,PIX_FMT_YUV422P,(const AVPicture *)in,PIX_FMT_YUV420P,width,height); -} - -void gfx_conv_yuv410p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height) -{ - img_convert((AVPicture *)out,PIX_FMT_RGB32,(const AVPicture *)in,PIX_FMT_YUV410P,width,height); -} - -void gfx_conv_yuv411p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height) -{ - img_convert((AVPicture *)out,PIX_FMT_RGB32,(const AVPicture *)in,PIX_FMT_YUV411P,width,height); -} - -void gfx_conv_yuv420p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height) -{ - img_convert((AVPicture *)out,PIX_FMT_RGB32,(const AVPicture *)in,PIX_FMT_YUV420P,width,height); -} - diff --git a/src/add-ons/media/plugins/avcodec/gfx_conv_mmx.h b/src/add-ons/media/plugins/avcodec/gfx_conv_mmx.h index 63ce5cff2c..79456e4a61 100644 --- a/src/add-ons/media/plugins/avcodec/gfx_conv_mmx.h +++ b/src/add-ons/media/plugins/avcodec/gfx_conv_mmx.h @@ -5,6 +5,8 @@ #include #include "libavcodec/avcodec.h" +bool IsMmxCpu(); + void gfx_conv_null_mmx(AVFrame *in, AVFrame *out, int width, int height); void gfx_conv_yuv410p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height); diff --git a/src/add-ons/media/plugins/avcodec/gfx_util.cpp b/src/add-ons/media/plugins/avcodec/gfx_util.cpp index f20fefe763..6af7bd0848 100644 --- a/src/add-ons/media/plugins/avcodec/gfx_util.cpp +++ b/src/add-ons/media/plugins/avcodec/gfx_util.cpp @@ -16,14 +16,14 @@ #endif //#define INCLUDE_MMX defined(__INTEL__) -#define INCLUDE_MMX 1 +#define INCLUDE_MMX 0 // this function will try to find the best colorspaces for both the ff-codec and // the Media Kit sides. gfx_convert_func resolve_colorspace(color_space colorSpace, PixelFormat pixelFormat) { #if INCLUDE_MMX - bool mmx = true; + bool mmx = IsMmxCpu(); #endif switch (colorSpace) diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/Jamfile b/src/add-ons/media/plugins/avcodec/libavcodec/Jamfile index 996f8c1533..36cec0fc6a 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/Jamfile +++ b/src/add-ons/media/plugins/avcodec/libavcodec/Jamfile @@ -14,7 +14,7 @@ TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS) if $(HAIKU_GCC_VERSION[1]) >= 3 { SubDirCcFlags -fomit-frame-pointer -fno-pic ; } else { - SubDirCcFlags -fomit-frame-pointer -DPIC -fno-common ; + SubDirCcFlags -fomit-frame-pointer -DPIC ; } local defines ; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/config.h b/src/add-ons/media/plugins/avcodec/libavcodec/config.h index a4fbf94f52..87cda3940e 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/config.h +++ b/src/add-ons/media/plugins/avcodec/libavcodec/config.h @@ -54,9 +54,7 @@ #define HAVE_DLFCN_H 0 #define HAVE_DLOPEN 0 #define HAVE_DOS_PATHS 0 -// Jamfile must have -fomit_frame_pointer -#define HAVE_EBP_AVAILABLE 1 -// We use position independant code so no EBX +#define HAVE_EBP_AVAILABLE 0 #define HAVE_EBX_AVAILABLE 0 #define HAVE_FAST_64BIT 0 #define HAVE_FAST_CMOV 0 @@ -77,10 +75,10 @@ #define HAVE_MACHINE_IOCTL_BT848_H 0 #define HAVE_MACHINE_IOCTL_METEOR_H 0 #define HAVE_MALLOC_H 1 -#define HAVE_MEMALIGN 0 +#define HAVE_MEMALIGN 1 #define HAVE_MKSTEMP 1 #define HAVE_PLD 0 -#define HAVE_POSIX_MEMALIGN 1 +#define HAVE_POSIX_MEMALIGN 0 #define HAVE_PPC64 0 #define HAVE_ROUND 1 #define HAVE_ROUNDF 1 diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/h264.c b/src/add-ons/media/plugins/avcodec/libavcodec/h264.c index 8788a6796c..91f20c9867 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/h264.c +++ b/src/add-ons/media/plugins/avcodec/libavcodec/h264.c @@ -2412,8 +2412,6 @@ b= t; } } } -#include -#undef printf static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ MpegEncContext * const s = &h->s; @@ -2422,8 +2420,6 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ const int mb_xy= h->mb_xy; const int mb_type= s->current_picture.mb_type[mb_xy]; uint8_t *dest_y, *dest_cb, *dest_cr; - uintptr_t v; - size_t align; int linesize, uvlinesize /*dct_offset*/; int i; int *block_offset = &h->block_offset[0]; @@ -2437,14 +2433,6 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ dest_cb = s->current_picture.data[1] + (mb_x + mb_y * s->uvlinesize) * 8; dest_cr = s->current_picture.data[2] + (mb_x + mb_y * s->uvlinesize) * 8; - v = (uintptr_t)dest_y; - - align = ffs((int)v); - - printf("aligned(16): %s: address: %p alignment: %d (2^%u)\n", - align > 4 ? "PASS" : "FAIL", v, 1<<(align-1), align-1); - - s->dsp.prefetch(dest_y + (s->mb_x&3)*4*s->linesize + 64, s->linesize, 4); s->dsp.prefetch(dest_cb + (s->mb_x&7)*s->uvlinesize + 64, dest_cr - dest_cb, 2); diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/x86/Jamfile b/src/add-ons/media/plugins/avcodec/libavcodec/x86/Jamfile index 4365af8aa1..7249eb0276 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/x86/Jamfile +++ b/src/add-ons/media/plugins/avcodec/libavcodec/x86/Jamfile @@ -19,7 +19,7 @@ local defines ; defines = HAVE_AV_CONFIG_H=1 ; defines += ARCH_X86=1 ARCH_X86_32=1 ARCH_PPC=0 ARCH_SPARC=0 ; defines += HAVE_AMD3DNOW=0 HAVE_AMD3DNOWEXT=0 ; -defines += HAVE_MMX=1 HAVE_MMX2=1 HAVE_SSE=1 HAVE_SSE3=1 ; +defines += HAVE_MMX=1 HAVE_MMX2=1 HAVE_SSE=0 HAVE_SSE3=1 ; defines += HAVE_ALTIVEC=0 ; defines += HAVE_VIS=0 ; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/x86/dsputil_mmx.c b/src/add-ons/media/plugins/avcodec/libavcodec/x86/dsputil_mmx.c index bef0d34eca..2e6563c1d3 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/x86/dsputil_mmx.c +++ b/src/add-ons/media/plugins/avcodec/libavcodec/x86/dsputil_mmx.c @@ -2391,56 +2391,6 @@ void ff_x264_deblock_h_luma_intra_sse2(uint8_t *pix, int stride, int alpha, int #define ff_float_to_int16_interleave6_3dnow(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6) #define ff_float_to_int16_interleave6_3dn2(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6) #endif - -#include -#undef printf - -void haiku_x264_deblock_v_luma_sse2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) { - - uintptr_t v = (uintptr_t)pix; - size_t align1; - size_t align2; - - align1 = ffs((int)v); - printf("V pix aligned(16): %s: address: %p alignment: %d (2^%u)\n", - align1 > 4 ? "PASS" : "FAIL", v, 1<<(align1-1), align1-1); - - v = (uintptr_t)tc0; - - align2 = ffs((int)v); - printf("V tc0 aligned(16): %s: address: %p alignment: %d (2^%u)\n", - align2 > 4 ? "PASS" : "FAIL", v, 1<<(align2-1), align2-1); - - if (align1 > 4 && align2 > 4) { - ff_x264_deblock_v_luma_sse2(pix, stride, alpha, beta, tc0); - } else { - h264_v_loop_filter_luma_mmx2(pix, stride, alpha, beta, tc0); - } -} - -void haiku_x264_deblock_h_luma_sse2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) { - - uintptr_t v = (uintptr_t)pix; - size_t align1; - size_t align2; - - align1 = ffs((int)v); - printf("H pix aligned(16): %s: address: %p alignment: %d (2^%u)\n", - align1 > 4 ? "PASS" : "FAIL", v, 1<<(align1-1), align1-1); - - v = (uintptr_t)tc0; - - align2 = ffs((int)v); - printf("H tc0 aligned(16): %s: address: %p alignment: %d (2^%u)\n", - align2 > 4 ? "PASS" : "FAIL", v, 1<<(align2-1), align2-1); - - if (align1 > 4 && align2 > 4) { - ff_x264_deblock_h_luma_sse2(pix, stride, alpha, beta, tc0); - } else { - h264_h_loop_filter_luma_mmx2(pix, stride, alpha, beta, tc0); - } -} - #define ff_float_to_int16_interleave6_sse2 ff_float_to_int16_interleave6_sse #define FLOAT_TO_INT16_INTERLEAVE(cpu, body) \ @@ -2995,8 +2945,8 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) #endif if( mm_flags&FF_MM_SSE2 ){ #if ARCH_X86_64 || !defined(__ICC) || __ICC > 1100 - c->h264_v_loop_filter_luma = haiku_x264_deblock_v_luma_sse2; - c->h264_h_loop_filter_luma = haiku_x264_deblock_h_luma_sse2; + c->h264_v_loop_filter_luma = ff_x264_deblock_v_luma_sse2; + c->h264_h_loop_filter_luma = ff_x264_deblock_h_luma_sse2; c->h264_v_loop_filter_luma_intra = ff_x264_deblock_v_luma_intra_sse2; c->h264_h_loop_filter_luma_intra = ff_x264_deblock_h_luma_intra_sse2; #endif diff --git a/src/add-ons/media/plugins/avcodec/libavutil/Jamfile b/src/add-ons/media/plugins/avcodec/libavutil/Jamfile index a55b8f38c7..926d6955dd 100644 --- a/src/add-ons/media/plugins/avcodec/libavutil/Jamfile +++ b/src/add-ons/media/plugins/avcodec/libavutil/Jamfile @@ -7,7 +7,7 @@ TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS) SubDirHdrs [ FDirName $(SUBDIR) .. ] ; SubDirHdrs [ FDirName $(SUBDIR) ../libavcodec ] ; -SubDirCcFlags -fomit-frame-pointer -DPIC -fno-common ; +SubDirCcFlags -fomit-frame-pointer -DPIC ; #SubDirCcFlags -DHAVE_AV_CONFIG_H=1 ; StaticLibrary libavutil.a : diff --git a/src/add-ons/media/plugins/avcodec/libswscale/Jamfile b/src/add-ons/media/plugins/avcodec/libswscale/Jamfile index 3c57a4411e..83139ea67d 100644 --- a/src/add-ons/media/plugins/avcodec/libswscale/Jamfile +++ b/src/add-ons/media/plugins/avcodec/libswscale/Jamfile @@ -8,7 +8,7 @@ SubDirHdrs [ FDirName $(SUBDIR) ../libavcodec ] ; TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS) : -Wall -Wmissing-prototypes -Wsign-compare -Wpointer-arith ] ; -SubDirCcFlags -fomit-frame-pointer -DPIC -fno-common ; +SubDirCcFlags -fomit-frame-pointer -DPIC ; local arch_sources ; arch_sources = ; diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.cpp index a5df061dad..2d859aa4d3 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.cpp @@ -41,17 +41,6 @@ AtomBase::~AtomBase() parentAtom = NULL; } -char *AtomBase::getAtomTypeAsFourcc() -{ - fourcc[0] = (char)((atomType >> 24) & 0xff); - fourcc[1] = (char)((atomType >> 16) & 0xff); - fourcc[2] = (char)((atomType >> 8) & 0xff); - fourcc[3] = (char)((atomType >> 0) & 0xff); - fourcc[4] = '\0'; - - return fourcc; -} - char *AtomBase::getAtomName() { char *_result; @@ -118,7 +107,7 @@ void AtomBase::DisplayAtoms() void AtomBase::DisplayAtoms(uint32 pindent) { Indent(pindent); - printf("(%s)\n",getAtomName()); + printf("%s\n",getAtomName()); } void AtomBase::Indent(uint32 pindent) @@ -135,6 +124,10 @@ bool AtomBase::IsKnown() void AtomBase::ReadArrayHeader(array_header *pHeader) { + Read(&pHeader->Version); + Read(&pHeader->Flags1); + Read(&pHeader->Flags2); + Read(&pHeader->Flags3); Read(&pHeader->NoEntries); } @@ -171,17 +164,6 @@ void AtomBase::Read(uint32 *value) *value = B_BENDIAN_TO_HOST_INT32(*value); } -void AtomBase::Read(int32 *value) -{ - uint32 bytes_read; - - bytes_read = getStream()->Read(value,sizeof(int32)); - - // Assert((bytes_read == sizeof(int32),"Read Error"); - - *value = B_BENDIAN_TO_HOST_INT32(*value); -} - void AtomBase::Read(uint16 *value) { uint32 bytes_read; @@ -220,52 +202,6 @@ void AtomBase::Read(uint8 *value, uint32 maxread) // Assert((bytes_read == maxread,"Read Error"); } -uint64 AtomBase::GetBits(uint64 buffer, uint8 startBit, uint8 totalBits) -{ - // startBit should range from 0-63, totalBits should range from 1-64 - if ((startBit < 64) && (totalBits > 0) && (totalBits <= 64) && (startBit + totalBits <= 64)) { - // Ok pull from the buffer the bits wanted. - buffer = buffer << startBit; - buffer = buffer >> (64 - (totalBits + startBit) + startBit); - - printf("buffer = %Ld\n",buffer); - - return buffer; - } - - return 0L; -} - -uint32 AtomBase::GetBits(uint32 buffer, uint8 startBit, uint8 totalBits) -{ - // startBit should range from 0-31, totalBits should range from 1-32 - if ((startBit < 32) && (totalBits > 0) && (totalBits <= 32) && (startBit + totalBits <= 32)) { - // Ok pull from the buffer the bits wanted. - buffer = buffer << startBit; - buffer = buffer >> (32 - (startBit + totalBits) + startBit); - - return buffer; - } - - return 0; -} - -FullAtom::FullAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) -{ -} - -FullAtom::~FullAtom() -{ -} - -void FullAtom::OnProcessMetaData() -{ - Read(&Version); - Read(&Flags1); - Read(&Flags2); - Read(&Flags3); -} - AtomContainer::AtomContainer(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { TotalChildren = 0; @@ -278,7 +214,7 @@ AtomContainer::~AtomContainer() void AtomContainer::DisplayAtoms(uint32 pindent) { Indent(pindent); - printf("%ld:(%s)\n",TotalChildren,getAtomName()); + printf("%ld:%s\n",TotalChildren,getAtomName()); pindent++; // for each child for (uint32 i = 0;i < TotalChildren;i++) { diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.h b/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.h index 4aea36632d..7ed170a8db 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.h @@ -101,18 +101,17 @@ public: uint64 getAtomSize() {return atomSize;}; uint32 getAtomType() {return atomType;}; - char *getAtomTypeAsFourcc(); - off_t getAtomOffset() { return atomOffset; }; - off_t getStreamOffset() { return streamOffset; }; - - uint64 getDataSize() { return atomSize - 8;}; + off_t getAtomOffset() {return atomOffset;}; + off_t getStreamOffset() {return streamOffset;}; + uint64 getDataSize() {return atomSize - 8;}; + uint64 getBytesRemaining(); - bool IsType(uint32 patomType) { return patomType == atomType; }; + bool IsType(uint32 patomType) {return patomType == atomType;}; - void setAtomOffset(off_t patomOffset) { atomOffset = patomOffset; }; - void setStreamOffset(off_t pstreamOffset) { streamOffset = pstreamOffset; }; + void setAtomOffset(off_t patomOffset) {atomOffset = patomOffset;}; + void setStreamOffset(off_t pstreamOffset) {streamOffset = pstreamOffset;}; char *getAtomName(); @@ -135,42 +134,20 @@ public: void setParent(AtomBase *pParent) {parentAtom = pParent;}; AtomBase *getParent() { return parentAtom;}; - + void Read(uint64 *value); void Read(uint32 *value); - void Read(int32 *value); void Read(uint16 *value); void Read(uint8 *value); void Read(char *value, uint32 maxread); void Read(uint8 *value, uint32 maxread); - - uint64 GetBits(uint64 buffer, uint8 startBit, uint8 totalBits); - uint32 GetBits(uint32 buffer, uint8 startBit, uint8 totalBits); -}; - -class FullAtom : public AtomBase { -public: - FullAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); - virtual ~FullAtom(); - - virtual void OnProcessMetaData(); - uint8 getVersion() {return Version;}; - uint8 getFlags1() {return Flags1;}; - uint8 getFlags2() {return Flags2;}; - uint8 getFlags3() {return Flags3;}; - -private: - uint8 Version; - uint8 Flags1; - uint8 Flags2; - uint8 Flags3; }; class AtomContainer : public AtomBase { /* - This is an Atom that contains other atoms. It has children that may be Container Atoms or Standard Atoms + This is an Atom that contains other atoms. It has children that may be Containter Atoms or Standard Atoms */ diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp index a7422c3c21..72d6bca455 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp @@ -39,13 +39,14 @@ extern AtomBase *getAtom(BPositionIO *pStream); MOVFileReader::MOVFileReader(BPositionIO *pStream) { theStream = pStream; - + // Find Size of Stream, need to rethink this for non seekable streams theStream->Seek(0,SEEK_END); StreamSize = theStream->Position(); + theStream->Seek(0,SEEK_SET); TotalChildren = 0; - + theMVHDAtom = NULL; } @@ -55,52 +56,41 @@ MOVFileReader::~MOVFileReader() theMVHDAtom = NULL; } -bool -MOVFileReader::IsEndOfData(off_t position) +bool MOVFileReader::IsEndOfData(off_t pPosition) { - AtomBase* aAtomBase; +AtomBase *aAtomBase; - // check all mdat atoms to make sure position is within one of them - - for (uint32 index=0;indexgetAtomSize() > 8)) { - MDATAtom *aMDATAtom = dynamic_cast(aAtomBase); - if (position >= aMDATAtom->getAtomOffset() && position <= aMDATAtom->getEOF()) { - return false; - } - } + aAtomBase = GetChildAtom(uint32('mdat'),0); + if (aAtomBase) { + MDATAtom *aMdatAtom = dynamic_cast(aAtomBase); + return pPosition >= aMdatAtom->getEOF(); } - + return true; } -bool -MOVFileReader::IsEndOfFile(off_t position) +bool MOVFileReader::IsEndOfFile(off_t pPosition) { - return (position >= StreamSize); + return (pPosition >= StreamSize); } -bool -MOVFileReader::IsEndOfFile() +bool MOVFileReader::IsEndOfFile() { - return theStream->Position() >= StreamSize; + return (theStream->Position() >= StreamSize); } -bool -MOVFileReader::AddChild(AtomBase *childAtom) +bool MOVFileReader::AddChild(AtomBase *pChildAtom) { - if (childAtom) { - atomChildren[TotalChildren++] = childAtom; + if (pChildAtom) { + atomChildren[TotalChildren++] = pChildAtom; return true; } return false; } -AtomBase * -MOVFileReader::GetChildAtom(uint32 patomType, uint32 offset) +AtomBase *MOVFileReader::GetChildAtom(uint32 patomType, uint32 offset) { - for (uint32 i = 0; i < TotalChildren; i++) { + for (uint32 i=0;iIsType(patomType)) { // found match, skip if offset non zero. if (offset == 0) { @@ -123,8 +113,7 @@ MOVFileReader::GetChildAtom(uint32 patomType, uint32 offset) return NULL; } -uint32 -MOVFileReader::CountChildAtoms(uint32 patomType) +uint32 MOVFileReader::CountChildAtoms(uint32 patomType) { uint32 count = 0; @@ -134,10 +123,9 @@ MOVFileReader::CountChildAtoms(uint32 patomType) return count; } -MVHDAtom* -MOVFileReader::getMVHDAtom() +MVHDAtom *MOVFileReader::getMVHDAtom() { - AtomBase *aAtomBase; +AtomBase *aAtomBase; if (theMVHDAtom == NULL) { aAtomBase = GetChildAtom(uint32('mvhd')); @@ -148,11 +136,223 @@ MOVFileReader::getMVHDAtom() return theMVHDAtom; } - -void -MOVFileReader::BuildSuperIndex() +uint32 MOVFileReader::getMovieTimeScale() { - AtomBase *aAtomBase; + return getMVHDAtom()->getTimeScale(); +} + +bigtime_t MOVFileReader::getMovieDuration() +{ + return ((bigtime_t(getMVHDAtom()->getDuration()) * 1000000L) / getMovieTimeScale()); +} + +uint32 MOVFileReader::getStreamCount() +{ + // count the number of tracks in the file + return (CountChildAtoms(uint32('trak'))); +} + +bigtime_t MOVFileReader::getVideoDuration(uint32 stream_index) +{ +AtomBase *aAtomBase; + + aAtomBase = GetChildAtom(uint32('trak'),stream_index); + + if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsVideo())) { + return (dynamic_cast(aAtomBase)->Duration(1)); + } + + return 0; +} + +bigtime_t MOVFileReader::getAudioDuration(uint32 stream_index) +{ +AtomBase *aAtomBase; + + aAtomBase = GetChildAtom(uint32('trak'),stream_index); + + if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsAudio())) { + return (dynamic_cast(aAtomBase)->Duration(1)); + } + + return 0; +} + +bigtime_t MOVFileReader::getMaxDuration() +{ +AtomBase *aAtomBase; +int32 video_index,audio_index; + video_index = -1; + audio_index = -1; + + // find the active video and audio tracks + for (uint32 i=0;i(aAtomBase)->IsActive())) { + if (dynamic_cast(aAtomBase)->IsAudio()) { + audio_index = int32(i); + } + if (dynamic_cast(aAtomBase)->IsVideo()) { + video_index = int32(i); + } + } + } + + if ((video_index >= 0) && (audio_index >= 0)) { + return MAX(getVideoDuration(video_index),getAudioDuration(audio_index)); + } + if ((video_index < 0) && (audio_index >= 0)) { + return getAudioDuration(audio_index); + } + if ((video_index >= 0) && (audio_index < 0)) { + return getVideoDuration(video_index); + } + + return 0; +} + +uint32 MOVFileReader::getVideoFrameCount(uint32 stream_index) +{ +AtomBase *aAtomBase; + + aAtomBase = GetChildAtom(uint32('trak'),stream_index); + + if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsVideo())) { + + return dynamic_cast(aAtomBase)->FrameCount(); + } + + return 1; +} + +uint32 MOVFileReader::getAudioFrameCount(uint32 stream_index) +{ + if (IsAudio(stream_index)) { + return uint32(((getAudioDuration(stream_index) * AudioFormat(stream_index)->SampleRate) / 1000000L) + 0.5); + } + + return 0; +} + +bool MOVFileReader::IsVideo(uint32 stream_index) +{ + // Look for a trak with a vmhd atom + + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); + + if (aAtomBase) { + return (dynamic_cast(aAtomBase)->IsVideo()); + } + + // No trak + return false; +} + +bool MOVFileReader::IsAudio(uint32 stream_index) +{ + // Look for a trak with a smhd atom + + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); + + if (aAtomBase) { + return (dynamic_cast(aAtomBase)->IsAudio()); + } + + // No trak + return false; +} + +uint32 MOVFileReader::getFirstFrameInChunk(uint32 stream_index, uint32 pChunkID) +{ + // Find Track + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); + if (aAtomBase) { + TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); + + return aTrakAtom->getFirstSampleInChunk(pChunkID); + } + + return 0; +} + +uint32 MOVFileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo) +{ + // Find Track + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); + if (aAtomBase) { + TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); + uint32 ChunkNo = 1; + + if (IsAudio(stream_index)) { + ChunkNo = pFrameNo; + } + + if (IsVideo(stream_index)) { + uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo); + + uint32 OffsetInChunk; + ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk); + } + + return aTrakAtom->getNoSamplesInChunk(ChunkNo); + } + + return 0; +} + +uint64 MOVFileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo) +{ + // Find Track + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); + if (aAtomBase) { + TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); + + if (IsAudio(stream_index)) { + // FrameNo is really chunk No for audio + uint32 ChunkNo = pFrameNo; + + // Get Offset For Chunk + return aTrakAtom->getOffsetForChunk(ChunkNo); + } + + if (IsVideo(stream_index)) { + + if (pFrameNo < aTrakAtom->FrameCount()) { + // Get Sample for Frame + uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo); + // Get Chunk For Sample and the offset for the frame within that chunk + uint32 OffsetInChunk; + uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk); + // Get Offset For Chunk + uint64 OffsetNo = aTrakAtom->getOffsetForChunk(ChunkNo); + + if (ChunkNo != 0) { + uint32 SampleSize; + // Adjust the Offset for the Offset in the chunk + if (aTrakAtom->IsSingleSampleSize()) { + SampleSize = aTrakAtom->getSizeForSample(SampleNo); + OffsetNo = OffsetNo + (OffsetInChunk * SampleSize); + } else { + // This is bad news performance wise + for (uint32 i=1;i<=OffsetInChunk;i++) { + SampleSize = aTrakAtom->getSizeForSample(SampleNo-i); + OffsetNo = OffsetNo + SampleSize; + } + } + } + + return OffsetNo; + } + } + } + + return 0; +} + +void MOVFileReader::BuildSuperIndex() +{ +AtomBase *aAtomBase; for (uint32 stream=0;streamgetTimeScale(); -} - -bigtime_t -MOVFileReader::getMovieDuration() -{ - return bigtime_t((getMVHDAtom()->getDuration() * 1000000.0) / getMovieTimeScale()); -} - -uint32 -MOVFileReader::getStreamCount() -{ - // count the number of tracks in the file - return CountChildAtoms(uint32('trak')); -} - -bigtime_t -MOVFileReader::getVideoDuration(uint32 streamIndex) -{ - AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); - - if (aAtomBase && dynamic_cast(aAtomBase)->IsVideo()) - return dynamic_cast(aAtomBase)->Duration(1); - - return 0; -} - -bigtime_t -MOVFileReader::getAudioDuration(uint32 streamIndex) -{ - AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); - - if (aAtomBase && dynamic_cast(aAtomBase)->IsAudio()) - return dynamic_cast(aAtomBase)->Duration(1); - - return 0; -} - -bigtime_t -MOVFileReader::getMaxDuration() -{ - AtomBase *aAtomBase; - int32 videoIndex = -1; - int32 audioIndex = -1; - - // find the active video and audio tracks - for (uint32 i = 0; i < getStreamCount(); i++) { - aAtomBase = GetChildAtom(uint32('trak'), i); - - if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsActive())) { - if (dynamic_cast(aAtomBase)->IsAudio()) { - audioIndex = int32(i); - } - if (dynamic_cast(aAtomBase)->IsVideo()) { - videoIndex = int32(i); - } - } - } - - if (videoIndex >= 0 && audioIndex >= 0) { - return max_c(getVideoDuration(videoIndex), - getAudioDuration(audioIndex)); - } - if (videoIndex < 0 && audioIndex >= 0) { - return getAudioDuration(audioIndex); - } - if (videoIndex >= 0 && audioIndex < 0) { - return getVideoDuration(videoIndex); - } - - return 0; -} - -uint32 -MOVFileReader::getFrameCount(uint32 streamIndex) -{ - AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); - - if (aAtomBase) { - return dynamic_cast(aAtomBase)->FrameCount(); - } - - return 1; -} - -uint32 -MOVFileReader::getAudioChunkCount(uint32 streamIndex) -{ - AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); - - if (aAtomBase && dynamic_cast(aAtomBase)->IsAudio()) - return dynamic_cast(aAtomBase)->getTotalChunks(); - - return 0; -} - -bool -MOVFileReader::IsVideo(uint32 streamIndex) -{ - // Look for a 'trak' with a vmhd atom - - AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); - if (aAtomBase) - return dynamic_cast(aAtomBase)->IsVideo(); - - // No track - return false; -} - -bool -MOVFileReader::IsAudio(uint32 streamIndex) -{ - // Look for a 'trak' with a smhd atom - - AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); - - if (aAtomBase) - return dynamic_cast(aAtomBase)->IsAudio(); - - // No track - return false; -} - -uint32 -MOVFileReader::getFirstFrameInChunk(uint32 streamIndex, uint32 pChunkID) -{ - // Find Track - AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); - if (aAtomBase) { - TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); - - return aTrakAtom->getFirstSampleInChunk(pChunkID); - } - - return 0; -} - -uint32 -MOVFileReader::getNoFramesInChunk(uint32 streamIndex, uint32 pFrameNo) -{ - // Find Track - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex); - if (aAtomBase) { - TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); - uint32 ChunkNo = 1; - - uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo); - - uint32 OffsetInChunk; - ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk); - - return aTrakAtom->getNoSamplesInChunk(ChunkNo); - } - - return 0; -} - -uint64 -MOVFileReader::getOffsetForFrame(uint32 streamIndex, uint32 pFrameNo) -{ - // Find Track - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex); - if (aAtomBase) { - TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); - - if (pFrameNo < aTrakAtom->FrameCount()) { - // Get time for Frame - bigtime_t Time = aTrakAtom->getTimeForFrame(pFrameNo); - - // Get Sample for Time - uint32 SampleNo = aTrakAtom->getSampleForTime(Time); - - // Get Chunk For Sample and the offset for the frame within that chunk - uint32 OffsetInChunk; - uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk); - // Get Offset For Chunk - uint64 OffsetNo = aTrakAtom->getOffsetForChunk(ChunkNo); - - if (ChunkNo != 0) { - uint32 SizeForSample; - // Adjust the Offset for the Offset in the chunk - if (aTrakAtom->IsSingleSampleSize()) { - SizeForSample = aTrakAtom->getSizeForSample(SampleNo); - OffsetNo = OffsetNo + (OffsetInChunk * SizeForSample); - } else { - // This is bad news performance wise - for (uint32 i=1;i<=OffsetInChunk;i++) { - SizeForSample = aTrakAtom->getSizeForSample(SampleNo-i); - OffsetNo = OffsetNo + SizeForSample; - } - } - } - - printf("frame %ld, time %Ld, sample %ld, Chunk %ld, OffsetInChunk %ld, Offset %Ld\n",pFrameNo, Time, SampleNo, ChunkNo, OffsetInChunk, OffsetNo); - - return OffsetNo; - } - } - - return 0; -} - - -status_t -MOVFileReader::ParseFile() +status_t MOVFileReader::ParseFile() { AtomBase *aChild; while (IsEndOfFile() == false) { @@ -400,8 +392,7 @@ MOVFileReader::ParseFile() return B_OK; } -const mov_main_header* -MOVFileReader::MovMainHeader() +const mov_main_header *MOVFileReader::MovMainHeader() { // Fill In theMainHeader // uint32 micro_sec_per_frame; @@ -437,22 +428,22 @@ MOVFileReader::MovMainHeader() } else { theMainHeader.width = VideoFormat(videoStream)->width; theMainHeader.height = VideoFormat(videoStream)->height; - theMainHeader.total_frames = getFrameCount(videoStream); + theMainHeader.total_frames = getVideoFrameCount(videoStream); theMainHeader.suggested_buffer_size = theMainHeader.width * theMainHeader.height * VideoFormat(videoStream)->bit_count / 8; theMainHeader.micro_sec_per_frame = uint32(1000000.0 / VideoFormat(videoStream)->FrameRate); } - + theMainHeader.padding_granularity = 0; theMainHeader.max_bytes_per_sec = 0; return &theMainHeader; } -const AudioMetaData * -MOVFileReader::AudioFormat(uint32 streamIndex) +const AudioMetaData *MOVFileReader::AudioFormat(uint32 stream_index) { - if (IsAudio(streamIndex)) { - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex); + if (IsAudio(stream_index)) { + + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); @@ -505,16 +496,17 @@ MOVFileReader::AudioFormat(uint32 streamIndex) return NULL; } -const VideoMetaData* -MOVFileReader::VideoFormat(uint32 streamIndex) +const VideoMetaData *MOVFileReader::VideoFormat(uint32 stream_index) { - if (IsVideo(streamIndex)) { - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex); + if (IsVideo(stream_index)) { + + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); - + aAtomBase = aTrakAtom->GetChildAtom(uint32('stsd'),0); + if (aAtomBase) { STSDAtom *aSTSDAtom = dynamic_cast(aAtomBase); @@ -548,30 +540,29 @@ MOVFileReader::VideoFormat(uint32 streamIndex) return NULL; } -const mov_stream_header* -MOVFileReader::StreamFormat(uint32 streamIndex) +const mov_stream_header *MOVFileReader::StreamFormat(uint32 stream_index) { - if (IsActive(streamIndex) == false) { + // Fill In a Stream Header + theStreamHeader.length = 0; + + if (IsActive(stream_index) == false) { return NULL; } - // Fill In a Stream Header - theStreamHeader.length = 0; - - if (IsVideo(streamIndex)) { - theStreamHeader.rate = uint32(1000000.0*VideoFormat(streamIndex)->FrameRate); + if (IsVideo(stream_index)) { + theStreamHeader.rate = uint32(1000000L*VideoFormat(stream_index)->FrameRate); theStreamHeader.scale = 1000000L; - theStreamHeader.length = getFrameCount(streamIndex); + theStreamHeader.length = getVideoFrameCount(stream_index); } - - if (IsAudio(streamIndex)) { - theStreamHeader.rate = uint32(AudioFormat(streamIndex)->SampleRate); + + if (IsAudio(stream_index)) { + theStreamHeader.rate = uint32(AudioFormat(stream_index)->SampleRate); theStreamHeader.scale = 1; - theStreamHeader.length = getFrameCount(streamIndex); - theStreamHeader.sample_size = AudioFormat(streamIndex)->SampleSize; - theStreamHeader.suggested_buffer_size = AudioFormat(streamIndex)->BufferSize; + theStreamHeader.length = getAudioFrameCount(stream_index); + theStreamHeader.sample_size = AudioFormat(stream_index)->SampleSize; + theStreamHeader.suggested_buffer_size = theStreamHeader.rate * theStreamHeader.sample_size; } - + return &theStreamHeader; } @@ -579,14 +570,23 @@ MOVFileReader::StreamFormat(uint32 streamIndex) uint32 MOVFileReader::getChunkSize(uint32 streamIndex, uint32 frameNumber) { - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex); - if (aAtomBase) { - TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); + AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); + if (aAtomBase == NULL) + return 0; + TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); + + if (IsAudio(streamIndex)) { + // We read audio in chunk by chunk so chunk size is chunk size + off_t chunkStart = aTrakAtom->getOffsetForChunk(frameNumber); + return theChunkSuperIndex.getChunkSize(streamIndex, frameNumber, chunkStart); + } + + if (IsVideo(streamIndex)) { if (frameNumber < aTrakAtom->FrameCount()) { - uint32 SampleNo = aTrakAtom->getSampleForFrame(frameNumber); - - return aTrakAtom->getSizeForSample(SampleNo); + // We read video in Sample by Sample so chunk size is Sample Size + uint32 sampleNumber = aTrakAtom->getSampleForFrame(frameNumber); + return aTrakAtom->getSizeForSample(sampleNumber); } } @@ -595,62 +595,57 @@ MOVFileReader::getChunkSize(uint32 streamIndex, uint32 frameNumber) bool -MOVFileReader::IsKeyFrame(uint32 streamIndex, uint32 pFrameNo) +MOVFileReader::IsKeyFrame(uint32 stream_index, uint32 pFrameNo) { - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex); + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); - - return aTrakAtom->IsSyncSample(pFrameNo); + + uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo); + return aTrakAtom->IsSyncSample(SampleNo); } return false; } -bool -MOVFileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo, - off_t *start, uint32 *size, bool *keyframe) +bool MOVFileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe) { - *start = getOffsetForFrame(streamIndex, pFrameNo); - *size = getChunkSize(streamIndex, pFrameNo); - + *start = getOffsetForFrame(stream_index, pFrameNo); + *size = getChunkSize(stream_index, pFrameNo); + if ((*start > 0) && (*size > 0)) { - *keyframe = IsKeyFrame(streamIndex, pFrameNo); + *keyframe = IsKeyFrame(stream_index, pFrameNo); } -// printf("start %Ld, size %ld, eof %s, eod %s\n",*start,*size, IsEndOfFile(*start + *size) ? "true" : "false", IsEndOfData(*start + *size) ? "true" : "false"); - - // TODO need a better method for detecting End of Data Note ChunkSize of 0 seems to be it. - return *start > 0 && *size > 0 && !IsEndOfFile(*start + *size) - && !IsEndOfData(*start + *size); + return ((*start > 0) && (*size > 0) && !(IsEndOfFile(*start + *size)) && !(IsEndOfData(*start + *size))); } -bool -MOVFileReader::IsActive(uint32 streamIndex) +bool MOVFileReader::IsActive(uint32 stream_index) { - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex); + AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); return aTrakAtom->IsActive(); } - + return false; } /* static */ -bool -MOVFileReader::IsSupported(BPositionIO *source) +bool MOVFileReader::IsSupported(BPositionIO *source) { // MOV files normally do not have ftyp atoms // But when they do we need to check if they have a qt brand // No qt brand means the file is likely to be a MP4 file - AtomBase *aAtom = getAtom(source); + AtomBase *aAtom; + + aAtom = getAtom(source); if (aAtom) { if (dynamic_cast(aAtom)) { - aAtom->ProcessMetaData(); printf("ftyp atom found checking for qt brand\n"); + aAtom->ProcessMetaData(); // MP4 files start with a ftyp atom that contains an isom brand // MOV files with a ftyp atom contain the qt brand return dynamic_cast(aAtom)->HasBrand(uint32('qt ')); diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.h b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.h index 5acb936bc5..7c9eed4372 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.h @@ -33,7 +33,7 @@ #include "MOVParser.h" #include "ChunkSuperIndex.h" -// QT MOV file reader +// QT MOV file reader (and maybe MP4 as well) class MOVFileReader { private: // Atom List @@ -68,9 +68,9 @@ public: // getter for MVHDAtom MVHDAtom *getMVHDAtom(); - bool IsEndOfFile(off_t position); + bool IsEndOfFile(off_t pPosition); bool IsEndOfFile(); - bool IsEndOfData(off_t position); + bool IsEndOfData(off_t pPosition); // Is this a quicktime file static bool IsSupported(BPositionIO *source); @@ -81,44 +81,45 @@ public: // Duration defined by the movie header bigtime_t getMovieDuration(); - // The first video track duration indexed by streamIndex - bigtime_t getVideoDuration(uint32 streamIndex); - // the first audio track duration indexed by streamIndex - bigtime_t getAudioDuration(uint32 streamIndex); + // The first video track duration indexed by stream_index + bigtime_t getVideoDuration(uint32 stream_index); + // the first audio track duration indexed by stream_index + bigtime_t getAudioDuration(uint32 stream_index); // the max of all active audio or video durations bigtime_t getMaxDuration(); - // The no of frames in the track indexed by streamIndex - uint32 getFrameCount(uint32 streamIndex); - // The no of chunks in the audio track indexed by streamIndex - uint32 getAudioChunkCount(uint32 streamIndex); + // The no of frames in the video track indexed by stream_index + uint32 getVideoFrameCount(uint32 stream_index); + // The no of frames in the audio track indexed by stream_index + uint32 getAudioFrameCount(uint32 stream_index); + // Is stream (track) a video track - bool IsVideo(uint32 streamIndex); + bool IsVideo(uint32 stream_index); // Is stream (track) a audio track - bool IsAudio(uint32 streamIndex); + bool IsAudio(uint32 stream_index); - uint32 getNoFramesInChunk(uint32 streamIndex, uint32 pFrameNo); - uint32 getFirstFrameInChunk(uint32 streamIndex, uint32 pChunkID); + uint32 getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo); + uint32 getFirstFrameInChunk(uint32 stream_index, uint32 pChunkID); - uint64 getOffsetForFrame(uint32 streamIndex, uint32 pFrameNo); - uint32 getChunkSize(uint32 streamIndex, uint32 pFrameNo); - bool IsKeyFrame(uint32 streamIndex, uint32 pFrameNo); + uint64 getOffsetForFrame(uint32 stream_index, uint32 pFrameNo); + uint32 getChunkSize(uint32 stream_index, uint32 pFrameNo); + bool IsKeyFrame(uint32 stream_index, uint32 pFrameNo); status_t ParseFile(); BPositionIO *Source() {return theStream;}; - bool IsActive(uint32 streamIndex); + bool IsActive(uint32 stream_index); - bool GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe); + bool GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe); // Return all Audio Meta Data - const AudioMetaData *AudioFormat(uint32 streamIndex); + const AudioMetaData *AudioFormat(uint32 stream_index); // Return all Video Meta Data - const VideoMetaData *VideoFormat(uint32 streamIndex); + const VideoMetaData *VideoFormat(uint32 stream_index); // XXX these need work const mov_main_header *MovMainHeader(); - const mov_stream_header *StreamFormat(uint32 streamIndex); + const mov_stream_header *StreamFormat(uint32 stream_index); }; #endif diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp index 2b206f5c4d..7a40593308 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp @@ -57,10 +57,6 @@ AtomBase *getAtom(BPositionIO *pStream) // Handle extended size pStream->Read(&aRealAtomSize,4); aRealAtomSize = B_BENDIAN_TO_HOST_INT64(aRealAtomSize); - } else if (aAtomSize == 0) { - // aAtomSize extends to end of file. - // TODO this is broken - aRealAtomSize = 0; } else { aRealAtomSize = aAtomSize; } @@ -161,22 +157,10 @@ AtomBase *getAtom(BPositionIO *pStream) return new STSSAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); } - if (aAtomType == uint32('ctts')) { - return new CTTSAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); - } - if (aAtomType == uint32('stsz')) { return new STSZAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); } - if (aAtomType == uint32('stz2')) { - return new STZ2Atom(pStream, aStreamOffset, aAtomType, aRealAtomSize); - } - - if (aAtomType == uint32('ftyp')) { - return new FTYPAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); - } - if (aAtomType == uint32('cmov')) { return new CMOVAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); } @@ -193,6 +177,10 @@ AtomBase *getAtom(BPositionIO *pStream) return new ESDSAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); } + if (aAtomType == uint32('ftyp')) { + return new FTYPAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); + } + return new AtomBase(pStream, aStreamOffset, aAtomType, aRealAtomSize); } @@ -377,7 +365,7 @@ char *CMVDAtom::OnGetAtomName() return "Compressed Movie Data"; } -MVHDAtom::MVHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +MVHDAtom::MVHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { } @@ -387,7 +375,6 @@ MVHDAtom::~MVHDAtom() void MVHDAtom::OnProcessMetaData() { - FullAtom::OnProcessMetaData(); Read(&theHeader.CreationTime); Read(&theHeader.ModificationTime); Read(&theHeader.TimeScale); @@ -400,7 +387,7 @@ void MVHDAtom::OnProcessMetaData() Read(&theHeader.SelectionTime); Read(&theHeader.SelectionDuration); Read(&theHeader.CurrentTime); - Read(&theHeader.NextTrackID); + Read(&theHeader.NextTrackID); } char *MVHDAtom::OnGetAtomName() @@ -421,7 +408,7 @@ AtomBase *aAtomBase; return theMVHDAtom; } -STTSAtom::STTSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +STTSAtom::STTSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { theHeader.NoEntries = 0; SUMDurations = 0; @@ -440,12 +427,8 @@ void STTSAtom::OnProcessMetaData() { TimeToSample *aTimeToSample; - FullAtom::OnProcessMetaData(); - ReadArrayHeader(&theHeader); -// printf("STTS:: Entries %ld\n",theHeader.NoEntries); - for (uint32 i=0;iDuration * theTimeToSampleArray[i]->Count); SUMCounts += theTimeToSampleArray[i]->Count; - -// printf("(%ld,%ld)",aTimeToSample->Count,aTimeToSample->Duration); - } -// printf("\n"); } char *STTSAtom::OnGetAtomName() @@ -467,55 +446,28 @@ char *STTSAtom::OnGetAtomName() return "Time to Sample Atom"; } -uint32 STTSAtom::getSampleForTime(bigtime_t pTime) +uint32 STTSAtom::getSampleForTime(uint32 pTime) { - // Sample for time is this calc, how does STTS help us? - return uint32((pTime * FrameRate + 50) / 1000000.0); +// TODO this is too slow. PreCalc when loading this? + uint64 Duration = 0; + + for (uint32 i=0;iDuration * theTimeToSampleArray[i]->Count); + if (Duration > pTime) { + return i; + } + } + + return 0; } uint32 STTSAtom::getSampleForFrame(uint32 pFrame) { - // Convert frame to time and call getSampleForTime() +// Hmm Sample is Frame really, this Atom is more usefull for time->sample calcs return pFrame; } -CTTSAtom::CTTSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) -{ - theHeader.NoEntries = 0; -} - -CTTSAtom::~CTTSAtom() -{ - for (uint32 i=0;iCount); - Read(&aCompTimeToSample->Offset); - - theCompTimeToSampleArray[i] = aCompTimeToSample; - } -} - -char *CTTSAtom::OnGetAtomName() -{ - return "Composition Time to Sample Atom"; -} - -STSCAtom::STSCAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +STSCAtom::STSCAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { theHeader.NoEntries = 0; } @@ -532,13 +484,9 @@ void STSCAtom::OnProcessMetaData() { SampleToChunk *aSampleToChunk; - FullAtom::OnProcessMetaData(); - ReadArrayHeader(&theHeader); uint32 TotalPrevSamples = 0; - -// printf("STSC:: Entries %ld\n",theHeader.NoEntries); for (uint32 i=0;iTotalPrevSamples = 0; } -// printf("(%ld,%ld)",aSampleToChunk->SamplesPerChunk, aSampleToChunk->TotalPrevSamples); - theSampleToChunkArray[i] = aSampleToChunk; } -// printf("\n"); } char *STSCAtom::OnGetAtomName() @@ -614,7 +559,7 @@ uint32 STSCAtom::getChunkForSample(uint32 pSample, uint32 *pOffsetInChunk) return theSampleToChunkArray[theHeader.NoEntries-1]->FirstChunk; } -STSSAtom::STSSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +STSSAtom::STSSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { theHeader.NoEntries = 0; } @@ -631,15 +576,12 @@ void STSSAtom::OnProcessMetaData() { SyncSample *aSyncSample; - FullAtom::OnProcessMetaData(); - ReadArrayHeader(&theHeader); - + for (uint32 i=0;iSyncSampleNo); - theSyncSampleArray[i] = aSyncSample; } } @@ -657,7 +599,7 @@ bool STSSAtom::IsSyncSample(uint32 pSampleNo) return true; } - if (pSampleNo < theSyncSampleArray[i]->SyncSampleNo) { + if (pSampleNo > theSyncSampleArray[i]->SyncSampleNo) { return false; } } @@ -665,14 +607,14 @@ bool STSSAtom::IsSyncSample(uint32 pSampleNo) return false; } -STSZAtom::STSZAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +STSZAtom::STSZAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { - SampleCount = 0; + theHeader.NoEntries = 0; } STSZAtom::~STSZAtom() { - for (uint32 i=0;iEntrySize); - - theSampleSizeArray[i] = aSampleSizePtr; + Read(&aSampleSize->EntrySize); + theSampleSizeArray[i] = aSampleSize; } } } char *STSZAtom::OnGetAtomName() { - printf("SS=%ld Count=%ld ",SampleSize,SampleCount); + printf("%ld ",theHeader.SampleSize); return "Sample Size Atom"; } uint32 STSZAtom::getSizeForSample(uint32 pSampleNo) { - if (SampleSize > 0) { + if (theHeader.SampleSize > 0) { // All samples are the same size - return SampleSize; + return theHeader.SampleSize; } // Sample Array indexed by SampleNo @@ -718,96 +662,10 @@ uint32 STSZAtom::getSizeForSample(uint32 pSampleNo) bool STSZAtom::IsSingleSampleSize() { - return (SampleSize > 0); + return (theHeader.SampleSize > 0); } -STZ2Atom::STZ2Atom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) -{ - SampleCount = 0; -} - -STZ2Atom::~STZ2Atom() -{ - for (uint32 i=0;iEntrySize = (uint32)(EntrySize8); - break; - case 8: - Read(&EntrySize8); - // 1 value per byte - aSampleSizePtr->EntrySize = (uint32)(EntrySize8); - break; - case 16: - Read(&EntrySize16); - // 1 value per 2 bytes - aSampleSizePtr->EntrySize = (uint32)(EntrySize16); - break; - } - - theSampleSizeArray[i] = aSampleSizePtr; - } -} - -char *STZ2Atom::OnGetAtomName() -{ - return "Compressed Sample Size Atom"; -} - -uint32 STZ2Atom::getSizeForSample(uint32 pSampleNo) -{ -// THIS CODE NEEDS SOME TESTING, never seen a STZ2 atom - -uint32 index; - - if (FieldSize == 4) { - // 2 entries per array entry so Divide by 2 - index = pSampleNo / 2; - if (index * 2 == pSampleNo) { - // even so return low nibble - return theSampleSizeArray[index]->EntrySize && 0x0000000f; - } else { - // odd so return high nibble - return theSampleSizeArray[index]->EntrySize && 0x000000f0; - } - } - - // Sample Array indexed by SampleNo - return theSampleSizeArray[pSampleNo]->EntrySize; -} - -bool STZ2Atom::IsSingleSampleSize() -{ - return false; -} - -STCOAtom::STCOAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +STCOAtom::STCOAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { theHeader.NoEntries = 0; } @@ -834,8 +692,6 @@ void STCOAtom::OnProcessMetaData() { ChunkToOffset *aChunkToOffset; - FullAtom::OnProcessMetaData(); - ReadArrayHeader(&theHeader); for (uint32 i=0;i(getParent())->getMediaHandlerType(); + return dynamic_cast(getParent())->getMediaComponentSubType(); } void STSDAtom::ReadSoundDescription() @@ -1089,9 +945,6 @@ void STSDAtom::ReadVideoDescription() void STSDAtom::OnProcessMetaData() { - - FullAtom::OnProcessMetaData(); - ReadArrayHeader(&theHeader); for (uint32 i=0;i(getParent())->getMediaHandlerType(); + return dynamic_cast(getParent())->getMediaComponentSubType(); } STBLAtom::STBLAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize) @@ -1316,9 +1168,9 @@ char *STBLAtom::OnGetAtomName() return "Quicktime Sample Table Atom"; } -uint32 STBLAtom::getMediaHandlerType() +uint32 STBLAtom::getMediaComponentSubType() { - return dynamic_cast(getParent())->getMediaHandlerType(); + return dynamic_cast(getParent())->getMediaComponentSubType(); } DINFAtom::DINFAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize) @@ -1338,7 +1190,7 @@ char *DINFAtom::OnGetAtomName() return "Quicktime Data Information Atom"; } -TKHDAtom::TKHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +TKHDAtom::TKHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { } @@ -1348,11 +1200,15 @@ TKHDAtom::~TKHDAtom() void TKHDAtom::OnProcessMetaData() { - - FullAtom::OnProcessMetaData(); + Read(&Version); - if (getVersion() == 0) { + if (Version == 0) { + // Read into V0 header and convert to V1 Header tkhdV0 aHeaderV0; + + Read(&aHeaderV0.Flags1); + Read(&aHeaderV0.Flags2); + Read(&aHeaderV0.Flags3); Read(&aHeaderV0.CreationTime); Read(&aHeaderV0.ModificationTime); Read(&aHeaderV0.TrackID); @@ -1363,23 +1219,26 @@ void TKHDAtom::OnProcessMetaData() Read(&aHeaderV0.AlternateGroup); Read(&aHeaderV0.Volume); Read(&aHeaderV0.Reserved3); - - for (uint32 i=0;i<9;i++) { - Read(&theHeader.MatrixStructure[i]); - } - + Read(aHeaderV0.MatrixStructure,36); Read(&aHeaderV0.TrackWidth); Read(&aHeaderV0.TrackHeight); + theHeader.Flags1 = aHeaderV0.Flags1; + theHeader.Flags2 = aHeaderV0.Flags2; + theHeader.Flags3 = aHeaderV0.Flags3; theHeader.Reserved1 = aHeaderV0.Reserved1; theHeader.Reserved2 = aHeaderV0.Reserved2; theHeader.Reserved3 = aHeaderV0.Reserved3; + + for (uint32 i=0;i<36;i++) { + theHeader.MatrixStructure[i] = aHeaderV0.MatrixStructure[i]; + } // upconvert to V1 header - theHeader.CreationTime = (uint64)(aHeaderV0.CreationTime); - theHeader.ModificationTime = (uint64)(aHeaderV0.ModificationTime); + theHeader.CreationTime = uint64(aHeaderV0.CreationTime); + theHeader.ModificationTime = uint64(aHeaderV0.ModificationTime); theHeader.TrackID = aHeaderV0.TrackID; - theHeader.Duration = (uint64)(aHeaderV0.Duration); + theHeader.Duration = aHeaderV0.Duration; theHeader.Layer = aHeaderV0.Layer; theHeader.AlternateGroup = aHeaderV0.AlternateGroup; theHeader.Volume = aHeaderV0.Volume; @@ -1387,6 +1246,10 @@ void TKHDAtom::OnProcessMetaData() theHeader.TrackHeight = aHeaderV0.TrackHeight; } else { + // Read direct into V1 Header + Read(&theHeader.Flags1); + Read(&theHeader.Flags2); + Read(&theHeader.Flags3); Read(&theHeader.CreationTime); Read(&theHeader.ModificationTime); Read(&theHeader.TrackID); @@ -1397,11 +1260,7 @@ void TKHDAtom::OnProcessMetaData() Read(&theHeader.AlternateGroup); Read(&theHeader.Volume); Read(&theHeader.Reserved3); - - for (uint32 i=0;i<9;i++) { - Read(&theHeader.MatrixStructure[i]); - } - + Read(theHeader.MatrixStructure,36); Read(&theHeader.TrackWidth); Read(&theHeader.TrackHeight); } @@ -1430,20 +1289,20 @@ char *MDIAAtom::OnGetAtomName() return "Quicktime Media Atom"; } -uint32 MDIAAtom::getMediaHandlerType() +uint32 MDIAAtom::getMediaComponentSubType() { // get child atom hdlr HDLRAtom *aHDLRAtom; aHDLRAtom = dynamic_cast(GetChildAtom(uint32('hdlr'))); if (aHDLRAtom) { - return aHDLRAtom->getMediaHandlerType(); + return aHDLRAtom->getMediaComponentSubType(); } return 0; } -MDHDAtom::MDHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +MDHDAtom::MDHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { } @@ -1453,7 +1312,10 @@ MDHDAtom::~MDHDAtom() void MDHDAtom::OnProcessMetaData() { - FullAtom::OnProcessMetaData(); + Read(&theHeader.Version); + Read(&theHeader.Flags1); + Read(&theHeader.Flags2); + Read(&theHeader.Flags3); Read(&theHeader.CreationTime); Read(&theHeader.ModificationTime); Read(&theHeader.TimeScale); @@ -1469,7 +1331,7 @@ char *MDHDAtom::OnGetAtomName() bigtime_t MDHDAtom::getDuration() { - return bigtime_t((theHeader.Duration * 1000000.0) / theHeader.TimeScale); + return bigtime_t((uint64(theHeader.Duration) * 1000000L) / theHeader.TimeScale); } uint32 MDHDAtom::getTimeScale() @@ -1477,30 +1339,27 @@ uint32 MDHDAtom::getTimeScale() return theHeader.TimeScale; } -HDLRAtom::HDLRAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +HDLRAtom::HDLRAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { - name = NULL; } HDLRAtom::~HDLRAtom() { - if (name) { - free(name); - } } void HDLRAtom::OnProcessMetaData() { - FullAtom::OnProcessMetaData(); + Read(&theHeader.Version); + Read(&theHeader.Flags1); + Read(&theHeader.Flags2); + Read(&theHeader.Flags3); Read(&theHeader.ComponentType); Read(&theHeader.ComponentSubType); Read(&theHeader.ComponentManufacturer); Read(&theHeader.ComponentFlags); Read(&theHeader.ComponentFlagsMask); - - name = (char *)(malloc(getBytesRemaining())); - - Read(name,getBytesRemaining()); + + // Read Array of Strings? } char *HDLRAtom::OnGetAtomName() @@ -1518,12 +1377,12 @@ bool HDLRAtom::IsAudioHandler() return (theHeader.ComponentSubType == 'soun'); } -uint32 HDLRAtom::getMediaHandlerType() +uint32 HDLRAtom::getMediaComponentSubType() { return theHeader.ComponentSubType; } -VMHDAtom::VMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +VMHDAtom::VMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { } @@ -1533,11 +1392,15 @@ VMHDAtom::~VMHDAtom() void VMHDAtom::OnProcessMetaData() { - FullAtom::OnProcessMetaData(); - Read(&theHeader.GraphicsMode); - Read(&theHeader.OpColourRed); - Read(&theHeader.OpColourGreen); - Read(&theHeader.OpColourBlue); + vmhd aHeader; + Read(&aHeader.Version); + Read(&aHeader.Flags1); + Read(&aHeader.Flags2); + Read(&aHeader.Flags3); + Read(&aHeader.GraphicsMode); + Read(&aHeader.OpColourRed); + Read(&aHeader.OpColourGreen); + Read(&aHeader.OpColourBlue); } char *VMHDAtom::OnGetAtomName() @@ -1545,7 +1408,7 @@ char *VMHDAtom::OnGetAtomName() return "Quicktime Video Media Header"; } -SMHDAtom::SMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) +SMHDAtom::SMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { } @@ -1555,9 +1418,13 @@ SMHDAtom::~SMHDAtom() void SMHDAtom::OnProcessMetaData() { - FullAtom::OnProcessMetaData(); - Read(&theHeader.Balance); - Read(&theHeader.Reserved); + smhd aHeader; + Read(&aHeader.Version); + Read(&aHeader.Flags1); + Read(&aHeader.Flags2); + Read(&aHeader.Flags3); + Read(&aHeader.Balance); + Read(&aHeader.Reserved); } char *SMHDAtom::OnGetAtomName() diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h index 53f595171a..82fd9eac08 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h @@ -26,6 +26,8 @@ #define _MOV_PARSER_H +#include "MOVAtom.h" + #include #include #include @@ -33,10 +35,7 @@ #include -#include "MOVAtom.h" -typedef CompTimeToSample* CompTimeToSamplePtr; -typedef std::map > CompTimeToSampleArray; typedef SoundDescriptionV1* SoundDescPtr; typedef std::map > SoundDescArray; typedef VideoDescriptionV0* VideoDescPtr; @@ -49,11 +48,11 @@ typedef ChunkToOffset* ChunkToOffsetPtr; typedef std::map > ChunkToOffsetArray; typedef SyncSample* SyncSamplePtr; typedef std::map > SyncSampleArray; -typedef SampleSizeEntry* SampleSizePtr; -typedef std::map > SampleSizeArray; +typedef SampleSizeEntry* SampleSizeEntryPtr; +typedef std::map > SampleSizeArray; // Atom class for reading the movie header atom -class MVHDAtom : public FullAtom { +class MVHDAtom : public AtomBase { public: MVHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~MVHDAtom(); @@ -122,22 +121,6 @@ private: uint8 *Buffer; }; -// Atom class for reading the ftyp atom -class FTYPAtom : public AtomBase { -public: - FTYPAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); - virtual ~FTYPAtom(); - void OnProcessMetaData(); - char *OnGetAtomName(); - - bool HasBrand(uint32 brand); -private: - uint32 major_brand; - uint32 minor_version; - uint32 compatable_brands[32]; // Should be infinite but we will settle for max 32 - uint32 total_brands; -}; - // Atom class for reading the wide atom class WIDEAtom : public AtomBase { public: @@ -169,42 +152,26 @@ public: }; // Atom class for reading the time to sample atom -class STTSAtom : public FullAtom { +class STTSAtom : public AtomBase { public: STTSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~STTSAtom(); void OnProcessMetaData(); char *OnGetAtomName(); - uint64 getSUMCounts() { return SUMCounts; }; - bigtime_t getSUMDurations() { return SUMDurations; }; - uint32 getSampleForTime(bigtime_t pTime); + uint64 getSUMCounts() {return SUMCounts;}; + uint64 getSUMDurations() {return SUMDurations;}; + uint32 getSampleForTime(uint32 pTime); uint32 getSampleForFrame(uint32 pFrame); - void setFrameRate(float pFrameRate) { FrameRate = pFrameRate; }; - private: array_header theHeader; TimeToSampleArray theTimeToSampleArray; - bigtime_t SUMDurations; + uint64 SUMDurations; uint64 SUMCounts; - float FrameRate; -}; - -// Atom class for reading the composition time to sample atom -class CTTSAtom : public FullAtom { -public: - CTTSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); - virtual ~CTTSAtom(); - void OnProcessMetaData(); - char *OnGetAtomName(); - -private: - array_header theHeader; - CompTimeToSampleArray theCompTimeToSampleArray; }; // Atom class for reading the sample to chunk atom -class STSCAtom : public FullAtom { +class STSCAtom : public AtomBase { public: STSCAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~STSCAtom(); @@ -220,7 +187,7 @@ private: }; // Atom class for reading the chunk to offset atom -class STCOAtom : public FullAtom { +class STCOAtom : public AtomBase { public: STCOAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~STCOAtom(); @@ -240,7 +207,7 @@ private: }; // Atom class for reading the sync sample atom -class STSSAtom : public FullAtom { +class STSSAtom : public AtomBase { public: STSSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~STSSAtom(); @@ -254,7 +221,7 @@ private: }; // Atom class for reading the sample size atom -class STSZAtom : public FullAtom { +class STSZAtom : public AtomBase { public: STSZAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~STSZAtom(); @@ -264,27 +231,7 @@ public: uint32 getSizeForSample(uint32 pSampleNo); bool IsSingleSampleSize(); private: - uint32 SampleSize; - uint32 SampleCount; - - SampleSizeArray theSampleSizeArray; -}; - -// Atom class for reading the sample size 2 atom -class STZ2Atom : public FullAtom { -public: - STZ2Atom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); - virtual ~STZ2Atom(); - void OnProcessMetaData(); - char *OnGetAtomName(); - - uint32 getSizeForSample(uint32 pSampleNo); - bool IsSingleSampleSize(); -private: - uint32 SampleSize; - uint32 SampleCount; - uint8 FieldSize; - + SampleSizeHeader theHeader; SampleSizeArray theSampleSizeArray; }; @@ -321,7 +268,7 @@ private: }; // Atom class for reading the sdst atom -class STSDAtom : public FullAtom { +class STSDAtom : public AtomBase { public: STSDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~STSDAtom(); @@ -343,7 +290,7 @@ private: }; // Atom class for reading the track header atom -class TKHDAtom : public FullAtom { +class TKHDAtom : public AtomBase { public: TKHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~TKHDAtom(); @@ -357,16 +304,18 @@ public: // 0x002 Track in Movie // 0x004 Track in Preview // 0x008 Track in Poster + // It seems active tracks have all 4 flags set? - bool IsActive() {return ((getFlags3() && 0x01) || (getFlags3() && 0x0f));}; + bool IsActive() {return ((theHeader.Flags3 == 0x0f) || (theHeader.Flags3 == 0x03));}; private: tkhdV1 theHeader; + uint8 Version; }; // Atom class for reading the media header atom -class MDHDAtom : public FullAtom { +class MDHDAtom : public AtomBase { public: MDHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~MDHDAtom(); @@ -383,27 +332,23 @@ private: }; // Atom class for reading the video media header atom -class VMHDAtom : public FullAtom { +class VMHDAtom : public AtomBase { public: VMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~VMHDAtom(); void OnProcessMetaData(); char *OnGetAtomName(); - bool IsCopyMode() {return theHeader.GraphicsMode == 0;}; -private: - vmhd theHeader ; }; // Atom class for reading the sound media header atom -class SMHDAtom : public FullAtom { +class SMHDAtom : public AtomBase { public: SMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~SMHDAtom(); void OnProcessMetaData(); char *OnGetAtomName(); -private: - smhd theHeader; + }; // Atom class for reading the track atom @@ -416,15 +361,14 @@ public: void OnChildProcessingComplete(); bigtime_t Duration(uint32 TimeScale); // Return duration of track - bigtime_t Duration() { return Duration(timescale); } - uint32 FrameCount() { return framecount; }; + uint32 FrameCount() {return framecount;}; bool IsVideo(); // Is this a video track bool IsAudio(); // Is this a audio track // GetAudioMetaData() // If this is a audio track get the audio meta data // GetVideoMetaData() // If this is a video track get the video meta data - bigtime_t getTimeForFrame(uint32 pFrame); - uint32 getSampleForTime(bigtime_t pTime); + uint32 getTimeForFrame(uint32 pFrame, uint32 pTimeScale); + uint32 getSampleForTime(uint32 pTime); uint32 getSampleForFrame(uint32 pFrame); uint32 getChunkForSample(uint32 pSample, uint32 *pOffsetInChunk); uint64 getOffsetForChunk(uint32 pChunkID); @@ -433,15 +377,12 @@ public: uint32 getNoSamplesInChunk(uint32 pChunkID); uint32 getTotalChunks(); - float getSampleRate(); - float getFrameRate(); - bool IsSyncSample(uint32 pSampleNo); bool IsSingleSampleSize(); bool IsActive(); uint32 getBytesPerSample(); - + TKHDAtom *getTKHDAtom(); MDHDAtom *getMDHDAtom(); private: @@ -450,7 +391,6 @@ private: uint32 framecount; uint32 bytespersample; - uint32 timescale; }; // Atom class for reading the media container atom @@ -461,7 +401,7 @@ public: void OnProcessMetaData(); char *OnGetAtomName(); - uint32 getMediaHandlerType(); + uint32 getMediaComponentSubType(); }; // Atom class for reading the media information atom @@ -472,7 +412,7 @@ public: void OnProcessMetaData(); char *OnGetAtomName(); - uint32 getMediaHandlerType(); + uint32 getMediaComponentSubType(); }; // Atom class for reading the stbl atom @@ -483,7 +423,7 @@ public: void OnProcessMetaData(); char *OnGetAtomName(); - uint32 getMediaHandlerType(); + uint32 getMediaComponentSubType(); }; // Atom class for reading the dinf atom @@ -518,7 +458,7 @@ private: }; // Atom class for reading the Media Handler atom -class HDLRAtom : public FullAtom { +class HDLRAtom : public AtomBase { public: HDLRAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); virtual ~HDLRAtom(); @@ -527,11 +467,26 @@ public: bool IsVideoHandler(); bool IsAudioHandler(); - uint32 getMediaHandlerType(); + uint32 getMediaComponentSubType(); private: hdlr theHeader; - char *name; +}; + +class FTYPAtom : public AtomBase { +public: + FTYPAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); + virtual ~FTYPAtom(); + void OnProcessMetaData(); + char *OnGetAtomName(); + bool HasBrand(uint32 brand); + +private: + uint32 major_brand; + uint32 minor_version; + uint32 compatable_brands[32]; // Should be infinite but we will settle for max 32 + uint32 total_brands; + }; #endif diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVTrakAtom.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVTrakAtom.cpp index 44123664d7..67bdce5fac 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVTrakAtom.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVTrakAtom.cpp @@ -30,7 +30,6 @@ TRAKAtom::TRAKAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, theMDHDAtom = NULL; framecount = 0; bytespersample = 0; - timescale = 1; } TRAKAtom::~TRAKAtom() @@ -79,20 +78,16 @@ bigtime_t TRAKAtom::Duration(uint32 TimeScale) return getMDHDAtom()->getDuration(); } - return bigtime_t(getTKHDAtom()->getDuration() * 1000000.0) / TimeScale; + return bigtime_t(getTKHDAtom()->getDuration() * 1000000L) / TimeScale; } void TRAKAtom::OnChildProcessingComplete() { - timescale = getMDHDAtom()->getTimeScale(); - STTSAtom *aSTTSAtom = dynamic_cast(GetChildAtom(uint32('stts'),0)); if (aSTTSAtom) { framecount = aSTTSAtom->getSUMCounts(); - aSTTSAtom->setFrameRate(getFrameRate()); } - } // Is this a video track @@ -109,46 +104,25 @@ bool TRAKAtom::IsAudio() return (GetChildAtom(uint32('smhd'),0) != NULL); } -// frames per us -float TRAKAtom::getFrameRate() +uint32 TRAKAtom::getTimeForFrame(uint32 pFrame, uint32 pTimeScale) { - if (IsAudio()) { - AtomBase *aAtomBase = GetChildAtom(uint32('stsd'),0); - if (aAtomBase) { - STSDAtom *aSTSDAtom = dynamic_cast(aAtomBase); - - SoundDescriptionV1 aAudioDescription = aSTSDAtom->getAsAudio(); - return (aAudioDescription.desc.SampleRate / 65536.0) / aAudioDescription.bytesPerFrame; - } - } else if (IsVideo()) { - return (framecount * 1000000.0) / Duration(); - } + AtomBase *aAtomBase = GetChildAtom(uint32('stts'),0); - return 0.0; -} + if (aAtomBase) { + STTSAtom *aSTTSAtom = dynamic_cast(aAtomBase); -float TRAKAtom::getSampleRate() -{ - // Only valid for Audio - if (IsAudio()) { - AtomBase *aAtomBase = GetChildAtom(uint32('stsd'),0); - if (aAtomBase) { - STSDAtom *aSTSDAtom = dynamic_cast(aAtomBase); - - SoundDescriptionV1 aAudioDescription = aSTSDAtom->getAsAudio(); - return aAudioDescription.desc.SampleRate / 65536; + if (IsAudio()) { + // Frame * SampleRate = Time + } else if (IsVideo()) { + // Frame * fps = Time + return pFrame * ((aSTTSAtom->getSUMCounts() * 1000000L) / Duration(pTimeScale)); } } - return 0.0; + return 0; } -bigtime_t TRAKAtom::getTimeForFrame(uint32 pFrame) -{ - return bigtime_t((pFrame * 1000000.0) / getFrameRate()); -} - -uint32 TRAKAtom::getSampleForTime(bigtime_t pTime) +uint32 TRAKAtom::getSampleForTime(uint32 pTime) { AtomBase *aAtomBase = GetChildAtom(uint32('stts'),0); @@ -164,7 +138,7 @@ uint32 TRAKAtom::getSampleForFrame(uint32 pFrame) AtomBase *aAtomBase = GetChildAtom(uint32('stts'),0); if (aAtomBase) { - return (dynamic_cast(aAtomBase))->getSampleForTime(getTimeForFrame(pFrame)); + return (dynamic_cast(aAtomBase))->getSampleForFrame(pFrame); } return 0; diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h b/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h index 88a8a5486d..56b0eea228 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h @@ -140,11 +140,6 @@ struct TimeToSample { uint32 Duration; }; -struct CompTimeToSample { - uint32 Count; - uint32 Offset; -}; - struct SampleToChunk { uint32 FirstChunk; uint32 SamplesPerChunk; diff --git a/src/add-ons/media/plugins/mov_reader/mov_reader.cpp b/src/add-ons/media/plugins/mov_reader/mov_reader.cpp index 56adf0cfb0..691d7c8fa3 100644 --- a/src/add-ons/media/plugins/mov_reader/mov_reader.cpp +++ b/src/add-ons/media/plugins/mov_reader/mov_reader.cpp @@ -34,7 +34,7 @@ #include "mov_reader.h" -#define TRACE_MOV_READER +//#define TRACE_MOV_READER #ifdef TRACE_MOV_READER #define TRACE printf #else @@ -56,6 +56,7 @@ struct mov_cookie bool audio; // audio only: + off_t byte_pos; uint32 bytes_per_sec_rate; uint32 bytes_per_sec_scale; @@ -66,7 +67,6 @@ struct mov_cookie uint32 frame_pos; uint32 frames_per_sec_rate; uint32 frames_per_sec_scale; - uint32 frame_size; }; @@ -175,12 +175,11 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) codecID = B_BENDIAN_TO_HOST_INT32(audio_format->compression); - // frame_count is actually sample_count for audio - makes media_player happy but david sad - cookie->frame_count = theFileReader->getFrameCount(cookie->stream) * audio_format->FrameSize; + cookie->frame_count = theFileReader->getAudioFrameCount(cookie->stream); cookie->duration = theFileReader->getAudioDuration(cookie->stream); - cookie->frame_size = audio_format->FrameSize; - + cookie->audio = true; + cookie->byte_pos = 0; if (stream_header->scale && stream_header->rate) { cookie->bytes_per_sec_rate = stream_header->rate * audio_format->SampleSize * audio_format->NoOfChannels / 8; @@ -212,7 +211,6 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) (audio_format->compression == AUDIO_RAW) || (audio_format->compression == AUDIO_TWOS1) || (audio_format->compression == AUDIO_TWOS2)) { - description.family = B_BEOS_FORMAT_FAMILY; description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO; if (B_OK != formats.GetFormatFor(description, format)) { @@ -352,8 +350,7 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) cookie->audio = false; cookie->line_count = theFileReader->MovMainHeader()->height; - cookie->frame_size = 1; - + if (stream_header->scale && stream_header->rate) { cookie->frames_per_sec_rate = stream_header->rate; cookie->frames_per_sec_scale = stream_header->scale; @@ -478,14 +475,14 @@ movReader::Seek(void *cookie, if (seekTo & B_MEDIA_SEEK_TO_TIME) { // frame = (time * rate) / fps / 1000000LL *frame = ((*time * movcookie->frames_per_sec_rate) / (int64)movcookie->frames_per_sec_scale) / 1000000LL; - movcookie->frame_pos = *frame / movcookie->frame_size; + movcookie->frame_pos = *frame; TRACE("Time %Ld to Frame %Ld\n",*time, *frame); } if (seekTo & B_MEDIA_SEEK_TO_FRAME) { // time = frame * 1000000LL * fps / rate *time = (*frame * 1000000LL * (int64)movcookie->frames_per_sec_scale) / movcookie->frames_per_sec_rate; - movcookie->frame_pos = *frame / movcookie->frame_size; + movcookie->frame_pos = *frame; TRACE("Frame %Ld to Time %Ld\n", *frame, *time); } @@ -562,53 +559,47 @@ movReader::GetNextChunk(void *_cookie, { mov_cookie *cookie = (mov_cookie *)_cookie; - int64 start; - uint32 size; - bool keyframe; + int64 start; uint32 size; bool keyframe; - if (!theFileReader->GetNextChunkInfo(cookie->stream, (cookie->frame_pos / cookie->frame_size), &start, &size, &keyframe)) { - TRACE("%s LAST BUFFER : %d (%ld)\n",cookie->audio ? "AUDIO" : "VIDEO", cookie->stream, cookie->frame_pos); + if (!theFileReader->GetNextChunkInfo(cookie->stream, cookie->frame_pos, &start, &size, &keyframe)) return B_LAST_BUFFER_ERROR; - } if (cookie->buffer_size < size) { delete [] cookie->buffer; cookie->buffer_size = (size + 15) & ~15; cookie->buffer = new char [cookie->buffer_size]; } - - mediaHeader->start_time = bigtime_t(double(cookie->frame_pos) * 1000000.0 * double(cookie->frames_per_sec_scale)) / cookie->frames_per_sec_rate; - + if (cookie->audio) { - TRACE("Audio"); + TRACE("Audio stream %d: chunk %ld expected start %lld Size %ld key %d\n",cookie->stream, cookie->frame_pos, start, size, keyframe); mediaHeader->type = B_MEDIA_ENCODED_AUDIO; mediaHeader->u.encoded_audio.buffer_flags = keyframe ? B_MEDIA_KEY_FRAME : 0; + + // This will only work with raw audio I think. + mediaHeader->start_time = (cookie->byte_pos * 1000000LL * cookie->bytes_per_sec_scale) / cookie->bytes_per_sec_rate; + TRACE("Audio - Frames in Chunk %ld / Actual Start Time %Ld using byte_pos\n",theFileReader->getNoFramesInChunk(cookie->stream,cookie->frame_pos),mediaHeader->start_time); + + // We should find the current frame position (ie first frame in chunk) then compute using fps + cookie->frame_pos = theFileReader->getFirstFrameInChunk(cookie->stream,cookie->frame_pos); + mediaHeader->start_time = (cookie->frame_pos * 1000000LL * (int64)cookie->frames_per_sec_scale) / cookie->frames_per_sec_rate; + TRACE("Audio - Frames in Chunk %ld / Actual Start Time %Ld using frame_no %ld\n",theFileReader->getNoFramesInChunk(cookie->stream,cookie->frame_pos),mediaHeader->start_time, cookie->frame_pos); + + cookie->byte_pos += size; } else { - TRACE("Video"); + TRACE("Video stream %d: frame %ld start %lld Size %ld key %d\n",cookie->stream, cookie->frame_pos, start, size, keyframe); + mediaHeader->start_time = (cookie->frame_pos * 1000000LL * (int64)cookie->frames_per_sec_scale) / cookie->frames_per_sec_rate; mediaHeader->type = B_MEDIA_ENCODED_VIDEO; mediaHeader->u.encoded_video.field_flags = keyframe ? B_MEDIA_KEY_FRAME : 0; mediaHeader->u.encoded_video.first_active_line = 0; mediaHeader->u.encoded_video.line_count = cookie->line_count; - mediaHeader->u.encoded_video.field_number = 0; - mediaHeader->u.encoded_video.field_sequence = cookie->frame_pos; } - TRACE(" stream %d: frame %ld start time %.6f file pos %lld Size %ld key frame %s\n",cookie->stream, (cookie->frame_pos / cookie->frame_size), mediaHeader->start_time / 1000000.0, start, size, keyframe ? "true" : "false"); - - cookie->frame_pos += cookie->frame_size; + cookie->frame_pos++; + TRACE("stream %d: start_time %.6f\n", cookie->stream, mediaHeader->start_time / 1000000.0); + *chunkBuffer = cookie->buffer; *chunkSize = size; - - ssize_t bytesRead = theFileReader->Source()->ReadAt(start, cookie->buffer, size); - if (bytesRead < B_OK) - return bytesRead; - - if (bytesRead < (ssize_t)size) { - ERROR("Not enough bytes read asked for %ld got %ld\n", size, bytesRead); - return B_LAST_BUFFER_ERROR; - } - - return B_OK; + return (int)size == theFileReader->Source()->ReadAt(start, cookie->buffer, size) ? B_OK : B_LAST_BUFFER_ERROR; } diff --git a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4FileReader.cpp b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4FileReader.cpp index 0fb7f96359..c74569f457 100644 --- a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4FileReader.cpp +++ b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4FileReader.cpp @@ -69,7 +69,6 @@ MP4FileReader::IsEndOfData(off_t pPosition) if ((aAtomBase) && (aAtomBase->getAtomSize() > 8)) { MDATAtom *aMDATAtom = dynamic_cast(aAtomBase); if (pPosition >= aMDATAtom->getAtomOffset() && pPosition <= aMDATAtom->getEOF()) { -// printf("IsEndOfData %Ld,%Ld,%Ld\n",pPosition,aMDATAtom->getAtomOffset(),aMDATAtom->getEOF()); return false; } } @@ -635,7 +634,7 @@ MP4FileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo, *keyframe = IsKeyFrame(streamIndex, pFrameNo); } -// printf("frame %ld start %Ld, size %ld, eof %s, eod %s\n",pFrameNo,*start,*size, IsEndOfFile(*start + *size) ? "true" : "false", IsEndOfData(*start + *size) ? "true" : "false"); +// printf("start %Ld, size %ld, eof %s, eod %s\n",*start,*size, IsEndOfFile(*start + *size) ? "true" : "false", IsEndOfData(*start + *size) ? "true" : "false"); // TODO need a better method for detecting End of Data Note ChunkSize of 0 seems to be it. if (IsEndOfFile(*start + *size) || IsEndOfData(*start + *size)) { diff --git a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp index 14e08aa917..1acbcc9e51 100644 --- a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp +++ b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp @@ -31,7 +31,7 @@ #include "WavReaderPlugin.h" #include "RawFormats.h" -#define TRACE_WAVE_READER +//#define TRACE_WAVE_READER #ifdef TRACE_WAVE_READER #define TRACE printf #else @@ -137,11 +137,7 @@ WavReader::Sniff(int32 *streamCount) } format_struct format; - wave_format_ex wav_format; format_struct_extensible format_ext; - mpeg1_wav_format mpeg1_format; - mpeg3_wav_format mpeg3_format; - fact_struct fact; // read all chunks and search for "fact", "fmt" (normal or extensible) and "data" @@ -150,9 +146,6 @@ WavReader::Sniff(int32 *streamCount) bool foundFmt = false; bool foundFmtExt = false; bool foundData = false; - bool foundMPEG1 = false; - bool foundMPEG3 = false; - while (pos + sizeof(chunk_struct) <= fFileSize) { chunk_struct chunk; if (sizeof(chunk) != Source()->ReadAt(pos, &chunk, sizeof(chunk))) { @@ -166,43 +159,12 @@ WavReader::Sniff(int32 *streamCount) } switch (UINT32(chunk.fourcc)) { case FOURCC('f','m','t',' '): - // So what do we have a std format structure, a wav_format structure or a extended structure - if (UINT32(chunk.len) >= sizeof(wav_format)) { - // Read both format and wav format - if (sizeof(format) != Source()->ReadAt(pos, &format, sizeof(format))) { - ERROR("WavReader::Sniff: format chunk reading failed\n"); - break; - } - if (sizeof(wav_format) != Source()->ReadAt(pos, &wav_format, sizeof(wav_format))) { - ERROR("WavReader::Sniff: format chunk reading failed\n"); - break; - } - foundFmt = true; - - if (UINT16(wav_format.extra_size) == 12) { - // MPEG3 WAV FORMAT Structure - if (sizeof(mpeg3_format) != Source()->ReadAt(pos, &mpeg3_format, sizeof(mpeg3_format))) { - ERROR("WavReader::Sniff: format chunk reading failed\n"); - break; - } - foundMPEG3 = true; - } - if (UINT16(wav_format.extra_size) == 22) { - // MPEG1 WAV FORMAT Structure - if (sizeof(mpeg1_format) != Source()->ReadAt(pos, &mpeg1_format, sizeof(mpeg1_format))) { - ERROR("WavReader::Sniff: format chunk reading failed\n"); - break; - } - foundMPEG1 = true; - } - - } else if (UINT32(chunk.len) >= sizeof(format)) { + if (UINT32(chunk.len) >= sizeof(format)) { if (sizeof(format) != Source()->ReadAt(pos, &format, sizeof(format))) { ERROR("WavReader::Sniff: format chunk reading failed\n"); break; } foundFmt = true; - if (UINT32(chunk.len) >= sizeof(format_ext) && UINT16(format.format_tag) == 0xfffe) { if (sizeof(format_ext) != Source()->ReadAt(pos, &format_ext, sizeof(format_ext))) { ERROR("WavReader::Sniff: format extensible chunk reading failed\n"); @@ -269,28 +231,6 @@ WavReader::Sniff(int32 *streamCount) if (foundFact) { TRACE(" sample_length %ld\n", UINT32(fact.sample_length)); } - - if (foundMPEG1) { - TRACE(" layer %d\n", UINT16(mpeg1_format.head_layer)); - TRACE(" bitrate %ld\n", UINT32(mpeg1_format.head_bitrate)); - TRACE(" mode %d\n", UINT16(mpeg1_format.head_mode)); - TRACE(" mode ext %d\n", UINT16(mpeg1_format.head_mode_ext)); - TRACE(" emphisis %d\n", UINT16(mpeg1_format.head_emphasis)); - TRACE(" flags %d\n", UINT16(mpeg1_format.head_flags)); - TRACE(" pts low %ld\n", UINT32(mpeg1_format.pts_low)); - TRACE(" pts high %ld\n", UINT32(mpeg1_format.pts_high)); - } - - if (foundMPEG3) { - TRACE(" id %d\n", UINT16(mpeg3_format.id)); - TRACE(" flags %ld\n", UINT32(mpeg3_format.flags)); - TRACE(" block size %d\n", UINT16(mpeg3_format.block_size)); - TRACE(" frames per block %d\n", UINT16(mpeg3_format.frames_per_block)); - TRACE(" codec delay %d\n", UINT16(mpeg3_format.codec_delay)); - fBufferSize = mpeg3_format.block_size; - } else { - fBufferSize = BUFFER_SIZE; - } fMetaData.extra_size = 0; fMetaData.channels = UINT16(format.channels); @@ -358,7 +298,7 @@ WavReader::AllocateCookie(int32 streamNumber, void **cookie) data->position = 0; data->datasize = fDataSize; data->fps = fMetaData.samples_per_sec; - data->buffersize = (fBufferSize / fMetaData.block_align) * fMetaData.block_align; + data->buffersize = (BUFFER_SIZE / fMetaData.block_align) * fMetaData.block_align; data->buffer = malloc(data->buffersize); data->framecount = fFrameCount ? fFrameCount : (8 * fDataSize) / (fMetaData.channels * fMetaData.bits_per_sample); data->raw = fMetaData.format_tag == 0x0001; diff --git a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h index 0152cf3793..6de7cd42b6 100644 --- a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h +++ b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h @@ -71,7 +71,6 @@ private: int64 fFrameCount; int32 fFrameRate; - uint16 fBufferSize; }; diff --git a/src/add-ons/media/plugins/wav_reader/wav.h b/src/add-ons/media/plugins/wav_reader/wav.h index a7dcdbac2a..28b75db802 100644 --- a/src/add-ons/media/plugins/wav_reader/wav.h +++ b/src/add-ons/media/plugins/wav_reader/wav.h @@ -56,40 +56,7 @@ struct wave_format_ex { uint16 block_align; uint16 bits_per_sample; uint16 extra_size; -}; - -struct mpeg3_wav_format { - uint16 format_tag; - uint16 channels; - uint32 samples_per_sec; - uint32 avg_bytes_per_sec; - uint16 block_align; - uint16 bits_per_sample; - uint16 extra_size; - uint16 id; - uint32 flags; - uint16 block_size; - uint16 frames_per_block; - uint16 codec_delay; -}; - -struct mpeg1_wav_format { - uint16 format_tag; - uint16 channels; - uint32 samples_per_sec; - uint32 avg_bytes_per_sec; - uint16 block_align; - uint16 bits_per_sample; - uint16 extra_size; - uint16 head_layer; - uint32 head_bitrate; - uint16 head_mode; - uint16 head_mode_ext; - uint16 head_emphasis; - uint16 head_flags; - uint32 pts_low; - uint32 pts_high; -}; +} _PACKED; struct format_struct_extensible {