chromium/media/filters/ffmpeg_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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "media/filters/ffmpeg_demuxer.h"

#include <algorithm>
#include <memory>
#include <set>
#include <string_view>
#include <utility>

#include "base/base64.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "media/base/decrypt_config.h"
#include "media/base/demuxer.h"
#include "media/base/demuxer_memory_limit.h"
#include "media/base/limits.h"
#include "media/base/media_switches.h"
#include "media/base/media_tracks.h"
#include "media/base/media_types.h"
#include "media/base/sample_rates.h"
#include "media/base/supported_types.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_codecs.h"
#include "media/base/webvtt_util.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_aac_bitstream_converter.h"
#include "media/filters/ffmpeg_bitstream_converter.h"
#include "media/filters/ffmpeg_glue.h"
#include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h"
#include "media/formats/mpeg/mpeg1_audio_stream_parser.h"
#include "media/formats/webm/webm_crypto_helpers.h"
#include "media/media_buildflags.h"
#include "third_party/ffmpeg/ffmpeg_features.h"
#include "third_party/ffmpeg/libavcodec/packet.h"

#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
#include "media/filters/ffmpeg_h265_to_annex_b_bitstream_converter.h"
#endif

namespace media {

namespace {

constexpr int64_t kInvalidPTSMarker =;

void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {}

int AVSeekFrame(AVFormatContext* s, int stream_index, int64_t timestamp) {}

bool IsStreamEnabled(container_names::MediaContainerName container,
                     AVStream* stream) {}

}  // namespace

static base::Time ExtractTimelineOffset(
    container_names::MediaContainerName container,
    const AVFormatContext* format_context) {}

static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate) {}

static base::TimeDelta ExtractStartTime(AVStream* stream) {}

// Record audio decoder config UMA stats corresponding to a src= playback.
static void RecordAudioCodecStats(const AudioDecoderConfig& audio_config) {}

// Record video decoder config UMA stats corresponding to a src= playback.
static void RecordVideoCodecStats(container_names::MediaContainerName container,
                                  const VideoDecoderConfig& video_config,
                                  AVColorRange color_range,
                                  MediaLog* media_log) {}

static const char kCodecNone[] =;

static const char* GetCodecName(enum AVCodecID id) {}

static base::Value GetTimeValue(base::TimeDelta value) {}

template <>
struct MediaLogPropertyTypeSupport<MediaLogProperty::kMaxDuration,
                                   base::TimeDelta> {};

template <>
struct MediaLogPropertyTypeSupport<MediaLogProperty::kStartTime,
                                   base::TimeDelta> {};

static int ReadFrameAndDiscardEmpty(AVFormatContext* context,
                                    AVPacket* packet) {}

std::unique_ptr<FFmpegDemuxerStream> FFmpegDemuxerStream::Create(
    FFmpegDemuxer* demuxer,
    AVStream* stream,
    MediaLog* media_log) {}

static void UnmarkEndOfStreamAndClearError(AVFormatContext* format_context) {}

//
// FFmpegDemuxerStream
//
FFmpegDemuxerStream::FFmpegDemuxerStream(
    FFmpegDemuxer* demuxer,
    AVStream* stream,
    std::unique_ptr<AudioDecoderConfig> audio_config,
    std::unique_ptr<VideoDecoderConfig> video_config,
    MediaLog* media_log)
    :{}

FFmpegDemuxerStream::~FFmpegDemuxerStream() {}

void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {}

void FFmpegDemuxerStream::SetEndOfStream() {}

void FFmpegDemuxerStream::FlushBuffers(bool preserve_packet_position) {}

void FFmpegDemuxerStream::Abort() {}

void FFmpegDemuxerStream::Stop() {}

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

StreamLiveness FFmpegDemuxerStream::liveness() const {}

void FFmpegDemuxerStream::Read(uint32_t count, ReadCB read_cb) {}

void FFmpegDemuxerStream::EnableBitstreamConverter() {}

void FFmpegDemuxerStream::ResetBitstreamConverter() {}

void FFmpegDemuxerStream::InitBitstreamConverter() {}

bool FFmpegDemuxerStream::SupportsConfigChanges() {}

AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {}

VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {}

bool FFmpegDemuxerStream::IsEnabled() const {}

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

void FFmpegDemuxerStream::SetLiveness(StreamLiveness liveness) {}

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

void FFmpegDemuxerStream::SatisfyPendingRead() {}

bool FFmpegDemuxerStream::HasAvailableCapacity() {}

size_t FFmpegDemuxerStream::MemoryUsage() const {}

std::string FFmpegDemuxerStream::GetMetadata(const char* key) const {}

// static
base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
    const AVRational& time_base,
    int64_t timestamp) {}

//
// FFmpegDemuxer
//
FFmpegDemuxer::FFmpegDemuxer(
    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
    DataSource* data_source,
    const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
    MediaTracksUpdatedCB media_tracks_updated_cb,
    MediaLog* media_log,
    bool is_local_file)
    :{}

FFmpegDemuxer::~FFmpegDemuxer() {}

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

DemuxerType FFmpegDemuxer::GetDemuxerType() const {}

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

void FFmpegDemuxer::AbortPendingReads() {}

void FFmpegDemuxer::Stop() {}

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

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

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

bool FFmpegDemuxer::IsSeekable() const {}

void FFmpegDemuxer::SeekInternal(base::TimeDelta time,
                                 base::OnceCallback<void(int)> seek_cb) {}

base::Time FFmpegDemuxer::GetTimelineOffset() const {}

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

FFmpegDemuxerStream* FFmpegDemuxer::GetFirstEnabledFFmpegStream(
    DemuxerStream::Type type) const {}

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

int64_t FFmpegDemuxer::GetMemoryUsage() const {}

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

void FFmpegDemuxer::OnEncryptedMediaInitData(
    EmeInitDataType init_data_type,
    const std::string& encryption_key_id) {}

void FFmpegDemuxer::NotifyCapacityAvailable() {}

void FFmpegDemuxer::NotifyBufferingChanged() {}

// Helper for calculating the bitrate of the media based on information stored
// in |format_context| or failing that the size and duration of the media.
//
// Returns 0 if a bitrate could not be determined.
static int CalculateBitrate(AVFormatContext* format_context,
                            const base::TimeDelta& duration,
                            int64_t filesize_in_bytes) {}

void FFmpegDemuxer::OnOpenContextDone(bool result) {}

void FFmpegDemuxer::OnFindStreamInfoDone(int result) {}

void FFmpegDemuxer::LogMetadata(AVFormatContext* avctx,
                                base::TimeDelta max_duration) {}

FFmpegDemuxerStream* FFmpegDemuxer::FindStreamWithLowestStartTimestamp(
    bool enabled) {}

FFmpegDemuxerStream* FFmpegDemuxer::FindPreferredStreamForSeeking(
    base::TimeDelta seek_time) {}

void FFmpegDemuxer::OnSeekFrameDone(int result) {}

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

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

void FFmpegDemuxer::OnVideoSeekedForTrackChange(
    DemuxerStream* video_stream,
    base::OnceClosure seek_completed_cb,
    int result) {}

void FFmpegDemuxer::SeekOnVideoTrackChange(
    base::TimeDelta seek_to_time,
    TrackChangeCB seek_completed_cb,
    DemuxerStream::Type stream_type,
    const std::vector<DemuxerStream*>& streams) {}

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

void FFmpegDemuxer::ReadFrameIfNeeded() {}

void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {}

bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {}

bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {}

void FFmpegDemuxer::StreamHasEnded() {}

void FFmpegDemuxer::OnDataSourceError() {}

void FFmpegDemuxer::NotifyDemuxerError(PipelineStatus status) {}

void FFmpegDemuxer::SetLiveness(StreamLiveness liveness) {}

void FFmpegDemuxer::RunInitCB(PipelineStatus status) {}

void FFmpegDemuxer::RunPendingSeekCB(PipelineStatus status) {}

}  // namespace media