11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#ifndef CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_H_
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_H_
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <stddef.h>
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/basictypes.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/macros.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_ptr.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace chromecast {
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media {
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MediaMemoryChunk;
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// MediaMessage -
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Represents a media message, including:
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - a message header that gives for example the message size or its type,
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - the content of the message,
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - and some possible padding if the content does not occupy the whole
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//   reserved space.
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MediaMessage {
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Memory allocator: given a number of bytes to allocate,
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // return the pointer to the allocated block if successful
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // or NULL if allocation failed.
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef base::Callback<scoped_ptr<MediaMemoryChunk>(size_t)>
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MemoryAllocatorCB;
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates a message with no associated memory for its content, i.e.
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // each write on this message is a dummy operation.
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This type of message can be useful to calculate first the size of the
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // message, before allocating the real message.
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static scoped_ptr<MediaMessage> CreateDummyMessage(uint32 type);
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates a message with a capacity of at least |msg_content_capacity|
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // bytes. The actual content size can be smaller than its capacity.
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The message can be populated with some Write functions.
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static scoped_ptr<MediaMessage> CreateMessage(
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      uint32 type,
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const MemoryAllocatorCB& memory_allocator,
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      size_t msg_content_capacity);
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates a message of type |type| whose serialized structure is stored
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // in |mem|.
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static scoped_ptr<MediaMessage> CreateMessage(
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      uint32 type,
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<MediaMemoryChunk> mem);
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates a message from a memory area which already contains
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the serialized structure of the message.
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Only Read functions can be invoked on this type of message.
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static scoped_ptr<MediaMessage> MapMessage(
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<MediaMemoryChunk> mem);
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return the minimum size of a message.
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static size_t minimum_msg_size() {
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return offsetof(SerializedMsg, content);
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ~MediaMessage();
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Indicate whether the underlying serialized structure of the message is
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // available.
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note: the serialized structure might be unavailable in case of a dummy
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // message or if the underlying memory has been invalidated.
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool IsSerializedMsgAvailable() const;
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return the message and the total size of the message
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // incuding the header, the content and the possible padding.
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const void* msg() const { return msg_read_only_; }
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t size() const { return cached_msg_.header.size; }
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return the size of the message without padding.
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t actual_size() const {
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return minimum_msg_size() + cached_msg_.header.content_size;
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return the size of the content of the message.
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t content_size() const { return cached_msg_.header.content_size; }
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return the type of the message.
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 type() const { return cached_msg_.header.type; }
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Append a POD to the message.
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return true if the POD has been succesfully written.
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  template<typename T> bool WritePod(T* const& pod);
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  template<typename T> bool WritePod(const T& pod) {
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return WriteBuffer(&pod, sizeof(T));
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Append a raw buffer to the message.
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool WriteBuffer(const void* src, size_t size);
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Read a POD from the message.
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  template<typename T> bool ReadPod(T* pod) {
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return ReadBuffer(pod, sizeof(T));
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Read |size| bytes from the message from the last read position
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // and write it to |dst|.
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool ReadBuffer(void* dst, size_t size);
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return a pointer to a buffer of size |size|.
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return NULL if not successful.
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const void* GetBuffer(size_t size);
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void* GetWritableBuffer(size_t size);
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaMessage(uint32 type, size_t msg_size);
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaMessage(uint32 type, scoped_ptr<MediaMemoryChunk> memory);
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaMessage(scoped_ptr<MediaMemoryChunk> memory);
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct Header {
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Total size of the message (including both header & content).
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 size;
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Indicate the message type.
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 type;
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Actual size of the content in the message.
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 content_size;
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct SerializedMsg {
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Message header.
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Header header;
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Start of the content of the message.
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Use uint8_t since no special alignment is needed.
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint8 content;
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Indicate whether the message is a dummy message, i.e. a message without
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // a complete underlying serialized structure: only the message header is
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // available.
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool is_dummy_msg_;
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |cached_msg_| is used for 2 purposes:
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // - to create a dummy message
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // - for security purpose: cache the msg header to avoid browser security
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // issues.
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SerializedMsg cached_msg_;
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Header* const cached_header_;
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SerializedMsg* msg_;
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SerializedMsg* msg_read_only_;
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Memory allocated to store the underlying serialized structure into memory.
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note: a dummy message has no underlying serialized structure:
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |mem_| is a null pointer in that case.
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMemoryChunk> mem_;
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Read iterator into the message.
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t rd_offset_;
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(MediaMessage);
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace media
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace chromecast
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
166