问题
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
.
回答1:
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.
回答2:
On some platforms, the hardware decoder does not create user-space YUV by default. You may try
OMXCodec::Create(…,
flags | OMXCodec::kClientNeedsFramebuffer);
回答3:
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.
来源:https://stackoverflow.com/questions/21717728/how-to-dump-yuv-from-omxcodec-decoding-output