/* * * Copyright 2015 Rockchip Electronics Co. LTD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define MODULE_TAG "vp9d_api" #include #include #include #include "mpp_mem.h" #include "mpp_packet_impl.h" #include "vp9d_codec.h" #include "vp9d_parser.h" #include "vp9d_api.h" /*! *********************************************************************** * \brief * alloc all buffer *********************************************************************** */ MPP_RET vp9d_init(void *ctx, ParserCfg *init) { MPP_RET ret = MPP_OK; RK_U8 *buf = NULL; RK_S32 size = SZ_512K; Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; if (!vp9_ctx || !init) { mpp_err("vp9d init fail"); return MPP_ERR_NULL_PTR; } if ((ret = vp9d_parser_init(vp9_ctx, init)) != MPP_OK) goto _err_exit; if ((ret = vp9d_split_init(vp9_ctx)) != MPP_OK) goto _err_exit; buf = mpp_malloc(RK_U8, size); if (!buf) { mpp_err("vp9 init malloc stream buffer fail"); ret = MPP_ERR_NOMEM; goto _err_exit; } if ((ret = mpp_packet_init(&vp9_ctx->pkt, (void *)buf, size)) != MPP_OK) goto _err_exit; return ret; _err_exit: vp9d_deinit(vp9_ctx); return ret; } /*! *********************************************************************** * \brief * free all buffer *********************************************************************** */ MPP_RET vp9d_deinit(void *ctx) { RK_U8 *buf = NULL; Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; if (vp9_ctx) { vp9d_parser_deinit(vp9_ctx); vp9d_split_deinit(vp9_ctx); if (vp9_ctx->pkt) { buf = mpp_packet_get_data(vp9_ctx->pkt); MPP_FREE(buf); mpp_packet_deinit(&vp9_ctx->pkt); } } return MPP_OK; } /*! *********************************************************************** * \brief * reset *********************************************************************** */ MPP_RET vp9d_reset(void *ctx) { MPP_RET ret = MPP_ERR_UNKNOW; Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; vp9d_paser_reset(vp9_ctx); return ret = MPP_OK; } /*! *********************************************************************** * \brief * flush *********************************************************************** */ MPP_RET vp9d_flush(void *ctx) { MPP_RET ret = MPP_ERR_UNKNOW; (void)ctx; return ret = MPP_OK; } /*! *********************************************************************** * \brief * prepare *********************************************************************** */ MPP_RET vp9d_prepare(void *ctx, MppPacket pkt, HalDecTask *task) { MPP_RET ret = MPP_OK; Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; SplitContext_t *ps = (SplitContext_t *)vp9_ctx->priv_data2; RK_S64 pts = -1; RK_S64 dts = -1; RK_U8 *buf = NULL; RK_S32 length = 0; RK_U8 *out_data = NULL; RK_S32 out_size = -1; RK_S32 consumed = 0; RK_U8 *pos = NULL; task->valid = -1; pts = mpp_packet_get_pts(pkt); dts = mpp_packet_get_dts(pkt); vp9_ctx->eos = mpp_packet_get_eos(pkt); buf = pos = mpp_packet_get_pos(pkt); length = (RK_S32)mpp_packet_get_length(pkt); consumed = vp9d_split_frame(ps, &out_data, &out_size, buf, length); pos += (consumed >= 0) ? consumed : length; mpp_packet_set_pos(pkt, pos); vp9d_dbg(VP9D_DBG_STRMIN, "pkt_len=%d, pts=%lld\n", length, pts); if (out_size > 0) { vp9d_get_frame_stream(vp9_ctx, out_data, out_size); task->input_packet = vp9_ctx->pkt; task->valid = 1; mpp_packet_set_pts(vp9_ctx->pkt, pts); mpp_packet_set_dts(vp9_ctx->pkt, dts); task->flags.eos = vp9_ctx->eos; } else { task->valid = 0; task->flags.eos = vp9_ctx->eos; } (void)pts; (void)dts; (void)task; return ret = MPP_OK; } /*! *********************************************************************** * \brief * parser *********************************************************************** */ MPP_RET vp9d_parse(void *ctx, HalDecTask *in_task) { Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; MPP_RET ret = MPP_OK; vp9_parser_frame(vp9_ctx, in_task); return ret; } /*! *********************************************************************** * \brief * callback *********************************************************************** */ MPP_RET vp9d_callback(void *decoder, void *info) { MPP_RET ret = MPP_ERR_UNKNOW; Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)decoder; vp9_parser_update(vp9_ctx, info); return ret = MPP_OK; } /*! *********************************************************************** * \brief * api struct interface *********************************************************************** */ const ParserApi api_vp9d_parser = { .name = "vp9d_parse", .coding = MPP_VIDEO_CodingVP9, .ctx_size = sizeof(Vp9CodecContext), .flag = 0, .init = vp9d_init, .deinit = vp9d_deinit, .prepare = vp9d_prepare, .parse = vp9d_parse, .reset = vp9d_reset, .flush = vp9d_flush, .control = NULL, .callback = vp9d_callback, };