H264解码的一个測试程序

       网上看到的一个H264视频格式的解码測试程序,能够用来參考其逻辑流程。

代码例如以下:

Test_Display_H264()
{
      in_fd = open(H264_INPUT_FILE, O_RDONLY);  //video file open

      fstat(in_fd, &s);                                                // get input file size
      file_size = s.st_size;

 

      in_addr = (char *)mmap(0, file_size, PROT_READ, MAP_SHARED, in_fd, 0);  // mapping input file to memory
      pp_fd = open(PP_DEV_NAME, O_RDWR);                          // Post processor open,不须要它为什么要打开?

      fb_fd = open(FB_DEV_NAME, O_RDWR|O_NDELAY);                                     // LCD frame buffer open
                

      //
      // FrameExtractor Initialization 帧解压初始化//
      //
      pFrameExCtx = FrameExtractorInit(FRAMEX_IN_TYPE_MEM, delimiter_h264, sizeof(delimiter_h264), 1);  
      file_strm.p_start = file_strm.p_cur = (unsigned char *)in_addr;
      file_strm.p_end = (unsigned char *)(in_addr + file_size);
      FrameExtractorFirst(pFrameExCtx, &file_strm);                                      //流文件缓冲区起始及结束

      //


      ///    1. Create new instance      ///
      ///      (SsbSipH264DecodeInit)    ///
      //
     handle = SsbSipH264DecodeInit();

 

     //
     /     1.1 CreateFile     /
     //
     hOpen = open(MFC_DEV_NAME, O_RDWR|O_NDELAY);   //打开MFC设备
   
    //
    // 1.2 Mapping the MFC Input/Output Buffer //
    //
    // mapping shared in/out buffer between application and MFC device driver
    addr = (unsigned char *) mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hOpen, 0);
    pCTX = (_MFCLIB_H264_DEC *) malloc(sizeof(_MFCLIB_H264_DEC));   //定义解码CTX
  
  
     /
     ///    2. Obtaining the Input Buffer      ///
     ///      (SsbSipH264DecodeGetInBuf)        ///
     /
     pStrmBuf = SsbSipH264DecodeGetInBuf(handle, nFrameLeng);

    /


    / 2.1    (DeviceIoControl)           /
    / IOCTL_MFC_GET_STRM_BUF_ADDR 0x0080000F   /
    /
    mfc_args.get_buf_addr.in_usr_data = (int)pCTX->mapped_addr;
    r = ioctl(pCTX->hOpen, IOCTL_MFC_GET_LINE_BUF_ADDR, &mfc_args);

 

    ///
    // 2.2 H264 CONFIG stream extraction 帧解压配置 //
    //
    nFrameLeng = ExtractConfigStreamH264(pFrameExCtx, &file_strm, pStrmBuf, INPUT_BUFFER_SIZE, NULL);


   
    ///    3. Configuring the instance with the config stream    ///
    ///       (SsbSipH264DecodeExe)                             ///
   
    SsbSipH264DecodeExe(handle, nFrameLeng);
  
    /
    / 3.1       (DeviceIoControl)           /
    / IOCTL_MFC_H264_DEC_INIT 0x00800005   /
    /
    mfc_args.dec_init.in_strmSize = lengthBufFill;
    r = ioctl(pCTX->hOpen, IOCTL_MFC_H264_DEC_INIT, &mfc_args);

 

    /
    ///   4. Get stream information   ///
    /
    SsbSipH264DecodeGetConfig(handle, H264_DEC_GETCONF_STREAMINFO, &stream_info);

 

    //4.1 case H264_DEC_GETCONF_STREAMINFO
    g_stream_info.width      = pCTX->width;
    g_stream_info.height     = pCTX->height;
    g_stream_info.buf_width = pCTX->buf_width;
    g_stream_info.buf_height = pCTX->buf_height;

 

     // set post processor configuration
     // Structure type for IOCTL commands S3C_PP_SET_PARAMS, S3C_PP_SET_INPUT_BUF_START_ADDR_PHY,
     // S3C_PP_SET_INPUT_BUF_NEXT_START_ADDR_PHY, S3C_PP_SET_OUTPUT_BUF_START_ADDR_PHY.
     pp_param.src_full_width     = stream_info.buf_width;
     pp_param.src_full_height = stream_info.buf_height;
     pp_param.src_start_x   = 0;
     pp_param.src_start_y   = 0;
     pp_param.src_width    = pp_param.src_full_width;
     pp_param.src_height    = pp_param.src_full_height;
     pp_param.src_color_space = YC420;    //MFC decode数据为YUV420格式
     pp_param.dst_start_x   = 0;
     pp_param.dst_start_y   = 0;
     pp_param.dst_full_width     = FB0_WIDTH;   // destination width
     pp_param.dst_full_height = FB0_HEIGHT;   // destination height
     pp_param.dst_width    = pp_param.dst_full_width;
     pp_param.dst_height    = pp_param.dst_full_height;
     pp_param.dst_color_space = FB0_COLOR_SPACE; // RGB565
     pp_param.out_path           = DMA_ONESHOT;

     ioctl(pp_fd, S3C_PP_SET_PARAMS, &pp_param);

 

     // get LCD frame buffer address
     fb_size = pp_param.dst_full_width * pp_param.dst_full_height * 2; // RGB565
     fb_addr = (char *)mmap(0, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);

     //循环解压每一帧,直到播放完成
     while(1)
     {

            //
            ///       5. DECODE            ///
            ///    (SsbSipH264DecodeExe)   ///
            //
            if (SsbSipH264DecodeExe(handle, nFrameLeng) != SSBSIP_H264_DEC_RET_OK)
                  break;
            /
            / 5.1      (DeviceIoControl)           /
            / IOCTL_MFC_H264_DEC_EXE   0x00800007 /
            /
            mfc_args.dec_exe.in_strmSize = lengthBufFill;
            r = ioctl(pCTX->hOpen, IOCTL_MFC_H264_DEC_EXE, &mfc_args);

            //


            ///    6. Obtaining the Output Buffer      ///
            ///      (SsbSipH264DecodeGetOutBuf)       ///
            //
            SsbSipH264DecodeGetConfig(handle, H264_DEC_GETCONF_PHYADDR_FRAM_BUF, pYUVBuf);
 
            //6.1 IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR 0x00800013
            //获取物理地址给pp使用
            r = ioctl(pCTX->hOpen, IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR, &mfc_args);


            ///
            // Next H.264 VIDEO stream 获取下一帧//
            //
            nFrameLeng = NextFrameH264(pFrameExCtx, &file_strm, pStrmBuf, INPUT_BUFFER_SIZE, NULL);
            if (nFrameLeng < 4) //循环结束条件
                 break;

 

             // Post processing
             // pp_param.SrcFrmSt MFC output buffer physical address
             // pp_param.DstFrmSt LCD frame buffer physical address.
             pp_param.src_buf_addr_phy   = pYUVBuf[0]; // MFC output buffer
             ioctl(pp_fd, S3C_PP_SET_SRC_BUF_ADDR_PHY, &pp_param);

             ioctl(fb_fd, FBIOGET_FSCREENINFO, &lcd_info);
             pp_param.dst_buf_addr_phy   = lcd_info.smem_start;    // LCD frame buffer
             ioctl(pp_fd, S3C_PP_SET_DST_BUF_ADDR_PHY, &pp_param);
             ioctl(pp_fd, S3C_PP_START); //pp參数设置完成,启动pp
      }

      SsbSipH264DecodeDeInit(handle);


       munmap(in_addr, file_size);
       munmap(fb_addr, fb_size);
       close(pp_fd);
       close(fb_fd);
       close(in_fd);

       return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值