Toybrick

使用MPP解码RTSP流,获取不到frame数据

lozenyin

注册会员

积分
64
发表于 2023-1-14 17:19:08    查看: 64|回复: 2 | [复制链接]    打印 | 显示全部楼层
如题,参照mpp中的【mpi_dec_test.c】例程,使用ffmpeg接入RTSP流解封装为packet,然后传给mpp进行硬解码


代码如下
初始化函数
  1. int decodecRockchip::decodec_init(std::string rtsp_addr){
  2.     MPP_RET ret=MPP_OK;
  3.     MpiCmd mpi_cmd;

  4.     std::string ttt="h264";
  5.     mpp_dec_type= (in_rtsp_codec_type != ttt)? MPP_VIDEO_CodingMPEG4 : MPP_VIDEO_CodingHEVC ;

  6.     // config for runtime mode
  7.     MppDecCfg cfg       = NULL;
  8.     RK_U32 need_split   = 1;//硬件解码器的拆分模式

  9.     /********************************************************************/
  10.     //初始化流
  11.     InVideo_init(rtsp_addr);
  12.     /********************************************************************/

  13.     //创建MPP context 和 MPP api 接口
  14.     ret = mpp_create(&mpp_ctx, &mpp_mpi);
  15.     if (MPP_OK != ret) {
  16.         printf("mpp_create failed\n");
  17.         decodec_deinit();
  18.     }
  19.     printf("%p mpi_dec_test decoder test start w %d h %d type %d\n",mpp_ctx, in_rtsp_width, in_rtsp_height, mpp_dec_type);

  20.     //设置一些MPP的模式
  21.     mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE;//使能MPP内的协议解析器使用内部分帧处理
  22.     MppParam param = &need_split;
  23.     ret = mpp_mpi->control(mpp_ctx, mpi_cmd, param);
  24.     if (MPP_OK != ret) {
  25.         printf("mpi->control failed\n");
  26.         decodec_deinit();
  27.     }

  28.     //初始化Mpp,解码功能
  29.     ret = mpp_init(mpp_ctx, MPP_CTX_DEC, mpp_dec_type);
  30.     if (MPP_OK != ret) {
  31.         printf("mpp_init failed,%d\n",ret);
  32.         decodec_deinit();
  33.     }
  34.    
  35.     /********************************************************************/
  36.     printf("dec init endl\n\r");
  37.     return 0;
  38. }
复制代码
开始解码函数
  1. int decodecRockchip::decodec_start(){
  2.     RK_U32 pkt_done = 0;//用于标记是否发送完数据
  3.     RK_U32 pkt_eos  = 0;

  4.     MPP_RET ret=MPP_OK;
  5.     RK_S32 times = 3;//等待计时,单位毫秒


  6.     //测试保存视频文件
  7.     data.fp_output = fopen("./dec.yuv","ab+");

  8.     ret = mpp_packet_init(&mpp_packet, av_packet->data, av_packet->size);
  9.     if (ret) {
  10.         printf("mpp_packet_init failed\n");
  11.     }
  12.     mpp_packet_set_pts(mpp_packet, av_packet->pts);//设置数据包内容的播放时间

  13.     //循环
  14.     do
  15.     {
  16.         RK_U32 frm_eos = 0;

  17.         //获取一包视频数据
  18.         if(av_read_frame(pFormatCtx,av_packet)>=0 && av_packet->stream_index==is_Video)//获取ffmpeg的包
  19.         {
  20.             printf(">>>packet data size:%d \n\r",av_packet->size);
  21.         }else{
  22.             continue;//跳过
  23.         }


  24.         //喂数据给硬件解码器
  25.         if(!pkt_done){
  26.             ret = mpp_mpi->decode_put_packet(mpp_ctx, mpp_packet);
  27.             if (MPP_OK == ret) {
  28.                 printf("to packet for MPP\n\r");
  29.                 pkt_done = 1;
  30.             }
  31.         }

  32.         do
  33.         {
  34.             /* 拿数据 */
  35.             ret = mpp_mpi->decode_get_frame(mpp_ctx, &mpp_frame);
  36.             if (ret != MPP_OK) {
  37.                 printf("%p decode_get_frame failed ret %d\n", mpp_ctx, ret);
  38.                 break;
  39.             }else{
  40.                 if (MPP_ERR_TIMEOUT == ret) {
  41.                     if (times > 0) {
  42.                         times--;
  43.                         msleep(2);
  44.                     }
  45.                     printf("%p decode_get_frame failed too much time\n", mpp_ctx);
  46.                 }else{printf("aaa\n\r");}
  47.             }

  48.             if(mpp_frame){//当前卡在这里了~~~无法到里面去
  49.                 if(mpp_frame_get_info_change(mpp_frame)){
  50.                     //此时,mpp_frame中包含了解码后的帧数据

  51.                     RK_U32 width = mpp_frame_get_width(mpp_frame);
  52.                     RK_U32 height = mpp_frame_get_height(mpp_frame);
  53.                     RK_U32 hor_stride = mpp_frame_get_hor_stride(mpp_frame);
  54.                     RK_U32 ver_stride = mpp_frame_get_ver_stride(mpp_frame);
  55.                     RK_U32 buf_size = mpp_frame_get_buf_size(mpp_frame);
  56.                     printf("dec in frame width:%d,height:%d,hor_stride:%d,ver_stride:%d,buf_size:%d \n\r",width
  57.                                                                                                         ,height
  58.                                                                                                         ,hor_stride
  59.                                                                                                         ,ver_stride
  60.                                                                                                         ,buf_size);

  61.                     //测试
  62.                     dump_mpp_frame_to_file(mpp_frame, data.fp_output);
  63.                     printf(">>>保存一帧\n\r");

  64.                 }else{
  65.                     printf("aaa\n\r");
  66.                 }

  67.                 frm_eos = mpp_frame_get_eos(mpp_frame);
  68.                 mpp_frame_deinit(&mpp_frame);
  69.             }//else{printf("什么情况??\n\r");}

  70.             // 如果发送了最后一个数据包,但未找到最后一帧,则继续
  71.             if (pkt_eos && pkt_done && !frm_eos) {
  72.                 msleep(1);
  73.                 continue;
  74.             }
  75.             
  76.         } while (1);

  77.         if(av_packet != NULL)av_packet_unref(av_packet);
  78.         
  79.     } while (1);
  80.    
  81.     return 0;
  82. }
复制代码


然而获取到的【mpp_frame】为0(if(mpp_frame)一直没有进去)
请问一下,我说提供的信息是否可以看出问题所在?

同时询问一下是否有最新版本的MPP开发者手册?或是相关教程。万分感谢!!!

回复

使用道具 举报

jefferyzhang

论坛元老

积分
11162
发表于 2023-1-14 18:35:21 | 显示全部楼层
1. 最新的mpp文档就是wiki里那份,没有更新了:
https://t.rock-chips.com/wiki.ph ... 9%E4%B8%8B%E8%BD%BD

2. 最好的研究mpp方式是直接看mpp源码里的test代码。

3. ffmpeg有版权问题,官方无法支持。
回复

使用道具 举报

lozenyin

注册会员

积分
64
 楼主| 发表于 2023-1-15 09:53:24 | 显示全部楼层
jefferyzhang 发表于 2023-1-14 18:35
1. 最新的mpp文档就是wiki里那份,没有更新了:
https://t.rock-chips.com/wiki.php?filename=%E8%B5%84%E6 ...

那好的,我还是继续看demo的源码先,谢谢~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表