Status MJPEGVideoDecoderBaseMFX::FindStartOfImage(MediaData * in) { CMemBuffInput source; JERRCODE jerr; if (!m_IsInit) return UMC_ERR_NOT_INITIALIZED; source.Open((uint8_t*) in->GetDataPointer(), in->GetDataSize()); jerr = m_decBase->SetSource(&source); if(JPEG_OK != jerr) return UMC_ERR_FAILED; jerr = m_decBase->FindSOI(); if(JPEG_ERR_BUFF == jerr) return UMC_ERR_NOT_ENOUGH_DATA; if(JPEG_OK != jerr) return UMC_ERR_FAILED; in->MoveDataPointer(m_decBase->m_BitStreamIn.GetNumUsedBytes()); return UMC_OK; }
Status MJPEGVideoDecoderBaseMFX::_GetFrameInfo(const uint8_t* pBitStream, size_t nSize) { int32_t nchannels; int32_t precision; JSS sampling; JCOLOR color; CMemBuffInput in; JERRCODE jerr; if (!m_IsInit) return UMC_ERR_NOT_INITIALIZED; in.Open(pBitStream,nSize); jerr = m_decBase->SetSource(&in); if(JPEG_OK != jerr) return UMC_ERR_FAILED; jerr = m_decBase->ReadHeader( &m_frameDims.width,&m_frameDims.height,&nchannels,&color,&sampling,&precision); if(JPEG_ERR_BUFF == jerr) return UMC_ERR_NOT_ENOUGH_DATA; if(JPEG_NOT_IMPLEMENTED == jerr) return UMC_ERR_NOT_IMPLEMENTED; if(JPEG_OK != jerr) return UMC_ERR_FAILED; m_frameSampling = (int) sampling; m_color = color; m_interleavedScan = m_decBase->IsInterleavedScan(); // frame is interleaved if clip height is twice more than JPEG frame height if (m_DecoderParams.info.interlace_type != PROGRESSIVE) { m_interleaved = true; m_frameDims.height *= 2; } return UMC_OK; }
int main(int argc, char* argv[]) { int i; double msec; double decTime; double encTime; Ipp8u* buf; IM_TYPE fmtIn; IM_TYPE fmtOut; ExcStatus res; CIppImage image; CommandLine cmdline; CFormatDetector detector; BaseStream::TSize cnt; BaseStream::TSize size; bool help_flag; bool is_raw = false; CStdFileInput fi; CStdFileOutput fo; CMemBuffInput mi; CMemBuffOutput mo; CmdOptions cmdOptions; cmdOptions.loops = 1; ippStaticInit(); copyright_(); // Common params cmdline.AddKey("i","input file name", cmdOptions.src, 1, (StringA)"uic_test_image.jpg", IT_UNKNOWN); cmdline.AddKey("o","output file name (out.jp2 - default)", cmdOptions.dst, 1, (StringA)"out.jp2", IT_UNKNOWN); cmdline.AddKey("r","treat input image as raw (0 - default)", is_raw, 0, 0, IT_UNKNOWN); cmdline.AddKey("t","advanced timing, 0 - disable (default); 1 - enable", cmdOptions.timing, 1, 0, IT_UNKNOWN); cmdline.AddKey("m","number of loops for advanced timing (1 - default)", cmdOptions.loops, 1, 1, IT_UNKNOWN); cmdline.AddKey("d", "print problem diagnostics messages", cmdOptions.verbose_mode, 0, 0, IT_UNKNOWN); cmdline.AddKey("n","number of threads", cmdOptions.nthreads, 1, 0, IT_UNKNOWN); cmdline.AddKey("h","help key", help_flag, 0, 0, IT_UNKNOWN); cmdline.AddKey("W","width resolution", cmdOptions.res_width, 1, 0, IT_RAW); cmdline.AddKey("H","height resolution", cmdOptions.res_height, 1, 0, IT_RAW); cmdline.AddKey("D","data offset", cmdOptions.data_offset, 1, 0, IT_RAW); cmdline.AddKey("C","color format: gray, rgb (default), rgba, cmyk", cmdOptions.color_format, 1, (StringA)"rgb", IT_RAW); cmdline.AddKey("P","pixel format: 8u (default), 16u, 16s, 32u, 32s, 32f", cmdOptions.pixel_format, 1, (StringA)"8u", IT_RAW); cmdline.AddKey("q","quality [1...100]", cmdOptions.jpg_quality, 1, 100, IT_JPEG); cmdline.AddKey("s","sampling, 0 - 444 (default); 1 - 422; 2 - 411", cmdOptions.sampling, 1, 0, IT_JPEG); cmdline.AddKey("j","jpeg encoder mode: b - BASELINE (8-bit lossy); e - EXTENDED (12-bit lossy); p - PROGRESSIVE (8-bit progressive); l - LOSSLESS (2-16 bit lossless)", cmdOptions.jmode, 1, (StringA)"b", IT_JPEG); cmdline.AddKey("q","quality [1...100]", cmdOptions.jpg_quality, 1, 100, IT_JPEG2000); cmdline.AddKey("l","encoding mode, 0 - lossy encode (default); 1 - lossless encoding", cmdOptions.lossless, 1, 0, IT_JPEG2000); cmdline.AddKey("f","activate all filters", cmdOptions.png_filter[4], 0, 0, IT_PNG); cmdline.AddKey("fs","add sub filter", cmdOptions.png_filter[0], 0, 0, IT_PNG); cmdline.AddKey("fu","add up filter", cmdOptions.png_filter[1], 0, 0, IT_PNG); cmdline.AddKey("fa","add average filter", cmdOptions.png_filter[2], 0, 0, IT_PNG); cmdline.AddKey("fp","add Paeth filter", cmdOptions.png_filter[3], 0, 0, IT_PNG); cmdline.AddKey("q","quality [1...255] (1 - lossless, default; less is better)", cmdOptions.jxr_quality, 1, 1, IT_JPEGXR); cmdline.AddKey("Q","planar alpha quality [1...255] (1 - lossless, default; less is better)", cmdOptions.jxr_aquality, 1, 1, IT_JPEGXR); // cmdline.AddKey("s","sampling, 0 - 444 (default); 1 - 422; 2 - 420", cmdOptions.sampling, 1, 0, IT_JPEGXR); // cmdline.AddKey("f","bitstream order, 0 - spatial (default); 1 - frequency", cmdOptions.bitstream, 1, 0, IT_JPEGXR); cmdline.AddKey("l","overlap mode, 0 - no overlap (default); 1 - overlap one; 2 - overlap two", cmdOptions.overlap, 1, 0, IT_JPEGXR); cmdline.AddKey("a","alpha mode, 0 - interleaved alpha (default); 1 - planar alpha", cmdOptions.alpha_mode, 1, 0, IT_JPEGXR); cmdline.AddKey("F","trim flexbits [0...15] (0 - all flexbits, default; 15 - no flexbits)", cmdOptions.trim, 1, 0, IT_JPEGXR); cmdline.AddKey("b","bands mode, 0 - all bands (default); 1 - no flexbits; 2 - no highpass; 3 - dc only", cmdOptions.bands, 1, 0, IT_JPEGXR); cmdline.AddKey("c","encode CMYK images directly, without color conversion", cmdOptions.cmyk_direct, 0, 0, IT_JPEGXR); cmdline.AddKey("v","color conversion bits shift value for 16-bit and 32-bit images [0...32]", cmdOptions.bits_shift, 1, -1, IT_JPEGXR); cmdline.AddKey("U","amount of tiles per rows and columns (1 1 - default)", cmdOptions.tiles_amount[0], 2, 1, IT_JPEGXR); cmdline.AddKey("X","maximum tiles size in macroblocks (0 0 - default; 1 = 16px; override U argument)", cmdOptions.tiles_sizes[0], 2, 0, IT_JPEGXR); #ifdef USE_TBB cmdline.AddKey("u","multithread mode, 0 - pipeline threading (threads limited to 3); 1 - tile threading (threads limited to number of tiles); 2 - mixed threading (default; threads limited to number of tiles + 3)", cmdOptions.jxr_thread_mode, 1, 2, IT_JPEGXR); #endif if(argc == 1) { cmdline.HelpMessage(format_str); return -1; } if(!cmdline.Parse(argv, argc, IT_UNKNOWN, IT_UNKNOWN)) { cmdline.HelpMessage(format_str); printf("Invalid argument!\n"); return -1; } if(help_flag) cmdline.HelpMessage(format_str); fmtOut = ImageFormatFromExtension((const char*)cmdOptions.dst); if(IT_UNKNOWN == fmtOut || IT_DICOM == fmtOut) { printf("Unsupported output image format!\n"); return -1; } if(!BaseStream::IsOk(fi.Open(cmdOptions.src))) { printf("Can not open input file!\n"); return 1; } if(!BaseStream::IsOk(fo.Open(cmdOptions.dst))) { printf("Can not open output file!\n"); return 1; } if(is_raw) fmtIn = IT_RAW; else fmtIn = detector.ImageFormat(fi); if(IT_UNKNOWN == fmtIn) { printf("Unsupported input image format!\n"); return -1; } if(!cmdline.Parse(argv, argc, fmtIn, fmtOut)) { if(!help_flag) cmdline.HelpMessage(format_str); printf("Invalid argument!\n"); return -1; } CheckParam(cmdOptions.timing, 0, 1); CheckParam(cmdOptions.loops, 1, IPP_MAX_16U); if(!cmdOptions.timing) { res = DecodeImage(fi, image, cmdOptions, fmtIn, NULL); if(!IsOk(res)) { printf("Error in DecodeImage finction!\n"); return 1; } } else { msec = 0.0; fi.Size(size); buf = (Ipp8u*)ippMalloc((int)size); if(0 == buf) return 1; res = fi.Read(buf, size, cnt); if(!IsOk(res)) return 1; #if !defined(__WIN32) printf("WARNING: initialization of CTimer may take long!\n"); #endif for(i = 0; i < cmdOptions.loops; i++) { mi.Open(buf, (int)size); res = DecodeImage(mi, image, cmdOptions, fmtIn, &decTime); if(!IsOk(res)) return 1; msec += decTime; mi.Close(); } ippFree(buf); decTime = msec / cmdOptions.loops; } printf("image: %s, %dx%dx%d, %d-bits %s, color: %s, sampling: %s\n", (const char*)cmdOptions.src, image.Width(), image.Height(), image.NChannels(), image.Precision(), pxformat_str[image.Format()], color_str[image.Color()], sampling_str[image.Sampling()]); if(cmdOptions.timing) printf("decode time: %.2f msec\n", decTime); if(!cmdOptions.timing) { res = EncodeImage(image, fo, cmdOptions, fmtOut, NULL); if(!IsOk(res)) { printf("Error in EncodeImage finction!\n"); return 1; } } else { BaseStream::TPosition pos = 0; msec = 0.0; size = image.Step()*image.Height()*2; buf = (Ipp8u*)ippMalloc((int)size); if(0 == buf) return 1; for(i = 0; i < cmdOptions.loops; i++) { mo.Open(buf, (int)size); res = EncodeImage(image, mo, cmdOptions, fmtOut, &encTime); if(!IsOk(res)) return 1; msec += encTime; mo.Position(pos); mo.Close(); } fo.Write(buf, pos, cnt); ippFree(buf); encTime = msec / cmdOptions.loops; } if(cmdOptions.timing) printf("encode time: %.2f msec\n", encTime); return 0; } // main()
Status MJPEGVideoDecoder::GetFrame(MediaData *pDataIn, MediaData *pDataOut) { CMemBuffInput memReader; JPEGInternalParams params; Status status; JERRCODE jStatus; if(!m_pDecoder) return UMC_ERR_NOT_INITIALIZED; if(!pDataOut) return UMC_ERR_NULL_PTR; if(!pDataIn) return UMC_ERR_NOT_ENOUGH_DATA; memReader.Open((Ipp8u*)pDataIn->GetDataPointer(), (Ipp32s)pDataIn->GetDataSize()); jStatus = m_pDecoder->SetSource(&memReader); if(JPEG_OK != jStatus) return UMC_ERR_FAILED; jStatus = m_pDecoder->ReadHeader(¶ms.size.width, ¶ms.size.height, ¶ms.iChannels, ¶ms.color, ¶ms.sampling, ¶ms.iBitDepth); if(JPEG_ERR_BUFF == jStatus) return UMC_ERR_NOT_ENOUGH_DATA; else if(JPEG_OK != jStatus) return UMC_ERR_FAILED; m_pDecoder->SetThreadingMode(JT_RSTI); // override unsupported source formats if(params.sampling == JS_244 || params.sampling == JS_OTHER) params.sampling = JS_444; // invalidate frame data if(invalidateFrame(¶ms, m_pIntParams)) { // treat frame as interlaced if clip height is twice more than JPEG frame height if(params.size.height == (Ipp32s)((m_params.m_info.videoInfo.m_iHeight >> 1))) m_bField = true; m_pIntParams->size = params.size; m_pIntParams->color = params.color; m_pIntParams->sampling = params.sampling; m_pIntParams->iChannels = params.iChannels; m_pIntParams->iBitDepth = params.iBitDepth; ColorFormat colorFormat; Ipp32u iMemAlloc = 0; // use planar output for YUV if(params.color == JC_YCBCR || params.color == JC_YCCK) { m_iDstStep[0] = params.size.width*((m_pIntParams->iBitDepth + 7)/8); iMemAlloc = m_iDstStep[0]*params.size.height; if(params.sampling == JS_444) { m_iDstStep[1] = m_iDstStep[2] = m_iDstStep[0]; iMemAlloc += ((m_iDstStep[1] + m_iDstStep[2])*params.size.height); } else if(params.sampling == JS_422 || params.sampling == JS_411) { m_iDstStep[1] = m_iDstStep[2] = (m_iDstStep[0] + 1)/2; iMemAlloc += ((m_iDstStep[1] + m_iDstStep[2])*params.size.height); } if(params.color == JC_YCCK) { m_iDstStep[3] = m_iDstStep[0]; iMemAlloc += (m_iDstStep[3]*params.size.height); } } else { m_iDstStep[0] = params.size.width*params.iChannels*((m_pIntParams->iBitDepth + 7)/8); iMemAlloc = m_iDstStep[0]*params.size.height; } if(!m_pMemoryAllocator) return UMC_ERR_ALLOC; status = m_pMemoryAllocator->Alloc(&m_frameMID, iMemAlloc, UMC_ALLOC_PERSISTENT, 16); if(UMC_OK != status) return UMC_ERR_ALLOC; m_pDst[0] = (Ipp8u*)m_pMemoryAllocator->Lock(m_frameMID); if(!m_pDst[0]) return UMC_ERR_ALLOC; if(params.color == JC_YCBCR || params.color == JC_YCCK) { for(Ipp32s i = 1; i < params.iChannels; i++) m_pDst[i] = m_pDst[i-1] + m_iDstStep[i-1]*params.size.height; if(params.iBitDepth <= 8) m_pDecoder->SetDestination(m_pDst, m_iDstStep, params.size, params.iChannels, params.color, params.sampling, 8); else m_pDecoder->SetDestination((Ipp16s**)m_pDst, m_iDstStep, params.size, params.iChannels, params.color, params.sampling, 16); } else { if(params.iBitDepth <= 8) m_pDecoder->SetDestination(m_pDst[0], m_iDstStep[0], params.size, params.iChannels, params.color, JS_444, 8); else m_pDecoder->SetDestination((Ipp16s*)m_pDst[0], m_iDstStep[0], params.size, params.iChannels, params.color, JS_444, 16); } switch(params.color) { case JC_GRAY: colorFormat = GRAY; break; case JC_RGB: colorFormat = RGB; break; case JC_BGR: colorFormat = BGR; break; case JC_CMYK: colorFormat = CMYK; break; case JC_BGRA: colorFormat = BGRA; break; case JC_RGBA: colorFormat = RGBA; break; case JC_YCBCR: if(params.sampling == JS_444) colorFormat = YUV444; else if(params.sampling == JS_422) colorFormat = YUV422; else if(params.sampling == JS_411) colorFormat = YUV420; else return UMC_ERR_UNSUPPORTED; break; case JC_YCCK: if(params.sampling == JS_444) colorFormat = YUV444A; else if(params.sampling == JS_422) colorFormat = YUV422A; else if(params.sampling == JS_411) colorFormat = YUV420A; else return UMC_ERR_UNSUPPORTED; break; default: return UMC_ERR_UNSUPPORTED; } m_lastDecodedFrame.Init(params.size.width, params.size.height, colorFormat, params.iBitDepth); if(params.color == JC_YCBCR) { m_lastDecodedFrame.SetPlaneDataPtr(m_pDst[0], 0); m_lastDecodedFrame.SetPlanePitch(m_iDstStep[0], 0); m_lastDecodedFrame.SetPlaneDataPtr(m_pDst[1], 1); m_lastDecodedFrame.SetPlanePitch(m_iDstStep[1], 1); m_lastDecodedFrame.SetPlaneDataPtr(m_pDst[2], 2); m_lastDecodedFrame.SetPlanePitch(m_iDstStep[2], 2); } else if(params.color == JC_YCCK) { m_lastDecodedFrame.SetPlaneDataPtr(m_pDst[0], 0); m_lastDecodedFrame.SetPlanePitch(m_iDstStep[0], 0); m_lastDecodedFrame.SetPlaneDataPtr(m_pDst[1], 1); m_lastDecodedFrame.SetPlanePitch(m_iDstStep[1], 1); m_lastDecodedFrame.SetPlaneDataPtr(m_pDst[2], 2); m_lastDecodedFrame.SetPlanePitch(m_iDstStep[2], 2); m_lastDecodedFrame.SetPlaneDataPtr(m_pDst[3], 3); m_lastDecodedFrame.SetPlanePitch(m_iDstStep[3], 3); } else { m_lastDecodedFrame.SetPlaneDataPtr(m_pDst[0], 0); m_lastDecodedFrame.SetPlanePitch(m_iDstStep[0], 0); } m_lastDecodedFrame.m_frameType = I_PICTURE; } m_lastDecodedFrame.m_fPTSStart = pDataIn->m_fPTSStart; if(m_bField) m_lastDecodedFrame.m_picStructure = (m_bFirstField)?PS_TOP_FIELD:PS_BOTTOM_FIELD; // check AVI1 header for interlace info if(m_pDecoder->IsAVI1App0Detected()) { if(m_pDecoder->GetAVI1App0Polarity() == 0) { m_bField = false; m_lastDecodedFrame.m_picStructure = PS_PROGRESSIVE; } else if(m_pDecoder->GetAVI1App0Polarity() == 1) { m_bField = true; m_lastDecodedFrame.m_picStructure = PS_TOP_FIELD; } else if(m_pDecoder->GetAVI1App0Polarity() == 2) { m_bField = true; m_lastDecodedFrame.m_picStructure = PS_BOTTOM_FIELD; } } jStatus = m_pDecoder->ReadData(); if(JPEG_ERR_BUFF == jStatus) return UMC_ERR_NOT_ENOUGH_DATA; else if(JPEG_OK != jStatus) return UMC_ERR_FAILED; pDataIn->MoveDataPointer(m_pDecoder->GetNumDecodedBytes()); m_pDecoder->Reset(); m_bFirstField = !m_bFirstField; // switch field status = m_pPostProcessor->GetFrame(&m_lastDecodedFrame, pDataOut); if(UMC_ERR_NOT_ENOUGH_DATA == status && pDataIn->GetDataSize() > 4) // second field is already in buffer, force additional loop with old data return UMC_ERR_SYNC; else if(UMC_OK != status) return status; m_params.m_iFramesCounter++; return UMC_OK; }