#include "base/check.h"
#include "base/functional/bind.h"
+#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
+#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
+#include "base/task/thread_pool.h"
#include "content/renderer/media/tizen/elementary_media_stream_source/common/common.h"
#include "content/renderer/media/tizen/elementary_media_stream_source/common/logger.h"
#include "content/renderer/media/tizen/elementary_media_stream_source/control_thread/demuxer_dispatcher_client.h"
#include "media/filters/decoder_selector.h"
#include "media/filters/decrypting_demuxer_stream.h"
#include "media/filters/tizen/decoder_selection_policy.h"
+#include "media/video/gpu_memory_buffer_video_frame_pool.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/elementary_media_stream_source/web_elementary_media_track_ms_audio_sink.h"
public:
using Traits = DecoderTraits<StreamType>;
using CreateDecodersCb = typename Traits::CreateDecodersCb;
+ using DecodedBuffer = typename Traits::DecodedBuffer;
using Sink = typename Traits::Sink;
using StreamConfig = typename Traits::StreamConfig;
+ using ProcessOutputCb = base::RepeatingCallback<void(
+ scoped_refptr<DecodedBuffer>,
+ base::OnceCallback<void(scoped_refptr<DecodedBuffer>)>)>;
+
DecodingStream(MsDecodingStream* parent,
media::MediaLog* media_log,
std::shared_ptr<Sink> sink);
TrackType Type() const { return StreamType; }
private:
- using DecodedBuffer = typename Traits::DecodedBuffer;
using MediaDecoder = typename Traits::MediaDecoder;
bool is_initializing() const { return !!pending_decoder_; }
void DestroyCurrentDecoder();
void OnBufferDecoded(scoped_refptr<DecodedBuffer>);
+ void OnBufferDecodedAndProcessed(scoped_refptr<DecodedBuffer>);
void OnDecoderWaiting(media::WaitingReason);
StreamConfig config_;
bool is_flushing_until_keyframe_{false};
+ ProcessOutputCb process_output_cb_;
MsDecodingStream* parent_;
base::WeakPtrFactory<DecodingStream<StreamType>> weak_ptr_factory_{this};
}; // class DecodingStream
}
decoder_ = std::move(pending_decoder_);
+ if constexpr (StreamType == TrackType::kVideo) {
+ process_output_cb_ = parent_->GetBufferProcessorForDecoder(*decoder_);
+ }
TryProcessPendingDecodes();
}
scoped_refptr<DecodedBuffer> buffer) {
EMSS_VERBOSE_TYPED() << AsHumanReadableString(buffer);
+ if (process_output_cb_) {
+ process_output_cb_.Run(
+ std::move(buffer),
+ base::BindPostTaskToCurrentDefault(base::BindOnce(
+ &DecodingStream<StreamType>::OnBufferDecodedAndProcessed,
+ weak_ptr_factory_.GetWeakPtr())));
+ return;
+ }
+
+ OnBufferDecodedAndProcessed(std::move(buffer));
+}
+
+template <TrackType StreamType>
+void MsDecodingStream::DecodingStream<StreamType>::OnBufferDecodedAndProcessed(
+ scoped_refptr<DecodedBuffer> buffer) {
+ EMSS_VERBOSE_TYPED();
+
sink_->AppendPacket(std::move(buffer));
}
std::move(control_task_runner)));
}
+MsDecodingStream::ProcessVideoOutputCb
+MsDecodingStream::GetBufferProcessorForDecoder(
+ const media::VideoDecoder& video_decoder) {
+ EMSS_VERBOSE();
+
+ if (video_decoder.IsPlatformDecoder()) {
+ return {};
+ }
+
+ if (!gmb_pool_) {
+ EMSS_VERBOSE();
+ EMSS_LOG_ASSERT(gpu_factories_) << "GpuFactories should've been set by now";
+
+ gmb_pool_ = std::make_unique<media::GpuMemoryBufferVideoFramePool>(
+ base::SequencedTaskRunner::GetCurrentDefault(),
+ base::ThreadPool::CreateSequencedTaskRunner(
+ {base::TaskPriority::USER_BLOCKING}),
+ gpu_factories_);
+ }
+
+ return base::BindPostTaskToCurrentDefault(
+ base::BindRepeating(&MsDecodingStream::ProcessSoftwareDecodedVideoFrame,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void MsDecodingStream::ProcessSoftwareDecodedVideoFrame(
+ scoped_refptr<media::VideoFrame> frame,
+ VideoOutputProcessedCb on_frame_processed) {
+ EMSS_VERBOSE();
+ EMSS_LOG_ASSERT(gmb_pool_);
+
+ gmb_pool_->MaybeCreateHardwareFrame(std::move(frame),
+ std::move(on_frame_processed));
+}
+
} // namespace content::elementary_media_stream_source::worker_thread
#include "content/renderer/media/tizen/elementary_media_stream_source/worker_thread/platform_demuxer_adapter_client.h"
#include "media/base/media_log.h"
#include "media/base/video_decoder.h"
+#include "media/base/video_frame.h"
#include "media/video/gpu_video_accelerator_factories.h"
namespace blink {
namespace media {
class AudioDecoder;
+class GpuMemoryBufferVideoFramePool;
class GpuVideoAcceleratorFactories;
} // namespace media
using AudioStream = DecodingStream<TrackType::kAudio>;
using VideoStream = DecodingStream<TrackType::kVideo>;
+ using VideoOutputProcessedCb =
+ base::OnceCallback<void(scoped_refptr<media::VideoFrame>)>;
+ using ProcessVideoOutputCb =
+ base::RepeatingCallback<void(scoped_refptr<media::VideoFrame>,
+ VideoOutputProcessedCb)>;
+
void OnNewCreateAudioDecodersPrerequisiteAvailable();
void OnNewCreateVideoDecodersPrerequisiteAvailable();
+ ProcessVideoOutputCb GetBufferProcessorForDecoder(const media::VideoDecoder&);
+ void ProcessSoftwareDecodedVideoFrame(
+ scoped_refptr<media::VideoFrame> frame,
+ VideoOutputProcessedCb on_frame_processed);
+
std::unique_ptr<AudioStream> audio_stream_;
std::unique_ptr<VideoStream> video_stream_;
gfx::ColorSpace target_color_space_;
base::WeakPtr<media::DecoderFactory> decoder_factory_;
std::weak_ptr<any_thread::DemuxerDispatcher> dispatcher_;
+ std::unique_ptr<media::GpuMemoryBufferVideoFramePool> gmb_pool_;
media::GpuVideoAcceleratorFactories* gpu_factories_{nullptr};
std::unique_ptr<media::MediaLog> media_log_;