int AvcDecoder_OMX::mfc_dec_slice(unsigned char* data, unsigned int size, OMX_BOOL MultiSliceFlag) { SSBSIP_H264_STREAM_INFO avcd_info; int flag_video_frame = 0; if(m_mfc_flag_create == 0) { LOGE("mfc codec not yes created \n"); return -1; } flag_video_frame = mfc_flag_video_frame(data, size); if(flag_video_frame < 0) { LOGE("mfc_flag_video_frame error \n"); return -1; } // yj: multi-slice if(flag_video_frame == 1 && MultiSliceFlag == OMX_TRUE) flag_video_frame = 0; if(flag_video_frame == 1) { memcpy(m_mfc_buffer_now, delimiter_h264, 4); m_mfc_buffer_now += 4; m_mfc_buffer_size += 4; memcpy(m_mfc_buffer_now, data, size); m_mfc_buffer_now += size; m_mfc_buffer_size += size; if(m_mfc_flag_info_out == 0) { if(SsbSipH264DecodeExe(m_mfc_handle, m_mfc_buffer_size) < 0) { LOGE("SsbSipH264DecodeExe for GetConfig fail \n"); return -1; } if(SsbSipH264DecodeGetConfig(m_mfc_handle, H264_DEC_GETCONF_STREAMINFO, &avcd_info) < 0) { LOGE("SsbSipH264DecodeGetConfig fail\n"); return -1; } iDisplay_Width = avcd_info.width; iDisplay_Height = avcd_info.height; m_mfc_flag_info_out = 1; } if(SsbSipH264DecodeExe(m_mfc_handle, m_mfc_buffer_size) < 0) { LOGE("SsbSipH264DecodeExe(Main) fail \n"); return -1; } m_mfc_buffer_now = m_mfc_buffer_base; m_mfc_buffer_size = 0; } else { memcpy(m_mfc_buffer_now, delimiter_h264, 4); m_mfc_buffer_now += 4; m_mfc_buffer_size += 4; memcpy(m_mfc_buffer_now, data, size); m_mfc_buffer_now += size; m_mfc_buffer_size += size; return 0; } return 1; }
int Test_Display_H264(int argc, char **argv) { void *pStrmBuf; int nFrameLeng = 0; unsigned int pYUVBuf[2]; int is_first; struct pollfd test_fd; struct stat s; FRAMEX_CTX *pFrameExCtx; // frame extractor context FRAMEX_STRM_PTR file_strm; SSBSIP_H264_STREAM_INFO stream_info; s3c_pp_params_t pp_param; s3c_win_info_t osd_info_to_driver; struct fb_fix_screeninfo lcd_info; #ifdef FPS struct timeval start, stop; unsigned int time = 0; int frame_cnt = 0; #endif if(signal(SIGINT, sig_del_h264) == SIG_ERR) { printf("Sinal Error\n"); } if (argc != 3) { printf("Usage : #./mfc <file name> <run mode>\n"); printf(" - <file name> : H.264 file to be displayed.\n"); printf(" - <run mode> : 0 (PP DMA Mode), 1 (PP FIFO Mode)\n"); return -1; } // in file open in_fd = open(argv[1], O_RDONLY); if(in_fd < 0) { printf("Input file open failed\n"); return -1; } // get input file size fstat(in_fd, &s); file_size = s.st_size; // mapping input file to memory in_addr = (char *)mmap(0, file_size, PROT_READ, MAP_SHARED, in_fd, 0); if(in_addr == NULL) { printf("input file memory mapping failed\n"); return -1; } // Post processor open pp_fd = open(PP_DEV_NAME, O_RDWR|O_NONBLOCK); if(pp_fd < 0) { printf("Post processor open error\n"); return -1; } // LCD frame buffer open fb_fd = open(FB_DEV_NAME, O_RDWR|O_NDELAY); if(fb_fd < 0) { printf("LCD frame buffer open error\n"); return -1; } /////////////////////////////////// // 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(); if (handle == NULL) { printf("H264_Dec_Init Failed.\n"); return -1; } ///////////////////////////////////////////// /// 2. Obtaining the Input Buffer /// /// (SsbSipH264DecodeGetInBuf) /// ///////////////////////////////////////////// pStrmBuf = SsbSipH264DecodeGetInBuf(handle, nFrameLeng); if (pStrmBuf == NULL) { printf("SsbSipH264DecodeGetInBuf Failed.\n"); SsbSipH264DecodeDeInit(handle); return -1; } //////////////////////////////////// // H264 CONFIG stream extraction // //////////////////////////////////// nFrameLeng = ExtractConfigStreamH264(pFrameExCtx, &file_strm, pStrmBuf, INPUT_BUFFER_SIZE, NULL); printf("nFrameLeng = %d\n", nFrameLeng); //////////////////////////////////////////////////////////////// /// 3. Configuring the instance with the config stream /// /// (SsbSipH264DecodeExe) /// //////////////////////////////////////////////////////////////// if (SsbSipH264DecodeExe(handle, nFrameLeng) != SSBSIP_H264_DEC_RET_OK) { printf("H.264 Decoder Configuration Failed.\n"); return -1; } ///////////////////////////////////// /// 4. Get stream information /// ///////////////////////////////////// SsbSipH264DecodeGetConfig(handle, H264_DEC_GETCONF_STREAMINFO, &stream_info); printf("\t<STREAMINFO> width=%d height=%d buf_width=%d buf_height=%d.\n", \ stream_info.width, stream_info.height, stream_info.buf_width, stream_info.buf_height); // set post processor configuration 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; 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; if ( atoi (argv[2]) == 0 ) pp_param.out_path = DMA_ONESHOT; else { pp_param.out_path = FIFO_FREERUN; pp_param.scan_mode = PROGRESSIVE_MODE; } 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 #ifdef RGB24BPP fb_size = pp_param.dst_full_width * pp_param.dst_full_height * 4; // RGB888 #endif fb_addr = (char *)mmap(0, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0); if (fb_addr == NULL) { printf("LCD frame buffer mmap failed\n"); return -1; } osd_info_to_driver.Bpp = FB0_BPP; // RGB16 osd_info_to_driver.LeftTop_x = 0; osd_info_to_driver.LeftTop_y = 0; osd_info_to_driver.Width = FB0_WIDTH; // display width osd_info_to_driver.Height = FB0_HEIGHT; // display height // set OSD's information if(ioctl(fb_fd, SET_OSD_INFO, &osd_info_to_driver)) { printf("Some problem with the ioctl SET_OSD_INFO\n"); return -1; } ioctl(fb_fd, SET_OSD_START); if ( FIFO_FREERUN == pp_param.out_path ) { is_first = 1; } while(1) { #ifdef FPS gettimeofday(&start, NULL); #endif ////////////////////////////////// /// 5. DECODE /// /// (SsbSipH264DecodeExe) /// ////////////////////////////////// if (SsbSipH264DecodeExe(handle, nFrameLeng) != SSBSIP_H264_DEC_RET_OK) break; ////////////////////////////////////////////// /// 6. Obtaining the Output Buffer /// /// (SsbSipH264DecodeGetOutBuf) /// ////////////////////////////////////////////// SsbSipH264DecodeGetConfig(handle, H264_DEC_GETCONF_PHYADDR_FRAM_BUF, pYUVBuf); ///////////////////////////// // 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가 입력으로 넣어야 한다. if ( FIFO_FREERUN == pp_param.out_path ) { if ( is_first ) { pp_param.src_buf_addr_phy = pYUVBuf[0]; ioctl(pp_fd, S3C_PP_SET_SRC_BUF_ADDR_PHY, &pp_param); ioctl(pp_fd, S3C_PP_START); is_first = 0; } else { pp_param.src_next_buf_addr_phy = pYUVBuf[0]; ioctl(pp_fd, S3C_PP_SET_SRC_BUF_NEXT_ADDR_PHY, &pp_param); } } else { pp_param.src_buf_addr_phy = pYUVBuf[0]; 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); test_fd.fd = pp_fd; test_fd.events = POLLOUT|POLLERR; poll(&test_fd, 1, 3000); ioctl(pp_fd, S3C_PP_START); } #ifdef FPS gettimeofday(&stop, NULL); time += measureTime(&start, &stop); frame_cnt++; #endif } #ifdef FPS printf("Display Time : %u, Frame Count : %d, FPS : %f\n", time, frame_cnt, (float)frame_cnt*1000/time); #endif SsbSipH264DecodeDeInit(handle); munmap(in_addr, file_size); munmap(fb_addr, fb_size); close(pp_fd); close(fb_fd); close(in_fd); return 0; }