summaryrefslogtreecommitdiffstats
path: root/dom/media/AbstractMediaDecoder.h
blob: a0f04ec988e4cceaf26a0b092801ab1a3d808785 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef AbstractMediaDecoder_h_
#define AbstractMediaDecoder_h_

#include "mozilla/Attributes.h"
#include "mozilla/StateMirroring.h"

#include "FrameStatistics.h"
#include "MediaEventSource.h"
#include "MediaInfo.h"
#include "nsISupports.h"
#include "nsDataHashtable.h"
#include "nsThreadUtils.h"

class GMPCrashHelper;

namespace mozilla
{

namespace layers
{
  class ImageContainer;
  class KnowsCompositor;
} // namespace layers
class MediaResource;
class ReentrantMonitor;
class VideoFrameContainer;
class MediaDecoderOwner;
class CDMProxy;

typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags;

static inline bool IsCurrentThread(nsIThread* aThread) {
  return NS_GetCurrentThread() == aThread;
}

/**
 * The AbstractMediaDecoder class describes the public interface for a media decoder
 * and is used by the MediaReader classes.
 */
class AbstractMediaDecoder : public nsIObserver
{
public:
  // A special version of the above for the ogg decoder that is allowed to be
  // called cross-thread.
  virtual bool IsOggDecoderShutdown() { return false; }

  // Get the current MediaResource being used. Its URI will be returned
  // by currentSrc. Returns what was passed to Load(), if Load() has been called.
  virtual MediaResource* GetResource() const = 0;

  // Increments the parsed, decoded and dropped frame counters by the passed in
  // counts.
  // Can be called on any thread.
  virtual void NotifyDecodedFrames(const FrameStatisticsData& aStats) = 0;

  virtual AbstractCanonical<media::NullableTimeUnit>* CanonicalDurationOrNull() { return nullptr; };

  // Return an event that will be notified when data arrives in MediaResource.
  // MediaDecoderReader will register with this event to receive notifications
  // in order to update buffer ranges.
  // Return null if this decoder doesn't support the event.
  virtual MediaEventSource<void>* DataArrivedEvent()
  {
    return nullptr;
  }

  // Returns an event that will be notified when the owning document changes state
  // and we might have a new compositor. If this new compositor requires us to
  // recreate our decoders, then we expect the existing decoderis to return an
  // error independently of this.
  virtual MediaEventSource<RefPtr<layers::KnowsCompositor>>* CompositorUpdatedEvent()
  {
    return nullptr;
  }

  // Notify the media decoder that a decryption key is required before emitting
  // further output. This only needs to be overridden for decoders that expect
  // encryption, such as the MediaSource decoder.
  virtual void NotifyWaitingForKey() {}

  // Return an event that will be notified when a decoder is waiting for a
  // decryption key before it can return more output.
  virtual MediaEventSource<void>* WaitingForKeyEvent()
  {
    return nullptr;
  }

protected:
  virtual void UpdateEstimatedMediaDuration(int64_t aDuration) {};
public:
  void DispatchUpdateEstimatedMediaDuration(int64_t aDuration)
  {
    NS_DispatchToMainThread(NewRunnableMethod<int64_t>(this,
                                                       &AbstractMediaDecoder::UpdateEstimatedMediaDuration,
                                                       aDuration));
  }

  virtual VideoFrameContainer* GetVideoFrameContainer() = 0;
  virtual mozilla::layers::ImageContainer* GetImageContainer() = 0;

  // Returns the owner of this decoder or null when the decoder is shutting
  // down. The owner should only be used on the main thread.
  virtual MediaDecoderOwner* GetOwner() const = 0;

  // Set by Reader if the current audio track can be offloaded
  virtual void SetPlatformCanOffloadAudio(bool aCanOffloadAudio) {}

  virtual already_AddRefed<GMPCrashHelper> GetCrashHelper() { return nullptr; }

  // Stack based class to assist in notifying the frame statistics of
  // parsed and decoded frames. Use inside video demux & decode functions
  // to ensure all parsed and decoded frames are reported on all return paths.
  class AutoNotifyDecoded {
  public:
    explicit AutoNotifyDecoded(AbstractMediaDecoder* aDecoder)
      : mDecoder(aDecoder)
    {}
    ~AutoNotifyDecoded() {
      if (mDecoder) {
        mDecoder->NotifyDecodedFrames(mStats);
      }
    }

    FrameStatisticsData mStats;

  private:
    AbstractMediaDecoder* mDecoder;
  };

  // Classes directly inheriting from AbstractMediaDecoder do not support
  // Observe and it should never be called directly.
  NS_IMETHOD Observe(nsISupports *aSubject, const char * aTopic, const char16_t * aData) override
  { MOZ_CRASH("Forbidden method"); return NS_OK; }
};

} // namespace mozilla

#endif