How to dump YUV from OMXCodec decoding output

2019-01-20 05:44发布

I'd like to dump YUV data from OMXCodec decoding output. It's MediaBuffer type. It's impossible to access data() pointer.

If I try to access data, crash happens due to the check code below.

frameworks/av/media/libstagefright/MediaBuffer.cpp:119 CHECK(mGraphicBuffer == NULL) failed.

Please let me know the solution to extract YUV data from this MediaBuffer.

3条回答
一夜七次
2楼-- · 2019-01-20 06:04

From the MediaBuffer, I feel that the following should be functional. I haven't tried the same yet and have worked with rg2's solution i.e. directly based on gralloc handle, but feel that the following should also be functional.

 sp<GraphicBuffer> mCurrGraphicBuffer;
 void *vaddr;

 err = source->read(&buffer, &options); // Where buffer is of MediaBuffer type

 mCurrGraphicBuffer = buffer->graphicBuffer();
 width  = mCurrGraphicBuffer->getWidth();
 height = mCurrGraphicBuffer->getWidth();
 format = mCurrGraphicBuffer->getFormat();

 mCurrGraphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, &vaddr);
 //Dump the YUV file based on the vaddr, width, height, format
 mCurrGraphicBuffer->unlock();

EDIT:

In order for the aforementioned solution to work, the actual GraphicBuffer should be created or allocated with appropriate usage flags i.e. the buffer should be created with a hint that CPU would be accessing the same. Else, -EINVAL would be returned as per the documentation in gralloc.

查看更多
男人必须洒脱
3楼-- · 2019-01-20 06:17

On some platforms, the hardware decoder does not create user-space YUV by default. You may try

OMXCodec::Create(…,
    flags | OMXCodec::kClientNeedsFramebuffer);
查看更多
甜甜的少女心
4楼-- · 2019-01-20 06:28

What platform are you using?

1) Usually the easiest way to get output buffer dump is to do it in vendor OMX IL (in every vendor impl which I worked there were ready functions/macros to do it)

2) If not you should try to dump buffer in ACodec onFillBufferDone (you need to differentiate between audio/video) or onOutputBufferDrained, you must get mGraphicBuffer and get from it raw buffer - encapsulation is platform dependent eg for qc it would be

void const *buf = (void const*)((private_handle_t*)(info->mGraphicBuffer->handle))->base;

Assuming that info is (in ACodec::onOutputBufferDrained)

    BufferInfo *info =
    mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);

In OMXCodec case you can make the same at the end of OMXCodec::read Returned buf just save into the file, size to be written will be WxHxPixelRatio.

查看更多
登录 后发表回答