summaryrefslogtreecommitdiff
path: root/chromium/media/formats/mp2t/mp2t_stream_parser.h
blob: 84a8cb00d44d2969a7db6d1ca816be3f14fd6d4d (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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_FORMATS_MP2T_MP2T_STREAM_PARSER_H_
#define MEDIA_FORMATS_MP2T_MP2T_STREAM_PARSER_H_

#include <stdint.h>

#include <list>
#include <map>
#include <memory>
#include <set>

#include "base/containers/span.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/byte_queue.h"
#include "media/base/decrypt_config.h"
#include "media/base/media_export.h"
#include "media/base/stream_parser.h"
#include "media/base/video_decoder_config.h"
#include "media/formats/mp2t/timestamp_unroller.h"
#include "media/media_buildflags.h"

namespace media {

class StreamParserBuffer;

namespace mp2t {

class Descriptors;
class EsParser;
class PidState;

class MEDIA_EXPORT Mp2tStreamParser : public StreamParser {
 public:
  explicit Mp2tStreamParser(base::span<const std::string> allowed_codecs,
                            bool sbr_in_mimetype);

  Mp2tStreamParser(const Mp2tStreamParser&) = delete;
  Mp2tStreamParser& operator=(const Mp2tStreamParser&) = delete;

  ~Mp2tStreamParser() override;

  // StreamParser implementation.
  void Init(InitCB init_cb,
            const NewConfigCB& config_cb,
            const NewBuffersCB& new_buffers_cb,
            bool ignore_text_tracks,
            const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
            const NewMediaSegmentCB& new_segment_cb,
            const EndMediaSegmentCB& end_of_segment_cb,
            MediaLog* media_log) override;
  void Flush() override;
  bool GetGenerateTimestampsFlag() const override;
  bool Parse(const uint8_t* buf, int size) override;

 private:
  struct BufferQueueWithConfig {
    BufferQueueWithConfig(bool is_cfg_sent,
                          const AudioDecoderConfig& audio_cfg,
                          const VideoDecoderConfig& video_cfg);
    BufferQueueWithConfig(const BufferQueueWithConfig& other);
    ~BufferQueueWithConfig();

    bool is_config_sent;
    AudioDecoderConfig audio_config;
    StreamParser::BufferQueue audio_queue;
    VideoDecoderConfig video_config;
    StreamParser::BufferQueue video_queue;
  };

  // Callback invoked to register a Program Map Table.
  // Note: Does nothing if the PID is already registered.
  void RegisterPmt(int program_number, int pmt_pid);

  // Callback invoked to register a PES pid.
  // Possible values for |stream_type| are defined in:
  // ISO-13818.1 / ITU H.222 Table 2.34 "Stream type assignments".
  // |pes_pid| is part of the Program Map Table.
  // Some stream types are qualified by additional |descriptors|.
  void RegisterPes(int pes_pid,
                   int stream_type,
                   const Descriptors& descriptors);

  // Since the StreamParser interface allows only one audio & video streams,
  // an automatic PID filtering should be applied to select the audio & video
  // streams.
  void UpdatePidFilter();

  // Callback invoked each time the audio/video decoder configuration is
  // changed.
  void OnVideoConfigChanged(int pes_pid,
                            const VideoDecoderConfig& video_decoder_config);
  void OnAudioConfigChanged(int pes_pid,
                            const AudioDecoderConfig& audio_decoder_config);

  // Invoke the initialization callback if needed.
  bool FinishInitializationIfNeeded();

  // Callback invoked by the ES stream parser
  // to emit a new audio/video access unit.
  void OnEmitAudioBuffer(
      int pes_pid,
      scoped_refptr<StreamParserBuffer> stream_parser_buffer);
  void OnEmitVideoBuffer(
      int pes_pid,
      scoped_refptr<StreamParserBuffer> stream_parser_buffer);
  bool EmitRemainingBuffers();

  std::unique_ptr<EsParser> CreateH264Parser(int pes_pid);
  std::unique_ptr<EsParser> CreateAacParser(int pes_pid);
  std::unique_ptr<EsParser> CreateMpeg1AudioParser(int pes_pid);

#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
  bool ShouldForceEncryptedParser();
  std::unique_ptr<EsParser> CreateEncryptedH264Parser(int pes_pid,
                                                      bool emit_clear_buffers);
  std::unique_ptr<EsParser> CreateEncryptedAacParser(int pes_pid,
                                                     bool emit_clear_buffers);

  std::unique_ptr<PidState> MakeCatPidState();
  void UnregisterCat();

  // Register the PIDs for the Cenc packets (CENC-ECM and CENC-PSSH).
  void RegisterCencPids(int ca_pid, int pssh_pid);
  void UnregisterCencPids();

  // Register a default encryption mode to be used for decoder configs. This
  // value is only used in the absence of explicit encryption metadata, as might
  // be the case during an unencrypted portion of a live stream.
  void RegisterEncryptionScheme(EncryptionScheme scheme);

  // Register the new KeyID and IV (parsed from CENC-ECM).
  void RegisterNewKeyIdAndIv(const std::string& key_id, const std::string& iv);

  // Register the PSSH (parsed from CENC-PSSH).
  void RegisterPsshBoxes(const std::vector<uint8_t>& init_data);

  const DecryptConfig* GetDecryptConfig() { return decrypt_config_.get(); }
#endif

  // List of callbacks.
  InitCB init_cb_;
  NewConfigCB config_cb_;
  NewBuffersCB new_buffers_cb_;
  EncryptedMediaInitDataCB encrypted_media_init_data_cb_;
  NewMediaSegmentCB new_segment_cb_;
  EndMediaSegmentCB end_of_segment_cb_;
  MediaLog* media_log_;

  // List of allowed stream types for this parser.
  std::set<int> allowed_stream_types_;

  // True when AAC SBR extension is signalled in the mimetype
  // (mp4a.40.5 in the codecs parameter).
  bool sbr_in_mimetype_;

  // Bytes of the TS stream.
  ByteQueue ts_byte_queue_;

  // List of PIDs and their state.
  std::map<int, std::unique_ptr<PidState>> pids_;

  // Selected audio and video PIDs.
  int selected_audio_pid_;
  int selected_video_pid_;

  // Pending audio & video buffers.
  std::list<BufferQueueWithConfig> buffer_queue_chain_;

  // Whether |init_cb_| has been invoked.
  bool is_initialized_;

  // Indicate whether a segment was started.
  bool segment_started_;

  // Timestamp unroller.
  // Timestamps in PES packets must be unrolled using the same offset.
  // So the unroller is global between PES pids.
  TimestampUnroller timestamp_unroller_;

#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
  EncryptionScheme initial_encryption_scheme_ = EncryptionScheme::kUnencrypted;

  // TODO(jrummell): Rather than store the key_id and iv in a DecryptConfig,
  // provide a better way to access the last values seen in a ECM packet.
  std::unique_ptr<DecryptConfig> decrypt_config_;
#endif
};

}  // namespace mp2t
}  // namespace media

#endif  // MEDIA_FORMATS_MP2T_MP2T_STREAM_PARSER_H_