blob: ffa5ab16a26474b895b5d1175f008076122ed22f [file] [log] [blame]
// 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.
#include <stdint.h>
#include <list>
#include <map>
#include <memory>
#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 {
explicit Mp2tStreamParser(bool sbr_in_mimetype);
~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;
struct BufferQueueWithConfig {
BufferQueueWithConfig(bool is_cfg_sent,
const AudioDecoderConfig& audio_cfg,
const VideoDecoderConfig& video_cfg);
BufferQueueWithConfig(const BufferQueueWithConfig& other);
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);
bool ShouldForceEncryptedParser();
std::unique_ptr<EsParser> CreateEncryptedH264Parser(int pes_pid);
std::unique_ptr<EsParser> CreateEncryptedAacParser(int pes_pid);
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 RegisterEncryptionMode(EncryptionMode mode);
// 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(); }
// 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_;
// 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_;
EncryptionMode initial_encryption_mode_ = EncryptionMode::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_;
} // namespace mp2t
} // namespace media