| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef GARNET_BIN_MEDIAPLAYER_GRAPH_PACKET_H_ |
| #define GARNET_BIN_MEDIAPLAYER_GRAPH_PACKET_H_ |
| |
| #include <limits> |
| #include <memory> |
| #include "garnet/bin/mediaplayer/graph/payloads/payload_allocator.h" |
| #include "garnet/bin/mediaplayer/graph/types/stream_type.h" |
| #include "lib/fxl/logging.h" |
| #include "lib/media/timeline/timeline_rate.h" |
| |
| namespace media_player { |
| |
| class Packet; |
| |
| // Shared pointer for packets. |
| typedef std::shared_ptr<Packet> PacketPtr; |
| |
| // Stream packet (access unit) possibly bearing a slice of stream content |
| // (payload). |
| // TODO(dalesat): Revisit this definition: |
| // 1) Remove pts_rate(). |
| // 2) Remove end_of_stream(). |
| class Packet { |
| public: |
| static const int64_t kUnknownPts = std::numeric_limits<int64_t>::min(); |
| |
| // Creates a packet. |
| static PacketPtr Create(int64_t pts, media::TimelineRate pts_rate, |
| bool keyframe, bool end_of_stream, size_t size, |
| fbl::RefPtr<PayloadBuffer> payload_buffer); |
| |
| // Creates an end-of-stream packet with no payload. |
| static PacketPtr CreateEndOfStream(int64_t pts, media::TimelineRate pts_rate); |
| |
| // Function type used for |AfterRecycling|. |
| using Action = fit::function<void(Packet*)>; |
| |
| Packet(int64_t pts, media::TimelineRate pts_rate, bool keyframe, |
| bool end_of_stream, size_t size, |
| fbl::RefPtr<PayloadBuffer> payload_buffer); |
| |
| virtual ~Packet(); |
| |
| // Returns the presentation timestamp of the packet where the duration of a |
| // tick is given by pts_rate(). |
| int64_t pts() const { return pts_; } |
| |
| // Returns the PTS tick rate. pts_rate().subject_delta() is the number of |
| // ticks corresponding to pts_rate().reference_delta() seconds. To convert |
| // a time value from seconds to PTS ticks, use seconds * pts_rate(). To |
| // convert a time value from PTS ticks to seconds, use seconds / pts_rate(). |
| media::TimelineRate pts_rate() const { return pts_rate_; } |
| |
| // Indicates whether this is a keyframe. |
| bool keyframe() const { return keyframe_; } |
| |
| // Indicates whether this is the last packet in the stream. |
| bool end_of_stream() const { return end_of_stream_; } |
| |
| // Returns the size in bytes of the packet payload or 0 if the packet has no |
| // payload. |
| size_t size() const { return size_; } |
| |
| // Returns a pointer to the packet payload or nullptr if there is no payload |
| // or the payload isn't mapped into process local memory. |
| void* payload() const { |
| return payload_buffer_ ? payload_buffer_->data() : nullptr; |
| } |
| |
| // Returns the packet's payload buffer. |
| fbl::RefPtr<PayloadBuffer> payload_buffer() const { return payload_buffer_; } |
| |
| // Retrieves the PTS using the specified PTS tick rate. Use this method to |
| // obtain the PTS at a specific tick rate once, possibly at the cost of a |
| // TimelineRate::Product call and a TimelineRate::Scale call. |
| int64_t GetPts(media::TimelineRate pts_rate); |
| |
| // Sets the PTS rate and adjusts PTS accordingly. Use this method to adjust |
| // the packet's PTS to a desired PTS tick rate so that future calls to |
| // pts() will use the desired rate. This method has approximately the same |
| // cost as GetPts, but may save the expense of subsequent conversions. |
| void SetPtsRate(media::TimelineRate pts_rate); |
| |
| // Gets the revised stream type, which may be null. |
| const std::unique_ptr<StreamType>& revised_stream_type() const { |
| return revised_stream_type_; |
| } |
| |
| // Sets the revised stream type for the packet. |
| void SetRevisedStreamType(std::unique_ptr<StreamType> stream_type) { |
| revised_stream_type_ = std::move(stream_type); |
| } |
| |
| // Returns a numeric label used in instrumentation. The default implementation |
| // returns 0. Specialized implementations are free to do otherwise. |
| virtual uint64_t GetLabel(); |
| |
| // Registers a function to be called after recycling. This method may only |
| // be called once on a given instance. An |Action| should not hold a reference |
| // to the |Packet|, because this would produce a circular reference, and the |
| // |Packet| would never be released. |action| will be called on an arbitrary |
| // thread. |
| // NOTE: This method may seem to be oddly named, but the name is consistent |
| // with a method in |PayloadBuffer|. Also, |Packet| will soon be managed with |
| // a |RefPtr|, which will make the name more relevant. |
| // TODO(dalesat): Switch from |std::shared_ptr| to |fbl::RefPtr|. |
| void AfterRecycling(Action action); |
| |
| private: |
| int64_t pts_; |
| media::TimelineRate pts_rate_; |
| bool keyframe_; |
| bool end_of_stream_; |
| size_t size_; |
| fbl::RefPtr<PayloadBuffer> payload_buffer_; |
| std::unique_ptr<StreamType> revised_stream_type_; |
| Action after_recycling_; |
| }; |
| |
| } // namespace media_player |
| |
| #endif // GARNET_BIN_MEDIAPLAYER_GRAPH_PACKET_H_ |