zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    【BZOJ】2019: [Usaco2009 Nov]找工作(spfa)
    【BZOJ】3668: [Noi2014]起床困难综合症(暴力)
    Redis 字符串结构和常用命令
    Redis实现存取数据+数据存取
    Spring 使用RedisTemplate操作Redis
    使用 java替换web项目的web.xml
    SQL server 从创建数据库到查询数据的简单操作
    SQL server 安装教程
    IntelliJ IDEA 注册码(因为之前的地址被封杀了,所以换了个地址)
    对程序员有帮助的几个非技术实用链接(点我,你不会后悔的)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3869840.html
Copyright © 2011-2022 走看看