chromium/media/filters/chunk_demuxer.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/filters/chunk_demuxer.h"

#include <algorithm>
#include <limits>
#include <memory>
#include <utility>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/not_fatal_until.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/bind_post_task.h"
#include "base/trace_event/trace_event.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/demuxer.h"
#include "media/base/media_tracks.h"
#include "media/base/mime_util.h"
#include "media/base/stream_parser.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_codecs.h"
#include "media/base/video_decoder_config.h"
#include "media/filters/frame_processor.h"
#include "media/filters/source_buffer_stream.h"
#include "media/filters/stream_parser_factory.h"

namespace {

// Helper to attempt construction of a StreamParser specific to |content_type|
// and |codecs|.
// TODO(wolenetz): Consider relocating this to StreamParserFactory in
// conjunction with updating StreamParserFactory's isTypeSupported() to also
// parse codecs, rather than require preparsed vector.
std::unique_ptr<media::StreamParser> CreateParserForTypeAndCodecs(
    const std::string& content_type,
    const std::string& codecs,
    media::MediaLog* media_log) {}

// Helper to calculate the expected codecs parsed from initialization segments
// for a few mime types that have an implicit codec.
std::string ExpectedCodecs(const std::string& content_type,
                           const std::string& codecs) {}

}  // namespace

namespace media {

ChunkDemuxerStream::ChunkDemuxerStream(Type type, MediaTrack::Id media_track_id)
    :{}

void ChunkDemuxerStream::StartReturningData() {}

void ChunkDemuxerStream::AbortReads() {}

void ChunkDemuxerStream::CompletePendingReadIfPossible() {}

void ChunkDemuxerStream::Shutdown() {}

bool ChunkDemuxerStream::IsSeekWaitingForData() const {}

void ChunkDemuxerStream::Seek(base::TimeDelta time) {}

bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) {}

void ChunkDemuxerStream::Remove(base::TimeDelta start,
                                base::TimeDelta end,
                                base::TimeDelta duration) {}

bool ChunkDemuxerStream::EvictCodedFrames(base::TimeDelta media_time,
                                          size_t newDataSize) {}

void ChunkDemuxerStream::OnMemoryPressure(
    base::TimeDelta media_time,
    base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level,
    bool force_instant_gc) {}

void ChunkDemuxerStream::OnSetDuration(base::TimeDelta duration) {}

Ranges<base::TimeDelta> ChunkDemuxerStream::GetBufferedRanges(
    base::TimeDelta duration) const {}

base::TimeDelta ChunkDemuxerStream::GetLowestPresentationTimestamp() const {}

base::TimeDelta ChunkDemuxerStream::GetHighestPresentationTimestamp() const {}

base::TimeDelta ChunkDemuxerStream::GetBufferedDuration() const {}

size_t ChunkDemuxerStream::GetMemoryUsage() const {}

void ChunkDemuxerStream::OnStartOfCodedFrameGroup(DecodeTimestamp start_dts,
                                                  base::TimeDelta start_pts) {}

bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config,
                                           bool allow_codec_change,
                                           MediaLog* media_log) {}

bool ChunkDemuxerStream::UpdateVideoConfig(const VideoDecoderConfig& config,
                                           bool allow_codec_change,
                                           MediaLog* media_log) {}

void ChunkDemuxerStream::MarkEndOfStream() {}

void ChunkDemuxerStream::UnmarkEndOfStream() {}

// DemuxerStream methods.
void ChunkDemuxerStream::Read(uint32_t count, ReadCB read_cb) {}

DemuxerStream::Type ChunkDemuxerStream::type() const {}

StreamLiveness ChunkDemuxerStream::liveness() const {}

AudioDecoderConfig ChunkDemuxerStream::audio_decoder_config() {}

VideoDecoderConfig ChunkDemuxerStream::video_decoder_config() {}

bool ChunkDemuxerStream::SupportsConfigChanges() {}

bool ChunkDemuxerStream::IsEnabled() const {}

void ChunkDemuxerStream::SetEnabled(bool enabled, base::TimeDelta timestamp) {}

void ChunkDemuxerStream::SetStreamMemoryLimit(size_t memory_limit) {}

void ChunkDemuxerStream::SetLiveness(StreamLiveness liveness) {}

void ChunkDemuxerStream::ChangeState_Locked(State state) {}

ChunkDemuxerStream::~ChunkDemuxerStream() = default;

void ChunkDemuxerStream::CompletePendingReadIfPossible_Locked() {}

std::pair<SourceBufferStreamStatus, DemuxerStream::DecoderBufferVector>
ChunkDemuxerStream::GetPendingBuffers_Locked() {}

ChunkDemuxer::ChunkDemuxer(
    base::OnceClosure open_cb,
    base::RepeatingClosure progress_cb,
    EncryptedMediaInitDataCB encrypted_media_init_data_cb,
    MediaLog* media_log)
    :{}

std::string ChunkDemuxer::GetDisplayName() const {}

DemuxerType ChunkDemuxer::GetDemuxerType() const {}

void ChunkDemuxer::Initialize(DemuxerHost* host,
                              PipelineStatusCallback init_cb) {}

void ChunkDemuxer::Stop() {}

void ChunkDemuxer::Seek(base::TimeDelta time, PipelineStatusCallback cb) {}

bool ChunkDemuxer::IsSeekable() const {}

// Demuxer implementation.
base::Time ChunkDemuxer::GetTimelineOffset() const {}

std::vector<DemuxerStream*> ChunkDemuxer::GetAllStreams() {}

base::TimeDelta ChunkDemuxer::GetStartTime() const {}

int64_t ChunkDemuxer::GetMemoryUsage() const {}

std::optional<container_names::MediaContainerName>
ChunkDemuxer::GetContainerForMetrics() const {}

void ChunkDemuxer::AbortPendingReads() {}

void ChunkDemuxer::StartWaitingForSeek(base::TimeDelta seek_time) {}

void ChunkDemuxer::CancelPendingSeek(base::TimeDelta seek_time) {}

ChunkDemuxer::Status ChunkDemuxer::AddId(
    const std::string& id,
    std::unique_ptr<AudioDecoderConfig> audio_config) {}

ChunkDemuxer::Status ChunkDemuxer::AddId(
    const std::string& id,
    std::unique_ptr<VideoDecoderConfig> video_config) {}

ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id,
                                         const std::string& content_type,
                                         const std::string& codecs) {}

#if BUILDFLAG(ENABLE_HLS_DEMUXER)
ChunkDemuxer::Status ChunkDemuxer::AddAutoDetectedCodecsId(
    const std::string& id,
    RelaxedParserSupportedType mime_type) {
  DVLOG(1) << __func__ << " id=" << id
           << " content_type=" << static_cast<int>(mime_type);
  base::AutoLock auto_lock(lock_);
  if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) ||
      IsValidId_Locked(id)) {
    return kReachedIdLimit;
  }

  CHECK(init_cb_);

  std::unique_ptr<media::StreamParser> stream_parser =
      StreamParserFactory::CreateRelaxedParser(mime_type);
  if (!stream_parser) {
    DVLOG(1) << __func__ << " failed: unsupported mime type for relaxed parser";
    return kNotSupported;
  }

  return AddIdInternal(id, std::move(stream_parser), std::nullopt);
}
#endif

ChunkDemuxer::Status ChunkDemuxer::AddIdInternal(
    const std::string& id,
    std::unique_ptr<media::StreamParser> stream_parser,
    std::optional<std::string_view> expected_codecs) {}

void ChunkDemuxer::SetTracksWatcher(const std::string& id,
                                    MediaTracksUpdatedCB tracks_updated_cb) {}

void ChunkDemuxer::SetParseWarningCallback(
    const std::string& id,
    SourceBufferParseWarningCB parse_warning_cb) {}

void ChunkDemuxer::RemoveId(const std::string& id) {}

Ranges<base::TimeDelta> ChunkDemuxer::GetBufferedRanges(
    const std::string& id) const {}

base::TimeDelta ChunkDemuxer::GetLowestPresentationTimestamp(
    const std::string& id) const {}

base::TimeDelta ChunkDemuxer::GetHighestPresentationTimestamp(
    const std::string& id) const {}

void ChunkDemuxer::FindAndEnableProperTracks(
    const std::vector<MediaTrack::Id>& track_ids,
    base::TimeDelta curr_time,
    DemuxerStream::Type track_type,
    TrackChangeCB change_completed_cb) {}

void ChunkDemuxer::OnEnabledAudioTracksChanged(
    const std::vector<MediaTrack::Id>& track_ids,
    base::TimeDelta curr_time,
    TrackChangeCB change_completed_cb) {}

void ChunkDemuxer::OnSelectedVideoTrackChanged(
    const std::vector<MediaTrack::Id>& track_ids,
    base::TimeDelta curr_time,
    TrackChangeCB change_completed_cb) {}

void ChunkDemuxer::DisableCanChangeType() {}

void ChunkDemuxer::OnMemoryPressure(
    base::TimeDelta currentMediaTime,
    base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level,
    bool force_instant_gc) {}

bool ChunkDemuxer::EvictCodedFrames(const std::string& id,
                                    base::TimeDelta currentMediaTime,
                                    size_t newDataSize) {}

bool ChunkDemuxer::AppendToParseBuffer(const std::string& id,
                                       base::span<const uint8_t> data) {}

StreamParser::ParseStatus ChunkDemuxer::RunSegmentParserLoop(
    const std::string& id,
    base::TimeDelta append_window_start,
    base::TimeDelta append_window_end,
    base::TimeDelta* timestamp_offset) {}

bool ChunkDemuxer::AppendChunks(
    const std::string& id,
    std::unique_ptr<StreamParser::BufferQueue> buffer_queue,
    base::TimeDelta append_window_start,
    base::TimeDelta append_window_end,
    base::TimeDelta* timestamp_offset) {}

void ChunkDemuxer::ResetParserState(const std::string& id,
                                    base::TimeDelta append_window_start,
                                    base::TimeDelta append_window_end,
                                    base::TimeDelta* timestamp_offset) {}

void ChunkDemuxer::Remove(const std::string& id,
                          base::TimeDelta start,
                          base::TimeDelta end) {}

bool ChunkDemuxer::CanChangeType(const std::string& id,
                                 const std::string& content_type,
                                 const std::string& codecs) {}

void ChunkDemuxer::ChangeType(const std::string& id,
                              const std::string& content_type,
                              const std::string& codecs) {}

double ChunkDemuxer::GetDuration() {}

double ChunkDemuxer::GetDuration_Locked() {}

void ChunkDemuxer::SetDuration(double duration) {}

bool ChunkDemuxer::IsParsingMediaSegment(const std::string& id) {}

bool ChunkDemuxer::GetGenerateTimestampsFlag(const std::string& id) {}

void ChunkDemuxer::SetSequenceMode(const std::string& id,
                                   bool sequence_mode) {}

void ChunkDemuxer::SetGroupStartTimestampIfInSequenceMode(
    const std::string& id,
    base::TimeDelta timestamp_offset) {}


void ChunkDemuxer::MarkEndOfStream(PipelineStatus status) {}

void ChunkDemuxer::UnmarkEndOfStream() {}

void ChunkDemuxer::Shutdown() {}

void ChunkDemuxer::SetMemoryLimitsForTest(DemuxerStream::Type type,
                                          size_t memory_limit) {}

void ChunkDemuxer::ChangeState_Locked(State new_state) {}

ChunkDemuxer::~ChunkDemuxer() {}

void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {}

bool ChunkDemuxer::IsSeekWaitingForData_Locked() const {}

void ChunkDemuxer::OnSourceInitDone(
    const std::string& source_id,
    const StreamParser::InitParameters& params) {}

// static
MediaTrack::Id ChunkDemuxer::GenerateMediaTrackId() {}

ChunkDemuxerStream* ChunkDemuxer::CreateDemuxerStream(
    const std::string& source_id,
    DemuxerStream::Type type) {}

bool ChunkDemuxer::IsValidId_Locked(const std::string& source_id) const {}

void ChunkDemuxer::UpdateDuration(base::TimeDelta new_duration) {}

void ChunkDemuxer::IncreaseDurationIfNecessary(base::TimeDelta new_duration) {}

void ChunkDemuxer::DecreaseDurationIfNecessary() {}

Ranges<base::TimeDelta> ChunkDemuxer::GetBufferedRanges() const {}

Ranges<base::TimeDelta> ChunkDemuxer::GetBufferedRanges_Locked() const {}

void ChunkDemuxer::StartReturningData() {}

void ChunkDemuxer::AbortPendingReads_Locked() {}

void ChunkDemuxer::SeekAllSources(base::TimeDelta seek_time) {}

void ChunkDemuxer::CompletePendingReadsIfPossible() {}

void ChunkDemuxer::ShutdownAllStreams() {}

void ChunkDemuxer::RunInitCB_Locked(PipelineStatus status) {}

void ChunkDemuxer::RunSeekCB_Locked(PipelineStatus status) {}

}  // namespace media