HRESULT AllocLAVFrameBuffers(LAVFrame *pFrame, ptrdiff_t stride) { LAVPixFmtDesc desc = getPixelFormatDesc(pFrame->format); if (stride < pFrame->width) { // Ensure alignment of at least 32 on all planes stride = FFALIGN(pFrame->width, 64); } stride *= desc.codedbytes; int alignedHeight = FFALIGN(pFrame->height, 2); memset(pFrame->data, 0, sizeof(pFrame->data)); memset(pFrame->stereo, 0, sizeof(pFrame->stereo)); memset(pFrame->stride, 0, sizeof(pFrame->stride)); for (int plane = 0; plane < desc.planes; plane++) { ptrdiff_t planeStride = stride / desc.planeWidth[plane]; size_t size = planeStride * (alignedHeight / desc.planeHeight[plane]); pFrame->data[plane] = (BYTE *)_aligned_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE, 64); pFrame->stride[plane] = planeStride; } if (pFrame->flags & LAV_FRAME_FLAG_MVC) { for (int plane = 0; plane < desc.planes; plane++) { size_t size = pFrame->stride[plane] * (alignedHeight / desc.planeHeight[plane]); pFrame->stereo[plane] = (BYTE *)_aligned_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE, 64); } } pFrame->destruct = &free_buffers; pFrame->flags |= LAV_FRAME_FLAG_BUFFER_MODIFY; return S_OK; }
HRESULT CopyLAVFrame(LAVFrame *pSrc, LAVFrame **ppDst) { ASSERT(pSrc->format != LAVPixFmt_DXVA2); *ppDst = (LAVFrame *)CoTaskMemAlloc(sizeof(LAVFrame)); if (!*ppDst) return E_OUTOFMEMORY; **ppDst = *pSrc; (*ppDst)->destruct = nullptr; (*ppDst)->priv_data = nullptr; AllocLAVFrameBuffers(*ppDst); LAVPixFmtDesc desc = getPixelFormatDesc(pSrc->format); for (int plane = 0; plane < desc.planes; plane++) { size_t linesize = (pSrc->width / desc.planeWidth[plane]) * desc.codedbytes; BYTE *dst = (*ppDst)->data[plane]; BYTE *src = pSrc->data[plane]; if (!dst || !src) return E_FAIL; for (int i = 0; i < (pSrc->height / desc.planeHeight[plane]); i++) { memcpy(dst, src, linesize); dst += (*ppDst)->stride[plane]; src += pSrc->stride[plane]; } } return S_OK; }
HRESULT CopyLAVFrame(LAVFrame *pSrc, LAVFrame **ppDst) { ASSERT(pSrc->format != LAVPixFmt_DXVA2); *ppDst = (LAVFrame *)CoTaskMemAlloc(sizeof(LAVFrame)); if (!*ppDst) return E_OUTOFMEMORY; **ppDst = *pSrc; (*ppDst)->destruct = nullptr; (*ppDst)->priv_data = nullptr; HRESULT hr = AllocLAVFrameBuffers(*ppDst); if (FAILED(hr)) return hr; LAVPixFmtDesc desc = getPixelFormatDesc(pSrc->format); for (int plane = 0; plane < desc.planes; plane++) { size_t linesize = (pSrc->width / desc.planeWidth[plane]) * desc.codedbytes; BYTE *dst = (*ppDst)->data[plane]; BYTE *src = pSrc->data[plane]; if (!dst || !src) return E_FAIL; for (int i = 0; i < (pSrc->height / desc.planeHeight[plane]); i++) { memcpy(dst, src, linesize); dst += (*ppDst)->stride[plane]; src += pSrc->stride[plane]; } if (pSrc->flags & LAV_FRAME_FLAG_MVC) { dst = (*ppDst)->stereo[plane]; src = pSrc->stereo[plane]; if (!dst || !src) return E_FAIL; for (int i = 0; i < (pSrc->height / desc.planeHeight[plane]); i++) { memcpy(dst, src, linesize); dst += (*ppDst)->stride[plane]; src += pSrc->stride[plane]; } } } (*ppDst)->side_data = nullptr; (*ppDst)->side_data_count = 0; for (int i = 0; i < pSrc->side_data_count; i++) { BYTE * p = AddLAVFrameSideData(*ppDst, pSrc->side_data[i].guidType, pSrc->side_data[i].size); if (p) memcpy(p, pSrc->side_data[i].data, pSrc->side_data[i].size); } return S_OK; }