| Index: media/cast/logging/log_serializer.cc
|
| diff --git a/media/cast/logging/log_serializer.cc b/media/cast/logging/log_serializer.cc
|
| index 12ef7d90ded404df308c971f8e55f8776f069f16..ddf549607a719f2956b8840f94414848e0305f26 100644
|
| --- a/media/cast/logging/log_serializer.cc
|
| +++ b/media/cast/logging/log_serializer.cc
|
| @@ -1,24 +1,11 @@
|
| // 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 "media/cast/logging/log_serializer.h"
|
| -
|
| -#include "base/big_endian.h"
|
| -
|
| -namespace media {
|
| -namespace cast {
|
| -
|
| -LogSerializer::LogSerializer(const int max_serialized_bytes)
|
| - : index_so_far_(0), max_serialized_bytes_(max_serialized_bytes) {
|
| - DCHECK_GT(max_serialized_bytes_, 0);
|
| -}
|
| -
|
| -LogSerializer::~LogSerializer() {}
|
| -
|
| -// The format is as follows:
|
| -// 16-bit integer describing the folowing LogMetadata proto size in bytes.
|
| -// The LogMetadata proto.
|
| +//
|
| +// The serialization format is as follows:
|
| +// 8-bit integer describing |is_audio|.
|
| +// 32-bit integer describing |first_rtp_timestamp|.
|
| +// 32-bit integer describing number of frame events.
|
| // (The following repeated for number of frame events):
|
| // 16-bit integer describing the following AggregatedFrameEvent proto size
|
| // in bytes.
|
| @@ -28,20 +15,31 @@ LogSerializer::~LogSerializer() {}
|
| // 16-bit integer describing the following AggregatedPacketEvent proto
|
| // size in bytes.
|
| // The AggregatedPacketEvent proto.
|
| -bool LogSerializer::SerializeEventsForStream(
|
| - const media::cast::proto::LogMetadata& metadata,
|
| - const FrameEventMap& frame_events,
|
| - const PacketEventMap& packet_events) {
|
| - if (!serialized_log_so_far_) {
|
| - serialized_log_so_far_.reset(new std::string(max_serialized_bytes_, 0));
|
| - }
|
|
|
| - int remaining_space = serialized_log_so_far_->size() - index_so_far_;
|
| - if (remaining_space <= 0)
|
| - return false;
|
| +#include "media/cast/logging/log_serializer.h"
|
|
|
| - base::BigEndianWriter writer(&(*serialized_log_so_far_)[index_so_far_],
|
| - remaining_space);
|
| +#include "base/big_endian.h"
|
| +#include "third_party/zlib/zlib.h"
|
| +
|
| +namespace media {
|
| +namespace cast {
|
| +
|
| +namespace {
|
| +
|
| +using media::cast::proto::AggregatedFrameEvent;
|
| +using media::cast::proto::AggregatedPacketEvent;
|
| +using media::cast::proto::LogMetadata;
|
| +
|
| +// Use 30MB of temp buffer to hold uncompressed data if |compress| is true.
|
| +const int kMaxUncompressedBytes = 30 * 1000 * 1000;
|
| +
|
| +bool DoSerializeEvents(const LogMetadata& metadata,
|
| + const FrameEventMap& frame_events,
|
| + const PacketEventMap& packet_events,
|
| + const int max_output_bytes,
|
| + char* output,
|
| + int* output_bytes) {
|
| + base::BigEndianWriter writer(output, max_output_bytes);
|
|
|
| int proto_size = metadata.ByteSize();
|
| if (!writer.WriteU16(proto_size))
|
| @@ -55,6 +53,7 @@ bool LogSerializer::SerializeEventsForStream(
|
| it != frame_events.end();
|
| ++it) {
|
| proto_size = it->second->ByteSize();
|
| +
|
| // Write size of the proto, then write the proto.
|
| if (!writer.WriteU16(proto_size))
|
| return false;
|
| @@ -69,6 +68,7 @@ bool LogSerializer::SerializeEventsForStream(
|
| it != packet_events.end();
|
| ++it) {
|
| proto_size = it->second->ByteSize();
|
| +
|
| // Write size of the proto, then write the proto.
|
| if (!writer.WriteU16(proto_size))
|
| return false;
|
| @@ -78,17 +78,86 @@ bool LogSerializer::SerializeEventsForStream(
|
| return false;
|
| }
|
|
|
| - index_so_far_ = serialized_log_so_far_->size() - writer.remaining();
|
| + *output_bytes = max_output_bytes - writer.remaining();
|
| return true;
|
| }
|
|
|
| -scoped_ptr<std::string> LogSerializer::GetSerializedLogAndReset() {
|
| - serialized_log_so_far_->resize(index_so_far_);
|
| - index_so_far_ = 0;
|
| - return serialized_log_so_far_.Pass();
|
| +bool Compress(char* uncompressed_buffer,
|
| + int uncompressed_bytes,
|
| + int max_output_bytes,
|
| + char* output,
|
| + int* output_bytes) {
|
| + z_stream stream = {0};
|
| + int result = deflateInit2(&stream,
|
| + Z_DEFAULT_COMPRESSION,
|
| + Z_DEFLATED,
|
| + // 16 is added to produce a gzip header + trailer.
|
| + MAX_WBITS + 16,
|
| + 8, // memLevel = 8 is default.
|
| + Z_DEFAULT_STRATEGY);
|
| + DCHECK_EQ(Z_OK, result);
|
| +
|
| + stream.next_in = reinterpret_cast<uint8*>(uncompressed_buffer);
|
| + stream.avail_in = uncompressed_bytes;
|
| + stream.next_out = reinterpret_cast<uint8*>(output);
|
| + stream.avail_out = max_output_bytes;
|
| +
|
| + // Do a one-shot compression. This will return Z_STREAM_END only if |output|
|
| + // is large enough to hold all compressed data.
|
| + result = deflate(&stream, Z_FINISH);
|
| + bool success = (result == Z_STREAM_END);
|
| +
|
| + if (!success)
|
| + DVLOG(2) << "deflate() failed. Result: " << result;
|
| +
|
| + result = deflateEnd(&stream);
|
| + DCHECK(result == Z_OK || result == Z_DATA_ERROR);
|
| +
|
| + if (success)
|
| + *output_bytes = max_output_bytes - stream.avail_out;
|
| +
|
| + return success;
|
| }
|
|
|
| -int LogSerializer::GetSerializedLength() const { return index_so_far_; }
|
| +} // namespace
|
| +
|
| +bool SerializeEvents(const LogMetadata& log_metadata,
|
| + const FrameEventMap& frame_events,
|
| + const PacketEventMap& packet_events,
|
| + bool compress,
|
| + int max_output_bytes,
|
| + char* output,
|
| + int* output_bytes) {
|
| + DCHECK_GT(max_output_bytes, 0);
|
| + DCHECK(output);
|
| + DCHECK(output_bytes);
|
| +
|
| + if (compress) {
|
| + // Allocate a reasonably large temp buffer to hold uncompressed data.
|
| + scoped_ptr<char[]> uncompressed_buffer(new char[kMaxUncompressedBytes]);
|
| + int uncompressed_bytes;
|
| + bool success = DoSerializeEvents(log_metadata,
|
| + frame_events,
|
| + packet_events,
|
| + kMaxUncompressedBytes,
|
| + uncompressed_buffer.get(),
|
| + &uncompressed_bytes);
|
| + if (!success)
|
| + return false;
|
| + return Compress(uncompressed_buffer.get(),
|
| + uncompressed_bytes,
|
| + max_output_bytes,
|
| + output,
|
| + output_bytes);
|
| + } else {
|
| + return DoSerializeEvents(log_metadata,
|
| + frame_events,
|
| + packet_events,
|
| + max_output_bytes,
|
| + output,
|
| + output_bytes);
|
| + }
|
| +}
|
|
|
| } // namespace cast
|
| } // namespace media
|
|
|