/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_frame" #include #include "mpp_debug.h" #include "mpp_mem_pool.h" #include "mpp_singleton.h" #include "mpp_meta_impl.h" #include "mpp_frame_impl.h" static const char *module_name = MODULE_TAG; static MppMemPool pool_frame = NULL; static void setup_mpp_frame_name(MppFrameImpl *frame) { frame->name = module_name; } static void setup_mpp_frame_defaults(MppFrameImpl *frame) { frame->color_range = MPP_FRAME_RANGE_UNSPECIFIED; frame->color_primaries = MPP_FRAME_PRI_UNSPECIFIED; frame->color_trc = MPP_FRAME_TRC_UNSPECIFIED; frame->colorspace = MPP_FRAME_SPC_UNSPECIFIED; } #define check_is_mpp_frame(frame) _check_is_mpp_frame(__FUNCTION__, frame) static void mpp_frame_srv_init() { if (pool_frame) return; pool_frame = mpp_mem_pool_init_f("MppFrame", sizeof(MppFrameImpl)); } static void mpp_frame_srv_deinit() { if (pool_frame) { mpp_mem_pool_deinit_f(pool_frame); pool_frame = NULL; } } MPP_SINGLETON(MPP_SGLN_FRAME, mpp_frame, mpp_frame_srv_init, mpp_frame_srv_deinit) MPP_RET _check_is_mpp_frame(const char *func, void *frame) { if (!__check_is_mpp_frame(frame)) return MPP_OK; mpp_err("pointer %p failed on %s check mpp_frame\n", frame, func); mpp_abort(); return MPP_NOK; } MPP_RET __check_is_mpp_frame(void *frame) { if (frame && ((MppFrameImpl*)frame)->name == module_name) return MPP_OK; return MPP_NOK; } MPP_RET mpp_frame_init(MppFrame *frame) { MppFrameImpl *p; if (!frame) { mpp_err_f("invalid NULL pointer input\n"); return MPP_ERR_NULL_PTR; } if (!pool_frame) mpp_frame_srv_init(); p = (MppFrameImpl*)mpp_mem_pool_get_f(pool_frame); if (!p) { mpp_err_f("malloc failed\n"); return MPP_ERR_NULL_PTR; } setup_mpp_frame_name(p); setup_mpp_frame_defaults(p); *frame = p; return MPP_OK; } MPP_RET mpp_frame_deinit(MppFrame *frame) { MppFrameImpl *p; if (!frame || check_is_mpp_frame(*frame)) { mpp_err_f("invalid NULL pointer input\n"); return MPP_ERR_NULL_PTR; } p = (MppFrameImpl *)*frame; if (p->buffer) mpp_buffer_put(p->buffer); if (p->meta) mpp_meta_put(p->meta); if (p->stopwatch) mpp_stopwatch_put(p->stopwatch); mpp_mem_pool_put_f(pool_frame, *frame); *frame = NULL; return MPP_OK; } MppBuffer mpp_frame_get_buffer(MppFrame frame) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return NULL; return (MppFrame)p->buffer; } void mpp_frame_set_buffer(MppFrame frame, MppBuffer buffer) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return; if (p->buffer != buffer) { if (buffer) mpp_buffer_inc_ref(buffer); if (p->buffer) mpp_buffer_put(p->buffer); p->buffer = buffer; } } RK_S32 mpp_frame_has_meta(const MppFrame frame) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return 0; return (NULL != p->meta); } MppMeta mpp_frame_get_meta(MppFrame frame) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return NULL; if (!p->meta) mpp_meta_get(&p->meta); return p->meta; } void mpp_frame_set_meta(MppFrame frame, MppMeta meta) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return; if (p->meta) { mpp_meta_put(p->meta); p->meta = NULL; } p->meta = meta; } MppFrameStatus *mpp_frame_get_status(MppFrame frame) { MppFrameImpl *p = (MppFrameImpl *)frame; return &p->status; } void mpp_frame_set_stopwatch_enable(MppFrame frame, RK_S32 enable) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return; if (enable && !p->stopwatch) { char name[32]; snprintf(name, sizeof(name) - 1, "frm %8llx", p->pts); p->stopwatch = mpp_stopwatch_get(name); if (p->stopwatch) mpp_stopwatch_set_show_on_exit(p->stopwatch, 1); } else if (!enable && p->stopwatch) { mpp_stopwatch_put(p->stopwatch); p->stopwatch = NULL; } } MppStopwatch mpp_frame_get_stopwatch(const MppFrame frame) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return NULL; return p->stopwatch; } MppFrame mpp_frame_dup(MppFrame src) { MppFrameImpl *p = (MppFrameImpl *)src; MppFrameImpl *ret; MppFrame frame = NULL; if (check_is_mpp_frame(src)) { mpp_err_f("invalid input src %p\n", src); return NULL; } mpp_frame_init(&frame); if (!frame) return NULL; ret = (MppFrameImpl *)frame; memcpy(ret, p, sizeof(MppFrameImpl)); if (p->meta) ret->meta = mpp_meta_dup(p->meta); return frame; } MPP_RET mpp_frame_copy(MppFrame dst, MppFrame src) { MppFrameImpl *p = (MppFrameImpl *)dst; if (!dst || check_is_mpp_frame(src)) { mpp_err_f("invalid input dst %p src %p\n", dst, src); return MPP_ERR_UNKNOW; } if (p->meta) mpp_meta_put(p->meta); memcpy(dst, src, sizeof(MppFrameImpl)); p = (MppFrameImpl *)src; if (p->meta) mpp_meta_inc_ref(p->meta); return MPP_OK; } MPP_RET mpp_frame_info_cmp(MppFrame frame0, MppFrame frame1) { MppFrameImpl *f0 = (MppFrameImpl *)frame0; MppFrameImpl *f1 = (MppFrameImpl *)frame1; if (check_is_mpp_frame(f0) || check_is_mpp_frame(f1)) { mpp_err_f("invalid NULL pointer input\n"); return MPP_ERR_NULL_PTR; } if ((f0->width == f1->width) && (f0->height == f1->height) && (f0->hor_stride == f1->hor_stride) && (f0->ver_stride == f1->ver_stride) && ((f0->fmt & ~MPP_FRAME_HDR_MASK) == (f1->fmt & ~MPP_FRAME_HDR_MASK)) && (f0->buf_size == f1->buf_size)) { return MPP_OK; } return MPP_NOK; } RK_U32 mpp_frame_get_fbc_offset(MppFrame frame) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return 0; if (MPP_FRAME_FMT_IS_FBC(p->fmt)) { RK_U32 fbc_version = p->fmt & MPP_FRAME_FBC_MASK; RK_U32 fbc_offset = 0; if (fbc_version == MPP_FRAME_FBC_AFBC_V1) { fbc_offset = MPP_ALIGN(MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16, SZ_4K); } else if (fbc_version == MPP_FRAME_FBC_AFBC_V2 || fbc_version == MPP_FRAME_FBC_RKFBC) { fbc_offset = 0; } p->fbc_offset = fbc_offset; } return p->fbc_offset; } RK_U32 mpp_frame_get_fbc_stride(MppFrame frame) { MppFrameImpl *p = (MppFrameImpl *)frame; if (check_is_mpp_frame(p)) return 0; return MPP_ALIGN(p->width, 16); } /* * object access function macro */ #define MPP_FRAME_ACCESSORS(type, field) \ type mpp_frame_get_##field(const MppFrame s) \ { \ check_is_mpp_frame((MppFrameImpl*)s); \ return ((MppFrameImpl*)s)->field; \ } \ void mpp_frame_set_##field(MppFrame s, type v) \ { \ check_is_mpp_frame((MppFrameImpl*)s); \ ((MppFrameImpl*)s)->field = v; \ } MPP_FRAME_ACCESSORS(RK_U32, width) MPP_FRAME_ACCESSORS(RK_U32, height) MPP_FRAME_ACCESSORS(RK_U32, hor_stride_pixel) MPP_FRAME_ACCESSORS(RK_U32, hor_stride) MPP_FRAME_ACCESSORS(RK_U32, ver_stride) MPP_FRAME_ACCESSORS(RK_U32, fbc_hdr_stride) MPP_FRAME_ACCESSORS(RK_U32, offset_x) MPP_FRAME_ACCESSORS(RK_U32, offset_y) MPP_FRAME_ACCESSORS(RK_U32, mode) MPP_FRAME_ACCESSORS(RK_U32, discard) MPP_FRAME_ACCESSORS(RK_U32, viewid) MPP_FRAME_ACCESSORS(RK_U32, poc) MPP_FRAME_ACCESSORS(RK_S64, pts) MPP_FRAME_ACCESSORS(RK_S64, dts) MPP_FRAME_ACCESSORS(RK_U32, eos) MPP_FRAME_ACCESSORS(RK_U32, info_change) MPP_FRAME_ACCESSORS(MppFrameColorRange, color_range) MPP_FRAME_ACCESSORS(MppFrameColorPrimaries, color_primaries) MPP_FRAME_ACCESSORS(MppFrameColorTransferCharacteristic, color_trc) MPP_FRAME_ACCESSORS(MppFrameColorSpace, colorspace) MPP_FRAME_ACCESSORS(MppFrameChromaLocation, chroma_location) MPP_FRAME_ACCESSORS(MppFrameFormat, fmt) MPP_FRAME_ACCESSORS(MppFrameRational, sar) MPP_FRAME_ACCESSORS(MppFrameMasteringDisplayMetadata, mastering_display) MPP_FRAME_ACCESSORS(MppFrameContentLightMetadata, content_light) MPP_FRAME_ACCESSORS(MppFrameHdrDynamicMeta*, hdr_dynamic_meta) MPP_FRAME_ACCESSORS(size_t, buf_size) MPP_FRAME_ACCESSORS(RK_U32, errinfo) MPP_FRAME_ACCESSORS(MppTask, task) MPP_FRAME_ACCESSORS(RK_U32, thumbnail_en) MPP_FRAME_ACCESSORS(size_t, fbc_size)