| Index: media/muxers/webm_muxer.cc
|
| diff --git a/media/muxers/webm_muxer.cc b/media/muxers/webm_muxer.cc
|
| index 02a4ca9fb2bcbe51b872c5b9f8fc3046c353b264..5b98472f875a5f536b9369f7e38fc626f4a6732d 100644
|
| --- a/media/muxers/webm_muxer.cc
|
| +++ b/media/muxers/webm_muxer.cc
|
| @@ -134,6 +134,7 @@ WebmMuxer::~WebmMuxer() {
|
|
|
| bool WebmMuxer::OnEncodedVideo(const VideoParameters& params,
|
| std::unique_ptr<std::string> encoded_data,
|
| + std::unique_ptr<std::string> encoded_alpha,
|
| base::TimeTicks timestamp,
|
| bool is_key_frame) {
|
| DVLOG(1) << __func__ << " - " << encoded_data->size() << "B";
|
| @@ -154,15 +155,17 @@ bool WebmMuxer::OnEncodedVideo(const VideoParameters& params,
|
| encoded_frames_queue_.clear();
|
|
|
| encoded_frames_queue_.push_back(base::MakeUnique<EncodedVideoFrame>(
|
| - std::move(encoded_data), timestamp, is_key_frame));
|
| + std::move(encoded_data), std::move(encoded_alpha), timestamp,
|
| + is_key_frame));
|
| return true;
|
| }
|
|
|
| // Any saved encoded video frames must have been dumped in OnEncodedAudio();
|
| DCHECK(encoded_frames_queue_.empty());
|
|
|
| - return AddFrame(std::move(encoded_data), video_track_index_,
|
| - timestamp - first_frame_timestamp_video_, is_key_frame);
|
| + return AddFrame(std::move(encoded_data), std::move(encoded_alpha),
|
| + video_track_index_, timestamp - first_frame_timestamp_video_,
|
| + is_key_frame);
|
| }
|
|
|
| bool WebmMuxer::OnEncodedAudio(const media::AudioParameters& params,
|
| @@ -188,6 +191,10 @@ bool WebmMuxer::OnEncodedAudio(const media::AudioParameters& params,
|
| while (!encoded_frames_queue_.empty()) {
|
| const bool res = AddFrame(
|
| base::MakeUnique<std::string>(*encoded_frames_queue_.front()->data),
|
| + encoded_frames_queue_.front()->alpha_data
|
| + ? base::MakeUnique<std::string>(
|
| + *encoded_frames_queue_.front()->alpha_data)
|
| + : nullptr,
|
| video_track_index_,
|
| encoded_frames_queue_.front()->timestamp - first_frame_timestamp_video_,
|
| encoded_frames_queue_.front()->is_keyframe);
|
| @@ -195,8 +202,7 @@ bool WebmMuxer::OnEncodedAudio(const media::AudioParameters& params,
|
| return false;
|
| encoded_frames_queue_.pop_front();
|
| }
|
| -
|
| - return AddFrame(std::move(encoded_data), audio_track_index_,
|
| + return AddFrame(std::move(encoded_data), nullptr, audio_track_index_,
|
| timestamp - first_frame_timestamp_audio_,
|
| true /* is_key_frame -- always true for audio */);
|
| }
|
| @@ -240,6 +246,14 @@ void WebmMuxer::AddVideoTrack(const gfx::Size& frame_size, double frame_rate) {
|
| DCHECK_EQ(0ull, video_track->crop_bottom());
|
| DCHECK_EQ(0.0f, video_track->frame_rate());
|
|
|
| + video_track->SetAlphaMode(mkvmuxer::VideoTrack::kAlpha);
|
| + // Alpha channel, if present, is stored in a BlockAdditional next to the
|
| + // associated opaque Block, see
|
| + // https://matroska.org/technical/specs/index.html#BlockAdditional.
|
| + // This follows Method 1 for VP8 encoding of A-channel described on
|
| + // http://wiki.webmproject.org/alpha-channel.
|
| + video_track->set_max_block_additional_id(1);
|
| +
|
| // Segment's timestamps should be in milliseconds, DCHECK it. See
|
| // http://www.webmproject.org/docs/container/#muxer-guidelines
|
| DCHECK_EQ(1000000ull, segment_.GetSegmentInfo()->timecode_scale());
|
| @@ -308,6 +322,7 @@ void WebmMuxer::ElementStartNotify(mkvmuxer::uint64 element_id,
|
| }
|
|
|
| bool WebmMuxer::AddFrame(std::unique_ptr<std::string> encoded_data,
|
| + std::unique_ptr<std::string> encoded_alpha,
|
| uint8_t track_index,
|
| base::TimeDelta timestamp,
|
| bool is_key_frame) {
|
| @@ -325,9 +340,21 @@ bool WebmMuxer::AddFrame(std::unique_ptr<std::string> encoded_data,
|
| }
|
|
|
| DCHECK(encoded_data->data());
|
| - return segment_.AddFrame(
|
| + if (!encoded_alpha || encoded_alpha->empty()) {
|
| + return segment_.AddFrame(
|
| + reinterpret_cast<const uint8_t*>(encoded_data->data()),
|
| + encoded_data->size(), track_index,
|
| + most_recent_timestamp_.InMicroseconds() *
|
| + base::Time::kNanosecondsPerMicrosecond,
|
| + is_key_frame);
|
| + }
|
| +
|
| + DCHECK(encoded_alpha->data());
|
| + return segment_.AddFrameWithAdditional(
|
| reinterpret_cast<const uint8_t*>(encoded_data->data()),
|
| - encoded_data->size(), track_index,
|
| + encoded_data->size(),
|
| + reinterpret_cast<const uint8_t*>(encoded_alpha->data()),
|
| + encoded_alpha->size(), 1 /* add_id */, track_index,
|
| most_recent_timestamp_.InMicroseconds() *
|
| base::Time::kNanosecondsPerMicrosecond,
|
| is_key_frame);
|
| @@ -335,9 +362,13 @@ bool WebmMuxer::AddFrame(std::unique_ptr<std::string> encoded_data,
|
|
|
| WebmMuxer::EncodedVideoFrame::EncodedVideoFrame(
|
| std::unique_ptr<std::string> data,
|
| + std::unique_ptr<std::string> alpha_data,
|
| base::TimeTicks timestamp,
|
| bool is_keyframe)
|
| - : data(std::move(data)), timestamp(timestamp), is_keyframe(is_keyframe) {}
|
| + : data(std::move(data)),
|
| + alpha_data(std::move(alpha_data)),
|
| + timestamp(timestamp),
|
| + is_keyframe(is_keyframe) {}
|
|
|
| WebmMuxer::EncodedVideoFrame::~EncodedVideoFrame() {}
|
|
|
|
|