blob: 64f4ed5a32b8a14e3db3646ee783037c3a29539b [file] [log] [blame]
// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef STARBOARD_SHARED_FFMPEG_FFMPEG_DEMUXER_IMPL_H_
#define STARBOARD_SHARED_FFMPEG_FFMPEG_DEMUXER_IMPL_H_
#include <deque>
#include <memory>
#include <vector>
#include "starboard/extension/demuxer.h"
#include "starboard/shared/ffmpeg/ffmpeg_common.h"
#include "starboard/shared/ffmpeg/ffmpeg_demuxer.h"
#include "starboard/shared/ffmpeg/ffmpeg_demuxer_impl_interface.h"
namespace starboard {
namespace shared {
namespace ffmpeg {
class FFMPEGDispatch;
// Forward class declaration of the explicit specialization with value FFMPEG.
template <>
class FFmpegDemuxerImpl<FFMPEG>;
// Declare the explicit specialization of the class with value FFMPEG.
template <>
class FFmpegDemuxerImpl<FFMPEG> : public FFmpegDemuxer {
public:
// Creates an FFmpegDemuxer instance for a specific version of FFmpeg. Returns
// null if the version of FFmpeg that is present is not supported.
static std::unique_ptr<FFmpegDemuxer> Create(
CobaltExtensionDemuxerDataSource* data_source);
~FFmpegDemuxerImpl() override;
// FFmpegDemuxer implementation:
CobaltExtensionDemuxerStatus Initialize() override;
bool HasAudioStream() const override;
bool HasVideoStream() const override;
const CobaltExtensionDemuxerAudioDecoderConfig& GetAudioConfig()
const override;
const CobaltExtensionDemuxerVideoDecoderConfig& GetVideoConfig()
const override;
int64_t GetDuration() const override;
int64_t GetStartTime() const override;
int64_t GetTimelineOffset() const override;
void Read(CobaltExtensionDemuxerStreamType type,
CobaltExtensionDemuxerReadCB read_cb,
void* read_cb_user_data) override;
CobaltExtensionDemuxerStatus Seek(int64_t seek_time_us) override;
private:
#if LIBAVUTIL_VERSION_INT >= LIBAVUTIL_VERSION_52_8
struct ScopedPtrAVFreeContext {
void operator()(void* ptr) const;
};
#endif // LIBAVUTIL_VERSION_INT >= LIBAVUTIL_VERSION_52_8
struct ScopedPtrAVFreeAVIOContext {
void operator()(void* ptr) const;
};
struct ScopedPtrAVFreePacket {
void operator()(void* ptr) const;
};
using ScopedAVPacket = std::unique_ptr<AVPacket, ScopedPtrAVFreePacket>;
explicit FFmpegDemuxerImpl(CobaltExtensionDemuxerDataSource* data_source);
// Creates an empty ScopedAVPacket. The returned ScopedAVPacket will not be
// null.
// Since different versions of FFmpeg require different functions to create an
// AVPacket, this function abstracts away those differences.
ScopedAVPacket CreateScopedAVPacket();
// Returns the next packet of type |type|, or nullptr if EoS has been reached
// or an error was encountered.
ScopedAVPacket GetNextPacket(CobaltExtensionDemuxerStreamType type);
// Returns a buffered packet of type |type|, or nullptr if no buffered packet
// is available.
ScopedAVPacket GetBufferedPacket(CobaltExtensionDemuxerStreamType type);
// Pushes |packet| into the queue specified by |type|.
void BufferPacket(ScopedAVPacket packet,
CobaltExtensionDemuxerStreamType type);
bool ParseAudioConfig(AVStream* audio_stream,
CobaltExtensionDemuxerAudioDecoderConfig* config);
bool ParseVideoConfig(AVStream* video_stream,
CobaltExtensionDemuxerVideoDecoderConfig* config);
CobaltExtensionDemuxerDataSource* data_source_ = nullptr;
AVStream* video_stream_ = nullptr;
AVStream* audio_stream_ = nullptr;
std::deque<ScopedAVPacket> video_packets_;
std::deque<ScopedAVPacket> audio_packets_;
std::vector<uint8_t> extra_audio_data_;
std::vector<uint8_t> extra_video_data_;
// These will only be properly populated if the corresponding AVStream is not
// null.
CobaltExtensionDemuxerAudioDecoderConfig audio_config_ = {};
CobaltExtensionDemuxerVideoDecoderConfig video_config_ = {};
bool initialized_ = false;
int64_t start_time_ = 0L;
int64_t duration_us_ = 0L;
int64_t timeline_offset_us_ = 0L;
// FFmpeg-related structs.
std::unique_ptr<AVIOContext, ScopedPtrAVFreeAVIOContext> avio_context_;
AVFormatContext* format_context_ = nullptr;
};
} // namespace ffmpeg
} // namespace shared
} // namespace starboard
#endif // STARBOARD_SHARED_FFMPEG_FFMPEG_DEMUXER_IMPL_H_