|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 #if !defined(WaveReader_h_) |
|
7 #define WaveReader_h_ |
|
8 |
|
9 #include "MediaDecoderReader.h" |
|
10 #include "mozilla/dom/HTMLMediaElement.h" |
|
11 |
|
12 namespace mozilla { |
|
13 namespace dom { |
|
14 class TimeRanges; |
|
15 } |
|
16 } |
|
17 |
|
18 namespace mozilla { |
|
19 |
|
20 class WaveReader : public MediaDecoderReader |
|
21 { |
|
22 public: |
|
23 WaveReader(AbstractMediaDecoder* aDecoder); |
|
24 ~WaveReader(); |
|
25 |
|
26 virtual nsresult Init(MediaDecoderReader* aCloneDonor); |
|
27 virtual bool DecodeAudioData(); |
|
28 virtual bool DecodeVideoFrame(bool &aKeyframeSkip, |
|
29 int64_t aTimeThreshold); |
|
30 |
|
31 virtual bool HasAudio() |
|
32 { |
|
33 return true; |
|
34 } |
|
35 |
|
36 virtual bool HasVideo() |
|
37 { |
|
38 return false; |
|
39 } |
|
40 |
|
41 virtual nsresult ReadMetadata(MediaInfo* aInfo, |
|
42 MetadataTags** aTags); |
|
43 virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime); |
|
44 virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime); |
|
45 |
|
46 // To seek in a buffered range, we just have to seek the stream. |
|
47 virtual bool IsSeekableInBufferedRanges() { |
|
48 return true; |
|
49 } |
|
50 |
|
51 private: |
|
52 bool ReadAll(char* aBuf, int64_t aSize, int64_t* aBytesRead = nullptr); |
|
53 bool LoadRIFFChunk(); |
|
54 bool GetNextChunk(uint32_t* aChunk, uint32_t* aChunkSize); |
|
55 bool LoadFormatChunk(uint32_t aChunkSize); |
|
56 bool FindDataOffset(uint32_t aChunkSize); |
|
57 bool LoadListChunk(uint32_t aChunkSize, nsAutoPtr<dom::HTMLMediaElement::MetadataTags> &aTags); |
|
58 bool LoadAllChunks(nsAutoPtr<dom::HTMLMediaElement::MetadataTags> &aTags); |
|
59 |
|
60 // Returns the number of seconds that aBytes represents based on the |
|
61 // current audio parameters. e.g. 176400 bytes is 1 second at 16-bit |
|
62 // stereo 44.1kHz. The time is rounded to the nearest microsecond. |
|
63 double BytesToTime(int64_t aBytes) const; |
|
64 |
|
65 // Returns the number of bytes that aTime represents based on the current |
|
66 // audio parameters. e.g. 1 second is 176400 bytes at 16-bit stereo |
|
67 // 44.1kHz. |
|
68 int64_t TimeToBytes(double aTime) const; |
|
69 |
|
70 // Rounds aBytes down to the nearest complete audio frame. Assumes |
|
71 // beginning of byte range is already frame aligned by caller. |
|
72 int64_t RoundDownToFrame(int64_t aBytes) const; |
|
73 int64_t GetDataLength(); |
|
74 int64_t GetPosition(); |
|
75 |
|
76 /* |
|
77 Metadata extracted from the WAVE header. Used to initialize the audio |
|
78 stream, and for byte<->time domain conversions. |
|
79 */ |
|
80 |
|
81 // Number of samples per second. Limited to range [100, 96000] in LoadFormatChunk. |
|
82 uint32_t mSampleRate; |
|
83 |
|
84 // Number of channels. Limited to range [1, 2] in LoadFormatChunk. |
|
85 uint32_t mChannels; |
|
86 |
|
87 // Size of a single audio frame, which includes a sample for each channel |
|
88 // (interleaved). |
|
89 uint32_t mFrameSize; |
|
90 |
|
91 // The sample format of the PCM data. AudioStream::SampleFormat doesn't |
|
92 // support U8. |
|
93 enum { |
|
94 FORMAT_U8, |
|
95 FORMAT_S16 |
|
96 } mSampleFormat; |
|
97 |
|
98 // Size of PCM data stored in the WAVE as reported by the data chunk in |
|
99 // the media. |
|
100 int64_t mWaveLength; |
|
101 |
|
102 // Start offset of the PCM data in the media stream. Extends mWaveLength |
|
103 // bytes. |
|
104 int64_t mWavePCMOffset; |
|
105 }; |
|
106 |
|
107 } // namespace mozilla |
|
108 |
|
109 #endif |