#include "media/muxers/mp4_muxer_delegate.h"
#include "base/logging.h"
#include "components/version_info/version_info.h"
#include "media/base/audio_parameters.h"
#include "media/base/video_codecs.h"
#include "media/formats/mp4/avc.h"
#include "media/formats/mp4/box_definitions.h"
#include "media/muxers/box_byte_stream.h"
#include "media/muxers/mp4_box_writer.h"
#include "media/muxers/mp4_fragment_box_writer.h"
#include "media/muxers/mp4_movie_box_writer.h"
#include "media/muxers/mp4_muxer_delegate_fragment.h"
#include "media/muxers/mp4_type_conversion.h"
#include "media/muxers/output_position_tracker.h"
#include "third_party/libgav1/src/src/obu_parser.h"
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
#include "media/formats/mp4/h264_annex_b_to_avc_bitstream_converter.h"
#endif
namespace media {
namespace {
TrackHeaderFlags;
constexpr char kVideoHandlerName[] = …;
constexpr char kAudioHandlerName[] = …;
constexpr char kUndefinedLanguageName[] = …;
constexpr uint32_t kMillisecondsTimeScale = …;
constexpr uint32_t kAudioSamplesPerFrame = …;
void BuildTrack(
mp4::writable_boxes::Movie& moov,
size_t track_index,
bool is_audio,
uint32_t timescale,
const mp4::writable_boxes::SampleDescription& sample_description) { … }
void CopyCreationTimeAndDuration(mp4::writable_boxes::Track& track,
const mp4::writable_boxes::MovieHeader& header,
base::TimeDelta track_duration) { … }
}
Mp4MuxerDelegate::Mp4MuxerDelegate(
AudioCodec audio_codec,
std::optional<VideoCodecProfile> video_profile,
std::optional<VideoCodecLevel> video_level,
Muxer::WriteDataCB write_callback,
size_t audio_sample_count_per_fragment)
: … { … }
Mp4MuxerDelegate::~Mp4MuxerDelegate() = default;
void Mp4MuxerDelegate::AddVideoFrame(
const Muxer::VideoParameters& params,
std::string encoded_data,
std::optional<VideoEncoder::CodecDescription> codec_description,
base::TimeTicks timestamp,
bool is_key_frame) { … }
void Mp4MuxerDelegate::BuildMovieVideoTrack(
const Muxer::VideoParameters& params,
std::string_view encoded_data,
std::optional<VideoEncoder::CodecDescription> codec_description) { … }
void Mp4MuxerDelegate::AddDataToVideoFragment(std::string_view encoded_data,
bool is_key_frame) { … }
void Mp4MuxerDelegate::AddAudioFrame(
const AudioParameters& params,
std::string encoded_data,
std::optional<AudioEncoder::CodecDescription> codec_description,
base::TimeTicks timestamp) { … }
void Mp4MuxerDelegate::BuildMovieAudioTrack(
const AudioParameters& params,
std::string_view encoded_data,
std::optional<AudioEncoder::CodecDescription> codec_description) { … }
void Mp4MuxerDelegate::AddDataToAudioFragment(std::string_view encoded_data) { … }
bool Mp4MuxerDelegate::FlushFragment() { … }
bool Mp4MuxerDelegate::Flush() { … }
size_t Mp4MuxerDelegate::MaybeFlushFileTypeBoxForStartup() { … }
size_t Mp4MuxerDelegate::MaybeFlushMoovBox() { … }
void Mp4MuxerDelegate::MaybeFlushMoofAndMfraBoxes(size_t written_offset) { … }
void Mp4MuxerDelegate::BuildFileTypeBox(
mp4::writable_boxes::FileType& mp4_file_type_box) { … }
void Mp4MuxerDelegate::BuildMovieBox() { … }
void Mp4MuxerDelegate::BuildVideoTrackFragmentRandomAccess(
base::TimeTicks start_video_time,
mp4::writable_boxes::TrackFragmentRandomAccess&
fragment_random_access_box_writer,
size_t written_offset) { … }
void Mp4MuxerDelegate::CreateFragmentIfNeeded(bool audio, bool is_key_frame) { … }
void Mp4MuxerDelegate::EnsureInitialized() { … }
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
std::string Mp4MuxerDelegate::ConvertNALUData(std::string_view encoded_data) {
if (!h264_converter_) {
h264_converter_ =
std::make_unique<media::H264AnnexBToAvcBitstreamConverter>();
}
bool config_changed = false;
size_t desired_size = 0;
std::vector<uint8_t> output_chunk;
base::span<const uint8_t> data_span(
reinterpret_cast<const uint8_t*>(encoded_data.data()),
encoded_data.size());
auto status = h264_converter_->ConvertChunk(data_span, output_chunk,
&config_changed, &desired_size);
CHECK_EQ(status.code(), media::MP4Status::Codes::kBufferTooSmall);
output_chunk.resize(desired_size);
status = h264_converter_->ConvertChunk(data_span, output_chunk,
&config_changed, &desired_size);
CHECK(status.is_ok());
std::string converted_encoded_data =
std::string(output_chunk.begin(), output_chunk.end());
return converted_encoded_data;
}
#endif
int Mp4MuxerDelegate::GetNextTrackIndex() { … }
void Mp4MuxerDelegate::LogBoxInfo() const { … }
}