This source file includes following definitions.
- DoSerializeEvents
- Compress
- SerializeEvents
#include "media/cast/logging/log_serializer.h"
#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;
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))
return false;
if (!metadata.SerializeToArray(writer.ptr(), writer.remaining()))
return false;
if (!writer.Skip(proto_size))
return false;
RtpTimestamp prev_rtp_timestamp = 0;
for (media::cast::FrameEventMap::const_iterator it = frame_events.begin();
it != frame_events.end();
++it) {
media::cast::proto::AggregatedFrameEvent frame_event(*(it->second));
frame_event.set_relative_rtp_timestamp(
frame_event.relative_rtp_timestamp() - prev_rtp_timestamp);
prev_rtp_timestamp = it->first;
proto_size = frame_event.ByteSize();
if (!writer.WriteU16(proto_size))
return false;
if (!frame_event.SerializeToArray(writer.ptr(), writer.remaining()))
return false;
if (!writer.Skip(proto_size))
return false;
}
prev_rtp_timestamp = 0;
for (media::cast::PacketEventMap::const_iterator it = packet_events.begin();
it != packet_events.end();
++it) {
media::cast::proto::AggregatedPacketEvent packet_event(*(it->second));
packet_event.set_relative_rtp_timestamp(
packet_event.relative_rtp_timestamp() - prev_rtp_timestamp);
prev_rtp_timestamp = it->first;
proto_size = packet_event.ByteSize();
if (!writer.WriteU16(proto_size))
return false;
if (!packet_event.SerializeToArray(writer.ptr(), writer.remaining()))
return false;
if (!writer.Skip(proto_size))
return false;
}
*output_bytes = max_output_bytes - writer.remaining();
return true;
}
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,
MAX_WBITS + 16,
8,
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;
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;
}
}
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) {
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);
}
}
}
}