Как вывести YUV из вывода декодирования OMXCodec
Я хотел бы бросить YUV
данные из OMXCodec
декодирование вывода. Это MediaBuffer
тип. Невозможно получить доступ к указателю data().
Если я пытаюсь получить доступ к данным, происходит сбой из-за кода проверки ниже.
frameworks/av/media/libstagefright/MediaBuffer.cpp:119 CHECK(mGraphicBuffer == NULL) failed.
Пожалуйста, дайте мне знать решение для извлечения YUV
данные из этого MediaBuffer
,
3 ответа
От MediaBuffer
Я чувствую, что следующее должно быть функциональным. Я еще не пробовал то же самое и работал с решением rg2, то есть непосредственно на основе gralloc
обрабатывать, но чувствую, что следующее также должно быть функциональным.
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();
РЕДАКТИРОВАТЬ:
Для того, чтобы вышеупомянутое решение работало, фактическое GraphicBuffer
должен быть создан или выделен с соответствующими флагами использования, т.е. буфер должен быть создан с подсказкой, что ЦП будет обращаться к тому же самому. В противном случае, -EINVAL
будет возвращен в соответствии с документацией вgralloc
,
На некоторых платформах аппаратный декодер не создает YUV пространства пользователя по умолчанию. Вы можете попробовать
OMXCodec::Create(…,
flags | OMXCodec::kClientNeedsFramebuffer);
Какую платформу вы используете?
1) Обычно самый простой способ получить дамп выходного буфера - это сделать это в вендоре OMX IL (у каждого вендора, с которым я работал, были готовые функции / макросы для этого)
2) Если нет, попробуйте сбросить буфер в ACodec. onFillBufferDone
(нужно различать аудио / видео) или onOutputBufferDrained
, вы должны получить mGraphicBuffer
и получить из него необработанный буфер - инкапсуляция зависит от платформы, например, для qc это будет
void const *buf = (void const*)((private_handle_t*)(info->mGraphicBuffer->handle))->base;
Предполагая, что информация есть (в ACodec::onOutputBufferDrained)
BufferInfo *info =
mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
В случае OMXCodec вы можете сделать то же самое в конце OMXCodec::read Возвращенный buf просто сохраните в файл, размер для записи будет WxHxPixelRatio.