int VpuDec::set_DecOpenParam() { int ret = -1; memset(&handle,0,sizeof(DecHandle)); DecOpenParam oparam;// = {0}; memset(&oparam, 0, sizeof(DecOpenParam)); //must to clean to 0 allocHwBuffer(Dec_RingBuf_Size); oparam.bitstreamFormat = (CodStd)dec_format; oparam.bitstreamBuffer = Dec_bufZone.pStartAddr; oparam.bitstreamBufferSize = Dec_bufZone.bufSize; oparam.pBitStream = (Uint8 *)Dec_bufZone.vStartaddr; oparam.reorderEnable = 1; oparam.mp4DeblkEnable = 0; oparam.chromaInterleave = 0; oparam.mp4Class = 0; if (cpu_is_mx6x()) oparam.avcExtension = 0; oparam.mjpg_thumbNailDecEnable = 0; oparam.mapType = 0; oparam.tiled2LinearEnable = 0; oparam.bitstreamMode = 1; oparam.jpgLineBufferMode = 1; if (dec_format == STD_AVC) { ps_mem_desc.size = PS_SAVE_SIZE; ret = IOGetPhyMem(&ps_mem_desc); if (ret){ printf("Unable to obtain physical ps save mem,LINE%d\n",__LINE__); return -1; } oparam.psSaveBuffer = ps_mem_desc.phy_addr; oparam.psSaveBufferSize = PS_SAVE_SIZE; } //printf("bitstreamFormat %x, bitstreamBuffer %x,bitstreamBufferSize %d, pBitStream %x\n",oparam.bitstreamFormat, //oparam.bitstreamBuffer,oparam.bitstreamBufferSize,oparam.pBitStream); ret = vpu_DecOpen(&handle, &oparam); if (ret != RETCODE_SUCCESS) { printf("vpu_DecOpen failed, ret:%d\n", ret); return -1; } return 0; }
static void decoder_renderer_setup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags) { if (videoFormat != VIDEO_FORMAT_H264) { fprintf(stderr, "Video format not supported\n"); exit(1); } struct mxcfb_gbl_alpha alpha; dbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; dbuf.memory = V4L2_MEMORY_MMAP; int fd_fb = open("/dev/fb0", O_RDWR, 0); if (fd_fb < 0){ fprintf(stderr, "Can't access framebuffer\n"); exit(EXIT_FAILURE); } alpha.alpha = 0; alpha.enable = 1; if (ioctl(fd_fb, MXCFB_SET_GBL_ALPHA, &alpha) < 0){ fprintf(stderr, "Can't set framebuffer output\n"); exit(EXIT_FAILURE); } close(fd_fb); mem_desc.size = STREAM_BUF_SIZE; if (IOGetPhyMem(&mem_desc)){ fprintf(stderr, "Can't get physical memory address\n"); exit(EXIT_FAILURE); } if (IOGetVirtMem(&mem_desc) <= 0) { fprintf(stderr, "Can't get virtual memory address\n"); exit(EXIT_FAILURE); } ps_mem_desc.size = PS_SAVE_SIZE; if (IOGetPhyMem(&ps_mem_desc)) { fprintf(stderr, "Can't get physical memory address\n"); exit(EXIT_FAILURE); } DecOpenParam oparam = {0}; oparam.bitstreamFormat = STD_AVC; oparam.bitstreamBuffer = mem_desc.phy_addr; oparam.bitstreamBufferSize = STREAM_BUF_SIZE; oparam.pBitStream = (Uint8 *) mem_desc.virt_uaddr; oparam.reorderEnable = 1; oparam.mp4DeblkEnable = 0; oparam.chromaInterleave = 0; oparam.avcExtension = oparam.mp4Class = 0; oparam.mjpg_thumbNailDecEnable = 0; oparam.mapType = LINEAR_FRAME_MAP; oparam.tiled2LinearEnable = 0; oparam.bitstreamMode = 1; oparam.psSaveBuffer = ps_mem_desc.phy_addr; oparam.psSaveBufferSize = PS_SAVE_SIZE; if (vpu_DecOpen(&handle, &oparam) != RETCODE_SUCCESS) { fprintf(stderr, "Can't open video decoder\n"); exit(EXIT_FAILURE); } decparam.dispReorderBuf = 0; decparam.skipframeMode = 0; decparam.skipframeNum = 0; decparam.iframeSearchEnable = 0; regfbcount = MIN_FRAME_BUFFER_COUNT + 2; int picWidth = ((width + 15) & ~15); int picHeight = ((height + 15) & ~15); stride = picWidth; int phy_slicebuf_size = WORST_SLICE_SIZE * 1024; slice_mem_desc.size = phy_slicebuf_size; if (IOGetPhyMem(&slice_mem_desc)){ fprintf(stderr, "Can't get slice physical address\n"); exit(EXIT_FAILURE); } fb = calloc(regfbcount, sizeof(FrameBuffer)); if (fb == NULL) { fprintf(stderr, "Can't allocate framebuffers\n"); exit(EXIT_FAILURE); } char v4l_device[16], node[8]; sprintf(node, "%d", 17); strcpy(v4l_device, "/dev/video"); strcat(v4l_device, node); fd = open(v4l_device, O_RDWR, 0); if (fd < 0){ fprintf(stderr, "Can't access video output\n"); exit(EXIT_FAILURE); } struct v4l2_format fmt = {0}; fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; fmt.fmt.pix.width = picWidth; fmt.fmt.pix.height = picHeight; fmt.fmt.pix.bytesperline = picWidth; fmt.fmt.pix.field = V4L2_FIELD_ANY; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { fprintf(stderr, "Can't set source video format\n"); exit(EXIT_FAILURE); } if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) { fprintf(stderr, "Can't set output video format\n"); exit(EXIT_FAILURE); } struct v4l2_requestbuffers reqbuf = {0}; reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; reqbuf.memory = V4L2_MEMORY_MMAP; reqbuf.count = regfbcount; struct v4l_buf* buffers[regfbcount]; if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) { fprintf(stderr, "Can't get video buffers\n"); exit(EXIT_FAILURE); } if (reqbuf.count < regfbcount) { fprintf(stderr, "Not enough video buffers\n"); exit(EXIT_FAILURE); } for (int i = 0; i < regfbcount; i++) { struct v4l2_buffer buffer = {0}; struct v4l_buf *buf; buf = calloc(1, sizeof(struct v4l_buf)); if (buf == NULL) { fprintf(stderr, "Not enough memory\n"); exit(EXIT_FAILURE); } buffers[i] = buf; buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; buffer.memory = V4L2_MEMORY_MMAP; buffer.index = i; if (ioctl(fd, VIDIOC_QUERYBUF, &buffer) < 0) { fprintf(stderr, "Can't get video buffer\n"); exit(EXIT_FAILURE); } buf->start = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buffer.m.offset); /* * Workaround for new V4L interface change, this change * will be removed after V4L driver is updated for this. * Need to call QUERYBUF ioctl again after mmap. */ if (ioctl(fd, VIDIOC_QUERYBUF, &buffer) < 0) { fprintf(stderr, "Can't set source video format\n"); exit(EXIT_FAILURE); } buf->offset = buffer.m.offset; buf->length = buffer.length; if (buf->start == MAP_FAILED) { fprintf(stderr, "Failed to map video buffer\n"); exit(EXIT_FAILURE); } } int img_size = stride * picHeight; vpu_mem_desc *mvcol_md = NULL; int mjpg_fmt = MODE420; int divX = (mjpg_fmt == MODE420 || mjpg_fmt == MODE422) ? 2 : 1; int divY = (mjpg_fmt == MODE420 || mjpg_fmt == MODE224) ? 2 : 1; mvcol_md = calloc(regfbcount, sizeof(vpu_mem_desc)); for (int i = 0; i < regfbcount; i++) { fb[i].myIndex = i; fb[i].bufY = buffers[i]->offset; fb[i].bufCb = fb[i].bufY + img_size; fb[i].bufCr = fb[i].bufCb + (img_size / divX / divY); /* allocate MvCol buffer here */ memset(&mvcol_md[i], 0, sizeof(vpu_mem_desc)); mvcol_md[i].size = img_size / divX / divY; if (IOGetPhyMem(&mvcol_md[i])) { fprintf(stderr, "Can't get physical address of colomn buffer\n"); exit(EXIT_FAILURE); } fb[i].bufMvCol = mvcol_md[i].phy_addr; } bufinfo.avcSliceBufInfo.bufferBase = slice_mem_desc.phy_addr; bufinfo.avcSliceBufInfo.bufferSize = phy_slicebuf_size; bufinfo.maxDecFrmInfo.maxMbX = stride / 16; bufinfo.maxDecFrmInfo.maxMbY = picHeight / 16; bufinfo.maxDecFrmInfo.maxMbNum = stride * picHeight / 256; int delay = -1; vpu_DecGiveCommand(handle, DEC_SET_FRAME_DELAY, &delay); }
static void decoder_renderer_setup(int width, int height, int redrawRate, void* context, int drFlags) { struct mxcfb_gbl_alpha alpha; dbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; dbuf.memory = V4L2_MEMORY_MMAP; int fd_fb = open("/dev/fb0", O_RDWR, 0); if (fd_fb < 0){ fprintf(stderr, "Can't access framebuffer\n"); exit(EXIT_FAILURE); } alpha.alpha = 0; alpha.enable = 1; if (ioctl(fd_fb, MXCFB_SET_GBL_ALPHA, &alpha) < 0){ fprintf(stderr, "Can't set framebuffer output\n"); exit(EXIT_FAILURE); } close(fd_fb); mem_desc.size = STREAM_BUF_SIZE; if (IOGetPhyMem(&mem_desc)){ fprintf(stderr, "Can't get physical memory address\n"); exit(EXIT_FAILURE); } if (IOGetVirtMem(&mem_desc) <= 0) { fprintf(stderr, "Can't get virtual memory address\n"); exit(EXIT_FAILURE); } ps_mem_desc.size = PS_SAVE_SIZE; if (IOGetPhyMem(&ps_mem_desc)) { fprintf(stderr, "Can't get physical memory address\n"); exit(EXIT_FAILURE); } DecOpenParam oparam = {0}; oparam.bitstreamFormat = STD_AVC; oparam.bitstreamBuffer = mem_desc.phy_addr; oparam.bitstreamBufferSize = STREAM_BUF_SIZE; oparam.pBitStream = (Uint8 *) mem_desc.virt_uaddr; oparam.reorderEnable = 1; oparam.mp4DeblkEnable = 0; oparam.chromaInterleave = 0; oparam.avcExtension = oparam.mp4Class = 0; oparam.mjpg_thumbNailDecEnable = 0; oparam.mapType = LINEAR_FRAME_MAP; oparam.tiled2LinearEnable = 0; oparam.bitstreamMode = 1; oparam.psSaveBuffer = ps_mem_desc.phy_addr; oparam.psSaveBufferSize = PS_SAVE_SIZE; if (vpu_DecOpen(&handle, &oparam) != RETCODE_SUCCESS) { fprintf(stderr, "Can't open video decoder\n"); exit(EXIT_FAILURE); } decparam.dispReorderBuf = 0; decparam.skipframeMode = 0; decparam.skipframeNum = 0; decparam.iframeSearchEnable = 0; }
mjpeg_decoder_t::mjpeg_decoder_t(vpu_t &vpu) : w_(0) , h_(0) , ystride_(0) , uvstride_(0) , imgSize_(0) , handle_(0) , phy_bsbuf_addr(0) , phy_ps_buf(0) , phy_slice_buf(0) , phy_slicebuf_size(0) , virt_bsbuf_addr(0) , bsbuf_end(0) , numRead(0) , fbcount(0) , fb(0) , pfbpool(0) , mvcol_memdesc(0) , startedDecode_(false) , app_fbs(0) , decoder_fbs(0) , state_(ERR) { vpu_mem_desc mem_desc = {0}; mem_desc.size = STREAM_BUF_SIZE; int ret = IOGetPhyMem(&mem_desc); if (ret) { fprintf(stderr,"Unable to obtain physical mem\n"); return; } if (IOGetVirtMem(&mem_desc) <= 0) { fprintf(stderr,"Unable to obtain virtual mem\n"); IOFreePhyMem(&mem_desc); return; } vpu_mem_desc slice_mem_desc = {0}; phy_bsbuf_addr = mem_desc.phy_addr; virt_bsbuf_addr = mem_desc.virt_uaddr; bsbuf_end = virt_bsbuf_addr + mem_desc.size ; DecOpenParam oparam ; memset(&oparam,0,sizeof(oparam)); oparam.bitstreamFormat = STD_MJPG ; oparam.bitstreamBuffer = phy_bsbuf_addr; oparam.bitstreamBufferSize = STREAM_BUF_SIZE; oparam.reorderEnable = 1 ; oparam.mp4DeblkEnable = 0 ; oparam.dynamicAllocEnable = 1 ; oparam.psSaveBuffer = 0 ; oparam.psSaveBufferSize = 0 ; ret = vpu_DecOpen(&handle_, &oparam); if (ret != RETCODE_SUCCESS) { fprintf(stderr,"vpu_DecOpen failed: %d\n", ret); return ; } debugPrint("vpu_DecOpen success\n" ); ret = vpu_DecGiveCommand(handle_,DEC_SET_REPORT_USERDATA, &userData); debugPrint("vpu_DecGiveCommand: %d(DEC_SET_REPORT_USERDATA)/%d\n", DEC_SET_REPORT_USERDATA,ret); if (ret != RETCODE_SUCCESS) { fprintf(stderr, "Failed to set user data report, ret %d\n", ret ); return ; } else printf( "disabled userdata\n" ); /* Parse bitstream and get width/height/framerate etc */ ret = vpu_DecSetEscSeqInit(handle_, 1); if (ret != RETCODE_SUCCESS) { fprintf(stderr, "Failed to set Esc Seq, ret %d\n", ret ); return ; } else debugPrint("vpu_DecSetEscSeqInit(1): %d\n", ret); state_ = INIT ; }