1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/media/cma/pipeline/video_pipeline_impl.h"
#include "base/bind.h"
#include "chromecast/media/cdm/browser_cdm_cast.h"
#include "chromecast/media/cma/base/buffering_defs.h"
#include "chromecast/media/cma/base/cma_logging.h"
#include "chromecast/media/cma/base/coded_frame_provider.h"
#include "chromecast/media/cma/base/decoder_config_adapter.h"
#include "chromecast/media/cma/pipeline/av_pipeline_impl.h"
#include "chromecast/public/graphics_types.h"
#include "chromecast/public/media/decoder_config.h"
#include "media/base/video_decoder_config.h"
namespace chromecast {
namespace media {
namespace {
const size_t kMaxVideoFrameSize = 1024 * 1024;
}
VideoPipelineImpl::VideoPipelineImpl(
MediaPipelineBackend::VideoDecoder* decoder,
const VideoPipelineClient& client)
: AvPipelineImpl(decoder, client.av_pipeline_client),
video_decoder_(decoder),
natural_size_changed_cb_(client.natural_size_changed_cb) {
DCHECK(video_decoder_);
}
VideoPipelineImpl::~VideoPipelineImpl() {
}
void VideoPipelineImpl::Initialize(
const std::vector<::media::VideoDecoderConfig>& configs,
scoped_ptr<CodedFrameProvider> frame_provider,
const ::media::PipelineStatusCB& status_cb) {
DCHECK_GT(configs.size(), 0u);
for (const auto& config : configs) {
CMALOG(kLogControl) << __FUNCTION__ << " "
<< config.AsHumanReadableString();
}
if (frame_provider) {
SetCodedFrameProvider(frame_provider.Pass(), kAppVideoBufferSize,
kMaxVideoFrameSize);
}
if (configs.empty()) {
status_cb.Run(::media::PIPELINE_ERROR_INITIALIZATION_FAILED);
return;
}
DCHECK(configs.size() <= 2);
DCHECK(configs[0].IsValidConfig());
VideoConfig video_config =
DecoderConfigAdapter::ToCastVideoConfig(kPrimary, configs[0]);
VideoConfig secondary_config;
if (configs.size() == 2) {
DCHECK(configs[1].IsValidConfig());
secondary_config = DecoderConfigAdapter::ToCastVideoConfig(kSecondary,
configs[1]);
video_config.additional_config = &secondary_config;
}
if (!video_decoder_->SetConfig(video_config)) {
status_cb.Run(::media::PIPELINE_ERROR_INITIALIZATION_FAILED);
return;
}
TransitionToState(kFlushed);
status_cb.Run(::media::PIPELINE_OK);
}
void VideoPipelineImpl::OnVideoResolutionChanged(const Size& size) {
if (state() != kPlaying)
return;
if (!natural_size_changed_cb_.is_null()) {
natural_size_changed_cb_.Run(gfx::Size(size.width, size.height));
}
}
void VideoPipelineImpl::OnUpdateConfig(
StreamId id,
const ::media::AudioDecoderConfig& audio_config,
const ::media::VideoDecoderConfig& video_config) {
if (video_config.IsValidConfig()) {
CMALOG(kLogControl) << __FUNCTION__ << " id:" << id << " "
<< video_config.AsHumanReadableString();
bool success = video_decoder_->SetConfig(
DecoderConfigAdapter::ToCastVideoConfig(id, video_config));
if (!success && !client().playback_error_cb.is_null())
client().playback_error_cb.Run(::media::PIPELINE_ERROR_DECODE);
}
}
void VideoPipelineImpl::UpdateStatistics() {
if (client().statistics_cb.is_null())
return;
MediaPipelineBackend::VideoDecoder::Statistics video_stats;
video_decoder_->GetStatistics(&video_stats);
::media::PipelineStatistics current_stats;
current_stats.video_bytes_decoded = video_stats.decoded_bytes;
current_stats.video_frames_decoded = video_stats.decoded_frames;
current_stats.video_frames_dropped = video_stats.dropped_frames;
::media::PipelineStatistics delta_stats;
delta_stats.video_bytes_decoded =
current_stats.video_bytes_decoded - previous_stats_.video_bytes_decoded;
delta_stats.video_frames_decoded =
current_stats.video_frames_decoded - previous_stats_.video_frames_decoded;
delta_stats.video_frames_dropped =
current_stats.video_frames_dropped - previous_stats_.video_frames_dropped;
previous_stats_ = current_stats;
client().statistics_cb.Run(delta_stats);
}
} // namespace media
} // namespace chromecast
|