#include "MppDecoder.h" #include #include #include #include "../LogRecorder/LogOutput.h" bool MppDecoder::init() { MppDecCfg cfg = NULL; RK_U32 need_split = 1; if (m_rgbData == nullptr) { m_rgbData = new unsigned char[m_width * m_height * 3]; } MPP_RET ret = mpp_create(&m_ctx, &m_mpi); if (ret) { LOG_ERROR("mpp_create failed\n"); return false; } MpiCmd cmd = MPP_CMD_BASE; MppParam param = NULL; cmd = MPP_DEC_SET_PARSER_SPLIT_MODE; param = &need_split; ret = m_mpi->control(m_ctx, cmd, param); if (ret) { LOG_ERROR("set parser split mode failed\n"); return false; } ret = mpp_init(m_ctx, MPP_CTX_DEC, MPP_VIDEO_CodingMJPEG); if (ret) { LOG_ERROR("mpp_init failed\n"); return false; } MppFrameFormat fmt = MPP_FMT_RGB888; param = &fmt; ret = m_mpi->control(m_ctx, MPP_DEC_SET_OUTPUT_FORMAT, param); if (ret) { LOG_ERROR("set output format failed\n"); return false; } ret = mpp_frame_init(&m_frame); if (ret) { LOG_ERROR("mpp_frame_init failed\n"); return false; } ret = mpp_buffer_group_get_internal(&m_frameGroup, MPP_BUFFER_TYPE_ION); if (ret) { LOG_ERROR("mpp_buffer_group_get_internal failed\n"); return false; } ret = mpp_buffer_group_get_internal(&m_PacketGroup, MPP_BUFFER_TYPE_ION); if (ret) { LOG_ERROR("mpp_buffer_group_get_internal failed\n"); return false; } RK_U32 hor_stride = MPP_ALIGN(m_width, 16); RK_U32 ver_stride = MPP_ALIGN(m_height, 16); ret = mpp_buffer_get(m_frameGroup, &m_frameBuffer, hor_stride * ver_stride * 4); if (ret) { LOG_ERROR("mpp_buffer_get failed\n"); return false; } mpp_frame_set_buffer(m_frame, m_frameBuffer); ret = mpp_buffer_get(m_PacketGroup, &m_packetBuffer, m_width * m_height * 3); if (ret) { LOG_ERROR("mpp_buffer_get failed\n"); return false; } ret = mpp_packet_init_with_buffer(&m_packet, m_packetBuffer); if (ret) { LOG_ERROR("mpp_packet_init_with_buffer failed\n"); return false; } m_inputBufferPtr = (unsigned char *)mpp_buffer_get_ptr(m_packetBuffer); return m_initFlag = true; } bool MppDecoder::decodeJpegToRgb(const char *jpegData, size_t jpegSize, unsigned char **rgbData, int *width, int *height) { if (!m_initFlag) { LOG_ERROR("MppDecoder[{}]: Decoder not initialized", m_index); return false; } if (jpegData == nullptr || jpegSize == 0) { LOG_ERROR("MppDecoder[{}]: Invalid jpeg data or size", m_index); return false; } memset(m_inputBufferPtr, 0, m_width * m_height * 3); memcpy(m_inputBufferPtr, jpegData, jpegSize); mpp_packet_set_pos(m_packet, m_inputBufferPtr); mpp_packet_set_length(m_packet, jpegSize); mpp_packet_set_eos(m_packet); MPP_RET ret; ret = m_mpi->poll(m_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK); if (ret) { LOG_ERROR("MppDecoder[{}]: m_mpi->poll input failed, ret={}", m_index, int(ret)); resetDecoder(); // 添加重置功能以尝试恢复 return false; } ret = m_mpi->dequeue(m_ctx, MPP_PORT_INPUT, &m_task); if (ret) { LOG_ERROR("MppDecoder[{}]: m_mpi->dequeue input failed, ret={}", m_index, int(ret)); resetDecoder(); return false; } mpp_task_meta_set_packet(m_task, KEY_INPUT_PACKET, m_packet); mpp_task_meta_set_frame(m_task, KEY_OUTPUT_FRAME, m_frame); ret = m_mpi->enqueue(m_ctx, MPP_PORT_INPUT, m_task); if (ret) { LOG_ERROR("MppDecoder[{}]: m_mpi->enqueue input failed, ret={}", m_index, int(ret)); resetDecoder(); return false; } ret = m_mpi->poll(m_ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK); if (ret) { LOG_ERROR("MppDecoder[{}]: m_mpi->poll output failed, ret={}", m_index, int(ret)); resetDecoder(); return false; } ret = m_mpi->dequeue(m_ctx, MPP_PORT_OUTPUT, &m_task); if (ret) { LOG_ERROR("MppDecoder[{}]: m_mpi->dequeue output failed, ret={}", m_index, int(ret)); resetDecoder(); return false; } if (m_task) { MppFrame Output = nullptr; mpp_task_meta_get_frame(m_task, KEY_OUTPUT_FRAME, &Output); if (Output) { MppBuffer buffer = nullptr; buffer = mpp_frame_get_buffer(Output); if (buffer) { *rgbData = (unsigned char *)mpp_buffer_get_ptr(buffer); *width = mpp_frame_get_width(Output); *height = mpp_frame_get_height(Output); } } m_mpi->enqueue(m_ctx, MPP_PORT_OUTPUT, m_task); return (Output != nullptr); } LOG_ERROR("MppDecoder[{}]: No task returned", m_index); return false; } bool MppDecoder::resetDecoder() { try { LOG_WARN("MppDecoder[{}]: Attempting to reset decoder", m_index); // reset the decoder context and MPI instance if they are valid if (m_ctx && m_mpi) { // clear the task queue and reset the decoder context m_mpi->reset(m_ctx); } LOG_INFO("MppDecoder[{}]: Decoder reset completed", m_index); return true; } catch (const std::exception& e) { LOG_ERROR("MppDecoder[{}]: Exception during reset: {}", m_index, e.what()); return false; } catch (...) { LOG_ERROR("MppDecoder[{}]: Unknown exception during reset", m_index); return false; } }