Hanln_77 2024-12-16 11:53 采纳率: 0%
浏览 318
已结题

rk3568使用rkmpp的api进行视频解码

您好,我看了您的文章,想付费请教您一个问题。我现在遇到的问题是:
已有条件:
1.我首先完成了在我的项目工程里完成了点亮mipi屏幕然后通过drm框架来播放图片和视频。目前已经实现了。
2.我也通过ffmpeg把MP4的视频通过指令行解码成完整的yuv视频数据,然后通过open方式实现在屏幕上播放视频。
问题:
1.我现在需要实现在项目里通过调用rk_mpp库的api进行边解码边输出帧数据通过drm播放,卡在了解码的这个部分。
尝试过的经历:
1.我尝试使用在rk_mpp这个git上直接拉下来的工程里进行编译,生成的test中的mpi_dec_test放在板卡执行,是可以正常的解码h264并实现输出yuv,
但是我把它编译生成的.a .so拿出来,头文件拿出来放到我的工程里,然后把mpi_dec_test的源代码放到我的主程序里面就编译它,已经把报错的依赖链接这些全部解决,但是编译出来的代码在mpp_init这里面进Segmentfault。
以下图片是目录结构

img

2.我又从gpt哪里生成一份代码,但总是卡在初始化的部分。

#include <stdio.h>
#include <stdlib.h>
#include "rk_mpi.h"  // 确保包含正确的头文件

int main() {
    MppCtx mpp_ctx = NULL;
    MppApi *mpp_api = NULL;  // 正确声明 mpp_api
    MppPacket packet = NULL;
    MppFrame frame = NULL;
    FILE *h264_file = NULL;
    size_t file_size = 0;
    int ret = 0;

    // 创建 MPP 上下文并初始化
    ret = mpp_create(&mpp_ctx, &mpp_api);  // 传递 mpp_api 指针
    if (ret != MPP_OK) {  // 使用正确的返回值常量
        printf("MPP create failed\n");
        return -1;
    }

    // 初始化 MPP(设置解码器为 H.264)
    ret = mpp_init(mpp_ctx, MPP_CTX_DEC, MPP_VIDEO_CodingAVC);
    if (ret != MPP_OK) {  // 使用正确的返回值常量
        printf("MPP init failed\n");
        mpp_destroy(mpp_ctx);  // 销毁上下文
        return -1;
    }

    // 打开 H.264 文件并获取大小
    h264_file = fopen("video.h264", "rb");
    if (!h264_file) {
        printf("Failed to open H.264 file\n");
        mpp_destroy(mpp_ctx);
        return -1;
    }
    fseek(h264_file, 0, SEEK_END);
    file_size = ftell(h264_file);
    fseek(h264_file, 0, SEEK_SET);

    // 分配内存读取文件数据
    unsigned char *h264_data = malloc(file_size);
    if (!h264_data) {
        printf("Memory allocation failed\n");
        fclose(h264_file);
        mpp_destroy(mpp_ctx);
        return -1;
    }
    fread(h264_data, 1, file_size, h264_file);
    fclose(h264_file);

    // 创建数据包
    ret = mpp_packet_init(&packet, h264_data, file_size);
    if (ret != MPP_OK) {  // 使用正确的返回值常量
        printf("MPP packet init failed\n");
        free(h264_data);
        mpp_destroy(mpp_ctx);
        return -1;
    }

    // 解码视频流(异步接口)
    ret = mpp_api->decode(mpp_ctx, packet, &frame);  // 解码接口
    if (ret != MPP_OK) {
        printf("Decode failed, error code: %d\n", ret);  // 打印错误码
        mpp_packet_deinit(&packet);
        free(h264_data);
        mpp_destroy(mpp_ctx);
        return -1;
    }

    // 获取解码帧的缓冲区
    MppBuffer mpp_buffer = mpp_frame_get_buffer(frame);  // 仅传入 frame 参数
    if (mpp_buffer == NULL) {
        printf("Failed to get buffer from MppFrame\n");
        mpp_packet_deinit(&packet);
        free(h264_data);
        mpp_destroy(mpp_ctx);
        return -1;
    }

    // 获取 YUV 数据
    void *yuv_data = mpp_buffer_get_ptr(mpp_buffer);  // 获取 YUV 数据的指针
    size_t yuv_size = mpp_buffer_get_size(mpp_buffer);  // 获取 YUV 数据的大小

    printf("Decoded frame size: %zu bytes\n", yuv_size);

    // 释放资源
    mpp_packet_deinit(&packet);
    free(h264_data);
    mpp_destroy(mpp_ctx);

    return 0;
}
  • 写回答

15条回答 默认 最新

  • 阿里嘎多学长 2024-12-16 12:08
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    rk3568使用rkmpp的api进行视频解码

    你好!根据你的描述,你已经实现了在rk3568上播放图片和视频使用drm框架,但是你想使用rkmpp的API来进行视频解码。rkmpp是 Rockchip 的一个多媒体处理器,可以用来进行视频解码、编码、处理等操作。

    为了使用rkmpp的API进行视频解码,你需要:

    1. 首先,需要在你的项目工程中包含rkmpp的头文件和库文件。
    2. 然后,需要初始化rkmpp的API,例如,使用 rk_mpp_init() 函数来初始化rkmpp。
    3. 接下来,需要创建一个视频解码器对象,例如,使用 rk_mpp_create_decoder() 函数来创建一个H.264解码器对象。
    4. 之后,需要将视频文件的路径和参数传递给解码器对象,例如,使用 rk_mpp_set_file() 函数来设置视频文件的路径。
    5. 最后,需要使用 rk_mpp_decode() 函数来进行视频解码。

    以下是一个简单的示例代码,演示如何使用rkmpp的API进行H.264视频解码:

    #include <rk_mpp.h>
    
    int main() {
        // 初始化rkmpp的API
        rk_mpp_init();
    
        // 创建一个H.264解码器对象
        rk_mpp_decoder_t *decoder = rk_mpp_create_decoder(RK_MPP_DECODER_H264);
    
        // 设置视频文件的路径
        char file_path[] = "/path/to/video.mp4";
        rk_mpp_set_file(decoder, file_path);
    
        // 设置解码器的参数
        rk_mpp_set_param(decoder, RK_MPP_PARAM_WIDTH, 1280);
        rk_mpp_set_param(decoder, RK_MPP_PARAM_HEIGHT, 720);
    
        // 进行视频解码
        rk_mpp_decode(decoder);
    
        // 释放解码器对象
        rk_mpp_free(decoder);
    
        return 0;
    }
    

    请注意,这只是一个简单的示例代码,你需要根据你的实际情况进行修改和调整。同时,你也需要确保你已经正确地包含了rkmpp的头文件和库文件。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 12月16日
  • 创建了问题 12月16日