Android: MPEG4Writer не запускается при использовании OMXCodec в качестве MediaSource

Я пытаюсь кодировать видео из буфера массива байтов и для этого я использую MPEG4Writer API из нативного кода.

Я создал свой обычай MediaSource класс, чтобы предоставить данные, и я обертываю его OMXCodec дать это MPEG4Writer:

sp<MediaSource> mVideoEncoder = OMXCodec::Create(client.interface(), omxEncMeta, true, mVideoOutSource);
mVideoEncoder->start();

mVideoOutSource это мой обычай MediaSource учебный класс, omxEncMeta является следующим:

int32_t colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
int32_t width = 480;
int32_t height = 360;
int32_t frameRate = 24;
int32_t bitRate = 500 * 1024;
int32_t iFrameInterval = 1;

sp<MetaData> omxEncMeta = new MetaData;
omxEncMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
omxEncMeta->setInt32(kKeyColorFormat, colorFormat);
omxEncMeta->setInt32(kKeyWidth, width);
omxEncMeta->setInt32(kKeyHeight, height);
omxEncMeta->setInt32(kKeyStride, width);
omxEncMeta->setInt32(kKeySliceHeight, height);
omxEncMeta->setInt32(kKeyFrameRate, frameRate);
omxEncMeta->setInt32(kKeySampleRate, frameRate);
omxEncMeta->setInt32(kKeyBitRate, bitRate);
omxEncMeta->setInt32(kKeyIFramesInterval, iFrameInterval);

но когда я звоню start() метод возвращает код ошибки UNKNOWN_ERROR,

Вместо этого, если я попытаюсь дать MPEG4Writer прямо мой обычай MediaSource (без упаковки OMXCodec он запускается успешно, но в конце концов он остановит запись с ошибкой Missing codec specific data (после примерно 12 кадров), и я думаю, это потому, что мой обычай MediaSource предоставляет только информацию о реальных кадрах, но ничего о формате кодека.

Я уверен, что что-то упустил с OMXCodec, но я не могу понять, что … Есть ли кто-нибудь, кто мог бы предоставить мне рабочий пример обычая MediaSource для кодирования? Или дать мне несколько советов, почему это не работает вообще?
Если вам нужна дополнительная информация, просто спросите, спасибо!

РЕДАКТИРОВАТЬ: Я разрабатываю это против API 14, поэтому, пожалуйста, не предлагайте мне использовать MediaCodec из API 16 🙂

РЕДАКТИРОВАТЬ: Вот как я начинаю MPEG4Writer:

int32_t outputFormat = OUTPUT_FORMAT_MPEG_4;
int64_t startTimeUs = systemTime() / 1000;
int32_t totalBitRate = bitRate;

sp<MetaData> meta = new MetaData;
meta->setInt64(kKeyTime, startTimeUs);
meta->setInt32(kKeyFileType, outputFormat);
meta->setInt32(kKeyBitRate, totalBitRate);

sp<MPEG4Writer> mWriter = new MPEG4Writer("/sdcard/encode_manual.mp4");
mWriter->addSource(mVideoEncoder);
status_t error = mWriter->start(meta.get());
if (error != OK) {
LOGE("Writer NOT started! %x", error);
} else {
LOGI("Writer started!");
}

Это вывод logcat (adb logcat OMXClient:V OMXCodec:V *:W):

W/ResourceType(  370): Skipping entry 0x7f04002f in package table 0 because it is not complex!
E/        ( 4127): Can't open file for reading
E/        ( 4127): Can't open file for reading
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  omx_video(): Inside Constructor()
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  omx_venc(): Inside component_init()
E/OMX-VENC-720p(  155): bool venc_dev::venc_validate_profile_level(OMX_U32*, OMX_U32*): Returning with eProfile = 1Level = 4
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  bool venc_dev::venc_open(OMX_U32)(): Init Profile/Level setting success
E/OMX-VENC-720p(  155): vidc.venc.debug.sliceinfo value is 0
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  Component_init return value = 0x0
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155): WARNING: Requested i/p bufsize[40960],Driver's updated i/p bufsize = 262144
E/OMX-VENC-720p(  155): bool venc_dev::venc_validate_profile_level(OMX_U32*, OMX_U32*): Returning with eProfile = 1Level = 256
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  bool venc_dev::venc_set_param(void*, OMX_INDEXTYPE)(): Profile/Level setting success
E/OMX-VENC-720p(  155): bool venc_dev::venc_validate_profile_level(OMX_U32*, OMX_U32*): Returning with eProfile = 1Level = 64
E/OMX-VENC-720p(  155): Calling set level (Framerate) with 15
E/OMX-VENC-720p(  155): bool venc_dev::venc_validate_profile_level(OMX_U32*, OMX_U32*): Returning with eProfile = 1Level = 64
E/OMX-VENC-720p(  155): Calling set level (Bitrate) with 15
E/OMX-VENC-720p(  155): get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:1, Level:2048
E/OMX-VENC-720p(  155): Profile/Level set equal to 1/64
E/OMX-VENC-720p(  155): bool venc_dev::venc_validate_profile_level(OMX_U32*, OMX_U32*): Returning with eProfile = 1Level = 64
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  venc_set_intra_period: nPFrames = 25 nBFrames = 0
E/OMX-VENC-720p(  155): bool venc_dev::venc_validate_profile_level(OMX_U32*, OMX_U32*): Returning with eProfile = 1Level = 64
E/OMX-VENC-720p(  155): Calling set level (Bitrate) with 15
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  allocate_input_buffer()::
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  allocate_input_buffer()::
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  allocate_input_buffer()::
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  allocate_output_buffer()::
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  actual cnt = 5
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  allocate_output_buffer()::
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  actual cnt = 5
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  allocate_output_buffer()::
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  actual cnt = 5
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  allocate_output_buffer()::
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  actual cnt = 5
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  allocate_output_buffer()::
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  actual cnt = 5
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  unsigned int venc_dev::venc_start()(): Check Profile/Level set in driver before start
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  unsigned int venc_dev::venc_start()(): Driver Profile[3]/Level[15] successfully SET
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155): ENC_CONFIG: Codec: 2, Profile 3, level : 15
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  ENC_CONFIG: Width: 480, Height:360, Fps: 25
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155): ENC_CONFIG: Bitrate: 512000, RC: 3, I-Period: 25
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155): ENC_CONFIG: qpI: 0, qpP: 80, qpb: 0
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155): ENC_CONFIG: VOP_Resolution: 4343391, Slice-Mode: 1, Slize_Size: 0
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155): ENC_CONFIG: EntropyMode: 1, CabacModel: 0
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155): ENC_CONFIG: DB-Mode: 2, alpha: 0, Beta: 0
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155): ENC_CONFIG: IntraMB/Frame: 18, HEC: 843271745
E/OMX-VENC-720p(  155): Width 480, Height 360, w_round 480, h_round 368, yuv_size 294912 alignment 8192 count 2
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  Allocated virt:0x4432e000, FD: 145 of size 294912
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  Allocated virt:0x4432e000, FD: 145 of size 294912 at index: 0
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  Allocated virt:0x44895000, FD: 147 of size 294912
E/OMX-VENC-720p(  155):
E/OMX-VENC-720p(  155):  Allocated virt:0x44895000, FD: 147 of size 294912 at index: 1
E/TestEnc-JNI( 4127): Writer NOT started! 80000000

3

Решение

Я только разобрался (тупой) вопрос: я звонил start() на mVideoEncoder ( OMXCodec экземпляр) перед звонком start() на MPEG4Writerи это давало UNKNOWN_ERROR,

Я решил по телефону start() только на MPEG4Writer пример.

3

Другие решения

Есть ошибка, которую я считаю важной:

omxEncMeta->setInt32(kKeyBitRate, frameRate); // should set bitrate, 24 is too small

также

omxEncMeta->setInt32(kKeySampleRate, frameRate); // i don't think is of any use

Затем: убедитесь, что ваш источник возвращает это

virtual sp<MetaData> getFormat() {
sp<MetaData> meta = new MetaData;
meta->setInt32(kKeyWidth, mWidth);
meta->setInt32(kKeyHeight, mHeight);
meta->setInt32(kKeyColorFormat, mColorFormat);
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
return meta;
}

MediaBuffer, который вы возвращаете из источника, должен быть правильного размера: 480 * 360 * 4 (я думаю, что это так).

Вы должны предоставить adb logcat: adb.exe logcat OMXClient: V OMXCodec: V *: W

2

По вопросам рекламы [email protected]