执笔蘸墨

执笔蘸墨

3个粉丝

5

问答

0

专栏

0

资料

执笔蘸墨  发布于  2024-06-24 16:20:29
采纳率 20%
5个问答
96

RV1126 ffmpeg rkmedia vdec 播放器,播放本地mp4问题

悬赏金¥ 10
问题最晚将于2024-07-01结题
     

流程如下:
1.解码器初始化

    VDEC_CHN_ATTR_S stVdecAttr;
    stVdecAttr.enCodecType = RK_CODEC_TYPE_H264;
    stVdecAttr.enMode = VIDEO_MODE_FRAME;
    stVdecAttr.enDecodecMode = VIDEO_DECODEC_HADRWARE;
    ret = RK_MPI_VDEC_CreateChn(0, &stVdecAttr);

2.ffmpeg读取AVPacket


AVPacket XFFmpeg::Read()
{
    AVPacket pkt;
    memset(&pkt, 0, sizeof(AVPacket));
    mutex.lock();
    if (!ic)
    {
        mutex.unlock();
        return pkt;
    }
    int err = av_read_frame(ic, &pkt);
    if (err != 0)
    {
        av_strerror(err, errorbuf, sizeof(errorbuf));
    }
    mutex.unlock();
    return pkt;
}

3.周期性将AVPacket的数据发送给解码器

    connect(&m_tmrVideoUpdate, &QTimer::timeout, this, [this]()
    {
        if(XFFmpeg::Get()->isPlay)
        {
            AVPacket pkt = XFFmpeg::Get()->Read();

            if (pkt.size > 0)
            {
                if (pkt.stream_index == XFFmpeg::Get()->audioStream)
                {
                    qDebug() << "定时器刷新音频";
//                    CRkProcessWidget::Get()->cAudioDecode(reinterpret_cast<char*>(pkt.data), pkt.size);
                    int tmp_apts = XFFmpeg::Get()->GetPts(&pkt);  // 更新音频的 pts

                    if(tmp_apts % 1000 == 0)
                    {
                        emit CRkProcessWidget::Get()->signalPtsUpdate(tmp_apts);
                    }
                }


                if (pkt.stream_index == XFFmpeg::Get()->videoStream)
                {
                    qDebug() << "定时器刷新视频";
                    qDebug() << "视频数据:"<<pkt.size;
                    CRkProcessWidget::Get()->cVideoDecode(reinterpret_cast<char*>(pkt.buf->buffer), pkt.buf->size);

//                    CMppH264Decoder::Get()->cDecode(&pkt);
                }
            }
            av_packet_unref(&pkt);
        }

        m_tmrVideoUpdate.start(30);
    });

int CRkProcessWidget::cVideoDecode(char* data, int size)
{

//    saveDataToFile(data, size, "/userdata/packet.bin");

    m_mutex.lock();
    qDebug()<<"进入Rk视频解码"<<endl;
    // 创建媒体缓冲区
    MEDIA_BUFFER mb = RK_MPI_MB_CreateBuffer((RK_U32)size, RK_FALSE, 0);

    // 检查缓冲区创建是否成功
    if (mb == nullptr)
    {
        qDebug() << "Error: Failed to create media buffer";
        return -1;
    }

    // 将数据复制到媒体缓冲区
    memcpy(RK_MPI_MB_GetPtr(mb), data, (size_t)size);

    qDebug() << " buffer size"<<RK_MPI_MB_GetSize(mb);

    RK_MPI_MB_SetSize(mb, (size_t)size);
//    printf("#Send packet(%p, %zuBytes) to VDEC[0].\n", RK_MPI_MB_GetPtr(mb),
//           RK_MPI_MB_GetSize(mb));


//    saveDataToFile(reinterpret_cast<char*>(RK_MPI_MB_GetPtr(mb)), static_cast<size_t>(RK_MPI_MB_GetSize(mb)), "/userdata/mb.bin");

    // 发送媒体缓冲区到解码通道
    int ret = RK_MPI_SYS_SendMediaBuffer(RK_ID_VDEC, 0, mb);
    qDebug()<<"发送视频解码"<<endl;
    if (ret != 0)
    {
        qDebug() << "Error: Failed to send media buffer, ret=" << ret;
        RK_MPI_MB_ReleaseBuffer(mb);
        return -1;
    }
    RK_MPI_MB_ReleaseBuffer(mb);

    m_mutex.unlock();

    CRkProcessWidget::Get()->cGetImage();

    return 0;



}

int CRkProcessWidget::cVideoDecode(char* data, int size)
{

//    saveDataToFile(data, size, "/userdata/packet.bin");

    m_mutex.lock();
    qDebug()<<"进入Rk视频解码"<<endl;
    // 创建媒体缓冲区
    MEDIA_BUFFER mb = RK_MPI_MB_CreateBuffer((RK_U32)size, RK_FALSE, 0);

    // 检查缓冲区创建是否成功
    if (mb == nullptr)
    {
        qDebug() << "Error: Failed to create media buffer";
        return -1;
    }

    // 将数据复制到媒体缓冲区
    memcpy(RK_MPI_MB_GetPtr(mb), data, (size_t)size);

    qDebug() << " buffer size"<<RK_MPI_MB_GetSize(mb);

    RK_MPI_MB_SetSize(mb, (size_t)size);
//    printf("#Send packet(%p, %zuBytes) to VDEC[0].\n", RK_MPI_MB_GetPtr(mb),
//           RK_MPI_MB_GetSize(mb));


//    saveDataToFile(reinterpret_cast<char*>(RK_MPI_MB_GetPtr(mb)), static_cast<size_t>(RK_MPI_MB_GetSize(mb)), "/userdata/mb.bin");

    // 发送媒体缓冲区到解码通道
    int ret = RK_MPI_SYS_SendMediaBuffer(RK_ID_VDEC, 0, mb);
    qDebug()<<"发送视频解码"<<endl;
    if (ret != 0)
    {
        qDebug() << "Error: Failed to send media buffer, ret=" << ret;
        RK_MPI_MB_ReleaseBuffer(mb);
        return -1;
    }
    RK_MPI_MB_ReleaseBuffer(mb);

    m_mutex.unlock();

    CRkProcessWidget::Get()->cGetImage();

    return 0;



}

4.获取解码后的数据并转换为qimage

int CRkProcessWidget::cGetImage()
{
    MEDIA_BUFFER mb = nullptr;
    int ret = 0;


    mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VDEC, 0, 1000);
    if (!mb)
    {

        qDebug()<<"RK_MPI_SYS_GetMediaBuffer get null buffer in 5s.."<<endl;
//        QThread::msleep(20);
        return -1;
    }


//    while(1)
//    {
//        mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VDEC, 0, 1000);
//        if (!mb)
//        {

//            qDebug()<<"RK_MPI_SYS_GetMediaBuffer get null buffer in 5s.."<<endl;
//            QThread::msleep(20);
//            continue;
//        }
//        else
//        {
//            qDebug()<<"get buffer"<<endl;
//            break;
//        }
//    }

    MB_IMAGE_INFO_S stImageInfo = {0};
    ret = RK_MPI_MB_GetImageInfo(mb, &stImageInfo);
    if (ret) {
      printf("Get image info failed! ret = %d\n", ret);
      RK_MPI_MB_ReleaseBuffer(mb);
      return -1;
    }

    // 打印图像信息
    printf("Image Info:\n");
    printf("Width: %u\n", stImageInfo.u32Width);
    printf("Height: %u\n", stImageInfo.u32Height);
    printf("Horizontal Stride: %u\n", stImageInfo.u32HorStride);
    printf("Image Type: %u\n", stImageInfo.enImgType);

    printf("#Send packet(%p, %zuBytes) to VDEC[0].\n", RK_MPI_MB_GetPtr(mb),
           RK_MPI_MB_GetSize(mb));

    const int imageSize = VIDEO_WIDTH * VIDEO_HEIGHT;  // RGB888 格式

    // 获取 MEDIA_BUFFER 中的数据指针和大小
    void *dataPtr = RK_MPI_MB_GetPtr(mb);
    size_t dataSize = RK_MPI_MB_GetSize(mb);

    // 检查数据大小是否符合预期
    if (dataSize != imageSize)
    {
        qDebug() << "Error: Data size mismatch";
        RK_MPI_MB_ReleaseBuffer(mb); // 释放 MEDIA_BUFFER
        return -1;
    }

    QImage image((uchar*)dataPtr, VIDEO_WIDTH, VIDEO_HEIGHT, QImage::Format_RGB888);
    if (image.isNull()) {
        qDebug() << "Error: Failed to create QImage";
        RK_MPI_MB_ReleaseBuffer(mb); // 释放 MEDIA_BUFFER
        return -1;
    }
    qDebug()<<"发送显示图像"<<endl;
    emit CRkProcessWidget::Get()->signalImageUpdate(image);

    RK_MPI_MB_ReleaseBuffer(mb);

    return 0;
}

问题在于 int CRkProcessWidget::cGetImage() 中的mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VDEC, 0, 1000);一直无法接收到解码后得到数据,一直显示超时
[RKMEDIA][SYS][Info]:INFO: RkmediaChnPopBuffer: Mode[VDEC]:Chn[0] get mediabuffer timeout!

我来回答
回答0个
时间排序
认可量排序
易百纳技术社区暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区