TIndexer::TIndexer(const TIndexerConfig& config) : Config(config) , Offset(0) , ChunkNumber(0) { if (Config.Verbose) { cerr << "Indexer config:\n"; Config.Print(cerr); cerr << "===============\n"; } Encoder = CreateEncoder(Config.CompressionMethod); }
int encore(void *handle, int enc_opt, void *param1, void *param2) { Encoder *pEnc = (Encoder *) handle; switch (enc_opt) { case ENC_OPT_INIT: return CreateEncoder((ENC_PARAM *) param1); case ENC_OPT_RELEASE: return FreeEncoder(pEnc); case ENC_OPT_ENCODE: return EncodeFrame(pEnc, (ENC_FRAME *) param1, (ENC_RESULT *) param2, RC_MODE); case ENC_OPT_ENCODE_VBR: return EncodeFrame(pEnc, (ENC_FRAME *) param1, (ENC_RESULT *) param2, VBR_MODE); case ENC_OPT_ENCODE_EXT: return EncodeFrame(pEnc, (ENC_FRAME *) param1, (ENC_RESULT *) param2, EXT_MODE); default: return ENC_FAIL; } }
void Picture::SaveBitmapToFile(const std::wstring & path, IWICBitmap* bitmap) { auto wicFactory = PublicResource::GetGraphicsResource().WicImagingFactory.p; CComPtr<IWICStream> stream; CComPtr<IWICBitmapEncoder> encoder; CComPtr<IWICBitmapFrameEncode> frameEncoder; CComPtr<ID2D1Bitmap> newBitmap; WICPixelFormatGUID format = GUID_WICPixelFormat32bppPBGRA; wicFactory->CreateStream(&stream); UINT width, height; bitmap->GetSize(&width, &height); stream->InitializeFromFilename(path.data(), GENERIC_WRITE); HRESULT hr = wicFactory->CreateEncoder(Picture::PictureTypeParser(path), nullptr, &encoder); hr = encoder->Initialize(stream, WICBitmapEncoderNoCache); hr = encoder->CreateNewFrame(&frameEncoder, nullptr); hr = frameEncoder->Initialize(nullptr); hr = frameEncoder->SetSize(width, height); hr = frameEncoder->SetPixelFormat(&format); hr = frameEncoder->WriteSource(bitmap,nullptr); hr = frameEncoder->Commit(); hr = encoder->Commit(); }
static block_t *ImageWrite( image_handler_t *p_image, picture_t *p_pic, video_format_t *p_fmt_in, video_format_t *p_fmt_out ) { block_t *p_block; /* Check if we can reuse the current encoder */ if( p_image->p_enc && ( p_image->p_enc->fmt_out.i_codec != p_fmt_out->i_chroma || p_image->p_enc->fmt_out.video.i_width != p_fmt_out->i_width || p_image->p_enc->fmt_out.video.i_height != p_fmt_out->i_height ) ) { DeleteEncoder( p_image->p_enc ); p_image->p_enc = 0; } /* Start an encoder */ if( !p_image->p_enc ) { p_image->p_enc = CreateEncoder( p_image->p_parent, p_fmt_in, p_fmt_out ); if( !p_image->p_enc ) return NULL; } /* Check if we need chroma conversion or resizing */ if( p_image->p_enc->fmt_in.video.i_chroma != p_fmt_in->i_chroma || p_image->p_enc->fmt_in.video.i_width != p_fmt_in->i_width || p_image->p_enc->fmt_in.video.i_height != p_fmt_in->i_height ) { picture_t *p_tmp_pic; if( p_image->p_filter ) if( p_image->p_filter->fmt_in.video.i_chroma != p_fmt_in->i_chroma || p_image->p_filter->fmt_out.video.i_chroma != p_image->p_enc->fmt_in.video.i_chroma ) { /* We need to restart a new filter */ DeleteFilter( p_image->p_filter ); p_image->p_filter = 0; } /* Start a filter */ if( !p_image->p_filter ) { es_format_t fmt_in; es_format_Init( &fmt_in, VIDEO_ES, p_fmt_in->i_chroma ); fmt_in.video = *p_fmt_in; p_image->p_filter = CreateFilter( p_image->p_parent, &fmt_in, &p_image->p_enc->fmt_in.video ); if( !p_image->p_filter ) { return NULL; } } else { /* Filters should handle on-the-fly size changes */ p_image->p_filter->fmt_in.i_codec = p_fmt_in->i_chroma; p_image->p_filter->fmt_out.video = *p_fmt_in; p_image->p_filter->fmt_out.i_codec =p_image->p_enc->fmt_in.i_codec; p_image->p_filter->fmt_out.video = p_image->p_enc->fmt_in.video; } picture_Hold( p_pic ); p_tmp_pic = p_image->p_filter->pf_video_filter( p_image->p_filter, p_pic ); if( likely(p_tmp_pic != NULL) ) { p_block = p_image->p_enc->pf_encode_video( p_image->p_enc, p_tmp_pic ); picture_Release( p_tmp_pic ); } else p_block = NULL; } else { p_block = p_image->p_enc->pf_encode_video( p_image->p_enc, p_pic ); } if( !p_block ) { msg_Dbg( p_image->p_parent, "no image encoded" ); return 0; } return p_block; }
// 打开 bool CVideoEncodeVt::Open(const STRUCT_PUSH_STREAM_PARAM& aPushStreamParam) { if(m_bOpen) return true; int ret = 0; CFMutableDictionaryRef pixelBufferInfo = NULL; CMVideoCodecType codecType = kCMVideoCodecType_H264; CFStringRef profileLevel = NULL; do { m_bCompressErr = false; m_bHasBFrames = false; m_iEntropy = H264_ENTROPY_NOT_SET; m_iProfile = H264_PROF_HIGH; m_iLevel = 0; m_iFrameRate = aPushStreamParam.iVideoFrameRate; //参数检查 if(m_iProfile == H264_PROF_BASELINE) { m_bHasBFrames = false; if(H264_CABAC == m_iEntropy) { m_iEntropy = H264_ENTROPY_NOT_SET; } } m_iDtsDelta = m_bHasBFrames ? -1 : 0; //取得profile level ret = GetProfileLevel(m_bHasBFrames, m_iProfile, m_iLevel, &profileLevel); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "GetProfileLevel failed!"); assert(false); break; } //取得pixel buffer info ret = GetCVPixelBufferInfo(aPushStreamParam.iVideoPushStreamWidth, aPushStreamParam.iVideoPushStreamHeight, &pixelBufferInfo); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CreateCVPixelBufferInfo failed!"); assert(false); break; } //清空编码缓存队列 ClearEncodeBuffQueue(); //获得附加数据 ret = GetExtraData(aPushStreamParam, codecType, profileLevel, pixelBufferInfo); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "EncExtraData failed!"); assert(false); break; } //创建编码器 ret = CreateEncoder(aPushStreamParam, codecType, profileLevel, pixelBufferInfo, &m_EncodeSession); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CreateEncoder failed!"); assert(false); break; } //是否使用B帧 CFBooleanRef hasBFrames; ret = VTSessionCopyProperty(m_EncodeSession, kVTCompressionPropertyKey_AllowFrameReordering, kCFAllocatorDefault, &hasBFrames); if (0 == ret) { m_bHasBFrames = CFBooleanGetValue(hasBFrames); CFRelease(hasBFrames); } }while(0); if (NULL != pixelBufferInfo) { CFRelease(pixelBufferInfo); } m_bOpen = ret == 0 ? true : false; return m_bOpen; }
int CVideoEncodeVt::GetExtraData(const STRUCT_PUSH_STREAM_PARAM& aPushStreamParam, CMVideoCodecType aeCodecType, CFStringRef aProfileLevel, CFDictionaryRef aPixelBufferInfo) { int ret = 0; AVFrame* pFrame = NULL; VTCompressionSessionRef session = NULL; CMSampleBufferRef sampleBuf = NULL; do { //创建编码器 ret = CreateEncoder(aPushStreamParam, aeCodecType, aProfileLevel, aPixelBufferInfo, &session); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CreateEncoder failed!"); assert(false); break; } //创建一个avframe,并分配缓存,设置参数 pFrame = av_frame_alloc(); if(NULL == pFrame) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "av_frame_alloc failed!"); assert(false); break; } int iWidth = aPushStreamParam.iVideoPushStreamWidth; int iHeight = aPushStreamParam.iVideoPushStreamHeight; int iYSize = iWidth * iHeight; int iUVSize = (iWidth / 2) * (iHeight / 2); pFrame->buf[0] = av_buffer_alloc(iYSize + iUVSize * 2); if(NULL == pFrame->buf[0]) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "av_buffer_alloc failed!"); assert(false); break; } pFrame->data[0] = pFrame->buf[0]->data; pFrame->data[1] = pFrame->buf[0]->data + iYSize; pFrame->data[2] = pFrame->buf[0]->data + iYSize + iUVSize; memset(pFrame->data[0], 0, iYSize); memset(pFrame->data[1], 128, iUVSize); memset(pFrame->data[2], 128, iUVSize); pFrame->linesize[0] = iWidth; pFrame->linesize[1] = (iWidth + 1) / 2; pFrame->linesize[2] = (iWidth + 1) / 2; pFrame->format = AV_PIX_FMT_YUV420P; pFrame->width = iWidth; pFrame->height = iHeight; pFrame->pts = 0; //编码 ret = EncodeFrame(pFrame, session); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "EncodeFrame failed!"); assert(false); break; } //等待编码结束 ret = VTCompressionSessionCompleteFrames(session, kCMTimeIndefinite); if(0 != ret) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "VTCompressionSessionCompleteFrames failed!"); break; } //取得编码后的数据 ret = PopBuff(&sampleBuf); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "PopBuff failed!"); assert(false); break; } }while(0); if(NULL != sampleBuf) { CFRelease(sampleBuf); sampleBuf = NULL; } if(NULL != pFrame) { av_frame_unref(pFrame); av_frame_free(&pFrame); } if(NULL != session) { CFRelease(session); session = NULL; } assert(0 == ret && m_pExtraData && m_iExtraDataSize > 0); return ret; }