Line data Source code
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 :
7 : #ifndef MP4_STREAM_H_
8 : #define MP4_STREAM_H_
9 :
10 : #include "mp4_demuxer/Stream.h"
11 :
12 : #include "MediaResource.h"
13 :
14 : #include "mozilla/Maybe.h"
15 : #include "mozilla/Monitor.h"
16 : #include "mozilla/UniquePtrExtensions.h"
17 :
18 : namespace mozilla {
19 :
20 : class Monitor;
21 :
22 : class MP4Stream : public mp4_demuxer::Stream {
23 : public:
24 : explicit MP4Stream(MediaResource* aResource);
25 : virtual ~MP4Stream();
26 : bool BlockingReadIntoCache(int64_t aOffset, size_t aCount, Monitor* aToUnlock);
27 : bool ReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
28 : size_t* aBytesRead) override;
29 : bool CachedReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
30 : size_t* aBytesRead) override;
31 : bool Length(int64_t* aSize) override;
32 :
33 : struct ReadRecord {
34 0 : ReadRecord(int64_t aOffset, size_t aCount) : mOffset(aOffset), mCount(aCount) {}
35 : bool operator==(const ReadRecord& aOther) { return mOffset == aOther.mOffset && mCount == aOther.mCount; }
36 : int64_t mOffset;
37 : size_t mCount;
38 : };
39 : bool LastReadFailed(ReadRecord* aOut)
40 : {
41 : if (mFailedRead.isSome()) {
42 : *aOut = mFailedRead.ref();
43 : return true;
44 : }
45 :
46 : return false;
47 : }
48 :
49 : void ClearFailedRead() { mFailedRead.reset(); }
50 :
51 : void Pin()
52 : {
53 : mResource.GetResource()->Pin();
54 : ++mPinCount;
55 : }
56 :
57 : void Unpin()
58 : {
59 : mResource.GetResource()->Unpin();
60 : MOZ_ASSERT(mPinCount);
61 : --mPinCount;
62 : if (mPinCount == 0) {
63 : mCache.Clear();
64 : }
65 : }
66 :
67 : private:
68 : MediaResourceIndex mResource;
69 : Maybe<ReadRecord> mFailedRead;
70 : uint32_t mPinCount;
71 :
72 0 : struct CacheBlock {
73 0 : CacheBlock(int64_t aOffset, size_t aCount)
74 0 : : mOffset(aOffset), mCount(aCount), mBuffer(nullptr) {}
75 : int64_t mOffset;
76 : size_t mCount;
77 :
78 0 : CacheBlock(CacheBlock&& aOther)
79 0 : : mOffset(aOther.mOffset)
80 0 : , mCount(aOther.mCount)
81 0 : , mBuffer(Move(aOther.mBuffer))
82 0 : {}
83 :
84 0 : bool Init()
85 : {
86 0 : mBuffer = MakeUniqueFallible<char[]>(mCount);
87 0 : return !!mBuffer;
88 : }
89 :
90 0 : char* Buffer()
91 : {
92 0 : MOZ_ASSERT(mBuffer.get());
93 0 : return mBuffer.get();
94 : }
95 :
96 : private:
97 : CacheBlock(const CacheBlock&) = delete;
98 : CacheBlock& operator=(const CacheBlock&) = delete;
99 :
100 : UniquePtr<char[]> mBuffer;
101 : };
102 : nsTArray<CacheBlock> mCache;
103 : };
104 :
105 : } // namespace mozilla
106 :
107 : #endif
|