ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_NONE,
ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_COPY,
ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_REFERENCE,
- ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE
+ ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE,
+ ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_MANUAL_COPY
} esplusplayer_decoded_video_frame_buffer_type;
/**
} esplusplayer_rsc_alloc_policy;
/**
+ * @brief Enumerations for the status of getting decoded video frame
+ * @version 4.0
+ */
+typedef enum {
+ /** @brief successfully decoded video frame acquired. */
+ ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_SUCCESS,
+ /** @brief it means app has to return the video before getting decoded
+ * video frame frame.
+ */
+ ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_NO_REMAINING_BUFFER,
+ /**
+ * @brief there is no filled video frame yet.
+ */
+ ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_NO_FILLED_BUFFER,
+ /**
+ * @brief internal error
+ */
+ ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_UNKNOWN
+} esplusplayer_get_decoded_video_frame_status_type;
+
+/**
* @brief Create a esplusplayer handle.
* @param None
* @return return esplusplayer handle pointer.
esplusplayer_stream_type type,
int64_t* offset);
/**
+ * @brief Requests decoded video frame packet to acquire it. it works only
+ * with #ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_MANUAL_COPY
+ * mode
+ * @param [in] handle : esplusplayer handle.
+ * @param [out] packet : the decoded buffer.
+ * @param [out] status : (nullable) the result of video frame requested
+ * @pre The player state must be one of #ESPLUSPLAYER_STATE_READY or
+ * #ESPLUSPLAYER_STATE_PAUSED or #ESPLUSPLAYER_STATE_PLAYING.
+ * @post None
+ * @return #ESPLUSPLAYER_ERROR_TYPE_NONE on success, otherwise one of
+ * esplusplayer_error_type values will be returned.
+ * @exception None
+ * @version 4.0
+ * @see esplusplayer_set_video_frame_buffer_type()
+ * @see esplusplayer_decoded_buffer_destroy()
+ * @see esplusplayer_decoded_video_frame_buffer_type
+ * @code
+ * ...
+ * esplusplayer_set_video_frame_buffer_type(handle,
+ * ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_MANUAL_COPY);
+ * ...
+ * esplusplayer_prepare_async(handle);
+ * ...
+ * // after prepared
+ * esplusplayer_decoded_video_packet packet;
+ * esplusplayer_get_decoded_video_frame_status_type state;
+ * int retval = esplusplayer_get_decoded_video_packet(handle, &packet, &state);
+ * if (state == ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_SUCCESS) {
+ * // successful case.
+ * // in this case, retval will be ESPLUSPLAYER_ERROR_TYPE_NONE
+ * // you have to call esplusplayer_decoded_buffer_destroy() after using the
+ * // packet
+ * ...
+ * esplusplayer_decoded_buffer_destroy(handle, &packet);
+ * } else if (state ==
+ * ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_NO_REMAINING_BUFFER) {
+ * // app has to call esplusplayer_decoded_buffer_destroy() with previous
+ * // video packet.
+ * // it means player couldn't draw the video frame into a buffer due to no
+ * buffer.
+ * // in this case ,retval will be ESPLUSPLAYER_ERROR_TYPE_NONE
+ * } else if (state ==
+ * ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_NO_FILLED_BUFFER) {
+ * // it means app should retry to get decoded video packet.
+ * // in most case, there were no buffers drawn in the timing you called this
+ * // api.
+ * // in this case, retval will be ESPLUSPLAYER_ERROR_TYPE_NONE
+ * } else if (state == ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_UNKNOWN) {
+ * // internal error happened
+ * // in this case, retval will be ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION
+ * }
+ * ...
+ * @endcode
+ */
+int esplusplayer_get_decoded_video_packet(
+ esplusplayer_handle handle, esplusplayer_decoded_video_packet* packet,
+ esplusplayer_get_decoded_video_frame_status_type* status);
+
+/**
* @brief Provided api for enabling video hole.
* @param [in] handle : esplusplayer handle.
* @param [in] value : the value of video hole.
return false;
}
/**
+ * @brief Get the decoded video packet.
+ * @param [out] packet
+ * @return GetDecodedVideoFrameStatus
+ */
+ virtual GetDecodedVideoFrameStatus GetDecodedPacket(
+ DecodedVideoPacket& packet) {
+ return GetDecodedVideoFrameStatus::kUnknown;
+ }
+ /**
+ * @brief Return the decoded video packet.
+ * @param [in] packet
+ * @return @c True on success, otherwise @c False
+ */
+ virtual bool ReturnDecodedPacket(const DecodedVideoPacket& packet) {
+ return false;
+ }
+ /**
* @brief Provided api for enabling video hole
* @return @c True on success, otherwise @c False
*/
void* buffer_addr = nullptr;
};
+struct DecoderBufferTime {
+ uint64_t pts = 0;
+ uint64_t system_time = 0;
+};
+
+/**
+ * @brief Enumerations for the state of getting decoded packet
+ */
+enum class GetDecodedVideoFrameStatus {
+ kSuccess,
+ kNoRemainingBuffer,
+ kNoFilledBuffer,
+ kUnknown,
+};
+
} // namespace plusplayer
#endif // __PLUSPLAYER_TYPES_BUFFER_H__
%bcond_without ESPLUSPLAYER_UT
Name: esplusplayer
Summary: new multimedia streaming player
-Version: 0.0.13
+Version: 0.0.14
Release: 0
Group: Multimedia/Libraries
License: Apache-2.0
}
};
+class ManualDecodedCopiedPacketList : public DecodedPacketManagerInterface {
+ public:
+ using Handler = std::function<bool(esplusplayer_decoded_video_packet*)>;
+ explicit ManualDecodedCopiedPacketList(Handler handler) : handler_(handler) {
+ LOG_DEBUG("created");
+ }
+ virtual ~ManualDecodedCopiedPacketList() { LOG_DEBUG("destroyed"); }
+
+ protected:
+ virtual bool TryToAdd(esplusplayer_decoded_video_packet* packet) {
+ return false;
+ }
+ virtual void Clear() {}
+ virtual void GetFreeTbmSurface(void** ptr, bool is_scale_change) {}
+
+ virtual void Remove(esplusplayer_decoded_video_packet* packet) {
+ if (handler_(packet) == false) {
+ LOG_ERROR("packet return failed");
+ }
+ }
+
+ private:
+ Handler handler_;
+};
class DecodedScaledPacketList : public AbstractDecodedPacketList {
public:
explicit DecodedScaledPacketList() { LOG_DEBUG("created"); }
bool SetVideoCodecType(const PlayerVideoCodecType& type) override;
bool SetRenderTimeOffset(const StreamType type, int64_t offset) override;
bool GetRenderTimeOffset(const StreamType type, int64_t* offset) override;
+ GetDecodedVideoFrameStatus GetDecodedPacket(
+ DecodedVideoPacket& packet) override;
+ bool ReturnDecodedPacket(const DecodedVideoPacket& packet) override;
bool EnableVideoHole(bool value) override;
private:
return SetStream_(track);
}
+GetDecodedVideoFrameStatus EsPlayer::GetDecodedPacket(
+ DecodedVideoPacket& packet) {
+ if (state_manager_.GetState() < EsState::kReady) {
+ LOG_ERROR_P(this, "Invalid State , current %d",
+ state_manager_.GetStateEnum());
+ return GetDecodedVideoFrameStatus::kUnknown;
+ }
+ return trackrenderer_->GetDecodedPacket(packet);
+}
+
+bool EsPlayer::ReturnDecodedPacket(const DecodedVideoPacket& packet) {
+ if (state_manager_.GetState() < EsState::kReady) {
+ LOG_ERROR_P(this, "Invalid State , current %d",
+ state_manager_.GetStateEnum());
+ return false;
+ }
+ return trackrenderer_->ReturnDecodedPacket(packet);
+}
void EsPlayer::ResetContextForClose_() {
internal::ResetDrmProperty(drm_property_);
: ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
}
+inline esplusplayer_get_decoded_video_frame_status_type
+convert_get_decoded_video_frame_status_(
+ const plusplayer::GetDecodedVideoFrameStatus status) {
+ switch (status) {
+ case plusplayer::GetDecodedVideoFrameStatus::kSuccess: {
+ return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_SUCCESS;
+ }
+ case plusplayer::GetDecodedVideoFrameStatus::kNoRemainingBuffer: {
+ return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_NO_REMAINING_BUFFER;
+ }
+ case plusplayer::GetDecodedVideoFrameStatus::kNoFilledBuffer: {
+ return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_NO_FILLED_BUFFER;
+ }
+ case plusplayer::GetDecodedVideoFrameStatus::kUnknown: {
+ return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_UNKNOWN;
+ }
+ default: { return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_UNKNOWN; }
+ }
+ return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_UNKNOWN;
+}
+
inline VideoStreamPtr convert_stream_ptr_(
esplusplayer_video_stream_info* from) {
LOG_INFO("mime type : %u", static_cast<int>(from->mime_type));
namespace {
std::shared_ptr<DecodedPacketManagerInterface> CreateDecodedPacketManager(
+ esplusplayer_handle handle,
esplusplayer_decoded_video_frame_buffer_type type) {
std::shared_ptr<DecodedPacketManagerInterface> mgr = nullptr;
if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_COPY)
mgr = std::make_shared<plusplayer::DecodedReferencePacketList>();
else if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE)
mgr = std::make_shared<plusplayer::DecodedScaledPacketList>();
+ else if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_MANUAL_COPY)
+ mgr = std::make_shared<plusplayer::ManualDecodedCopiedPacketList>(
+ [handle](esplusplayer_decoded_video_packet* pkt) {
+ plusplayer::DecodedVideoPacket _pkt;
+ _pkt.pts = pkt->pts;
+ _pkt.duration = pkt->duration;
+ _pkt.surface_data = static_cast<tbm_surface_h>(pkt->surface_data);
+ _pkt.buffer_addr = pkt->private_data;
+ return cast_(handle)->ReturnDecodedPacket(_pkt);
+ });
return mgr;
}
} // namespace
return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
auto priv = static_cast<EsPlusPlayerPriv*>(handle);
- priv->decoded_pkt_mgr = ::CreateDecodedPacketManager(type);
+ priv->decoded_pkt_mgr = ::CreateDecodedPacketManager(handle, type);
priv->listener->SetDecodedPacketManager(priv->decoded_pkt_mgr);
auto ret = cast_(handle)->SetVideoFrameBufferType(
return convert_return_type_(true);
}
+int esplusplayer_get_decoded_video_packet(
+ esplusplayer_handle handle, esplusplayer_decoded_video_packet* packet,
+ esplusplayer_get_decoded_video_frame_status_type* state) {
+ if (is_null_(handle) || is_null_(packet)) {
+ LOG_ERROR("handle[%p] or packet[%p] is nil.", handle, packet);
+ return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
+ }
+ plusplayer::DecodedVideoPacket _packet;
+ bool ret = false;
+ auto _state = cast_(handle)->GetDecodedPacket(_packet);
+ if (_state != plusplayer::GetDecodedVideoFrameStatus::kUnknown) {
+ ret = true;
+ }
+ if (_state == plusplayer::GetDecodedVideoFrameStatus::kSuccess) {
+ packet->pts = _packet.pts;
+ packet->duration = _packet.duration;
+ packet->surface_data = static_cast<void*>(_packet.surface_data);
+ packet->private_data = _packet.buffer_addr;
+ }
+ if (state) {
+ *state = convert_get_decoded_video_frame_status_(_state);
+ }
+ return convert_return_type_(ret);
+}
+
int esplusplayer_decoded_buffer_destroy(
esplusplayer_handle handle, esplusplayer_decoded_video_packet* packet) {
if (is_null_(handle)) {
bool Flush(const StreamType& type);
bool Flush(const TrackType& type);
void GetAttribute(const Attribute& attr, boost::any* value);
+ GetDecodedVideoFrameStatus GetDecodedPacket(DecodedVideoPacket& packet);
+ bool ReturnDecodedPacket(const DecodedVideoPacket& packet);
bool EnableVideoHole(bool value);
private:
#include "trackrenderer_capi/error.h"
#include "trackrenderer_capi/track.h"
#include "trackrenderer_capi/trackrenderer_capi.h"
+#include "trackrenderer_capi/trackrenderer_internal.h"
namespace plusplayer {
TrackType ConvertToTrackType(const TrackRendererTrackType typevalue);
DecodedVideoPacket ConvertToDecodedVideoPacket(
const TrackRendererDecodedVideoPacket* packet);
+TrackRendererDecodedVideoPacket ConvertToDecodedVideoPacket(
+ const DecodedVideoPacket& packet);
TrackRendererDecodedVideoFrameBufferType ConvertToVideoFrameBufferType(
const DecodedVideoFrameBufferType& type);
+GetDecodedVideoFrameStatus ConvertToGetDecodedVideoFrameStatus(
+ const TrackRendererGetDecodedVideoFrameState state);
TrackRendererDisplayMode ConvertToTrackRendererDisplayMode(
const DisplayMode& mode);
TrackRendererDisplayRotate ConvertToTrackRendererDisplayRotate(
handle_, adapter_utils::ConvertToVideoFrameBufferType(type));
}
+GetDecodedVideoFrameStatus TrackRendererAdapter::GetDecodedPacket(
+ DecodedVideoPacket& packet) {
+ TrackRendererDecodedVideoPacket _packet;
+ TrackRendererGetDecodedVideoFrameState state;
+ trackrenderer_get_decoded_video_frame(handle_, &_packet, &state);
+ packet = adapter_utils::ConvertToDecodedVideoPacket(&_packet);
+ return adapter_utils::ConvertToGetDecodedVideoFrameStatus(state);
+}
+
+bool TrackRendererAdapter::ReturnDecodedPacket(
+ const DecodedVideoPacket& packet) {
+ auto _packet = adapter_utils::ConvertToDecodedVideoPacket(packet);
+ if (trackrenderer_return_decoded_video_frame(handle_, &_packet) == kFailed) {
+ return false;
+ }
+ return true;
+}
+
bool TrackRendererAdapter::EnableVideoHole(bool value) {
return (trackrenderer_enable_video_hole(handle_, value) != kFailed);
}
return _packet;
}
+TrackRendererDecodedVideoPacket ConvertToDecodedVideoPacket(
+ const DecodedVideoPacket& packet) {
+ TrackRendererDecodedVideoPacket _packet;
+ _packet.pts = packet.pts;
+ _packet.duration = packet.duration;
+ _packet.surface_data = static_cast<tbm_surface_h>(packet.surface_data);
+ _packet.buffer_addr = packet.buffer_addr;
+ return _packet;
+}
+
TrackRendererDecodedVideoFrameBufferType ConvertToVideoFrameBufferType(
const DecodedVideoFrameBufferType& type) {
switch (type) {
}
}
+GetDecodedVideoFrameStatus ConvertToGetDecodedVideoFrameStatus(
+ const TrackRendererGetDecodedVideoFrameState state) {
+ switch (state) {
+ case TrackRendererGetDecodedVideoFrameStateErrorNone: {
+ return GetDecodedVideoFrameStatus::kSuccess;
+ }
+ case TrackRendererGetDecodedVideoFrameStateNoRemainingBufferError: {
+ return GetDecodedVideoFrameStatus::kNoRemainingBuffer;
+ }
+ case TrackRendererGetDecodedVideoFrameStateNoFilledBufferError: {
+ return GetDecodedVideoFrameStatus::kNoFilledBuffer;
+ }
+ case TrackRendererGetDecodedVideoFrameStateUnknownError: {
+ return GetDecodedVideoFrameStatus::kUnknown;
+ }
+ default:
+ LOG_ERROR("wrong state type");
+ return GetDecodedVideoFrameStatus::kUnknown;
+ }
+}
+
TrackRendererDisplayMode ConvertToTrackRendererDisplayMode(
const DisplayMode& mode) {
switch (mode) {