Android: MPEG4Writer ne parvient pas à démarrer lorsque OMXCodec est utilisé en tant que MediaSource

J’essaie de coder une vidéo à partir d’un tampon de tableau d’octets et MPEG4Writer API MPEG4Writer partir de code natif.

J’ai créé ma classe MediaSource personnalisée pour fournir les données et je l’enveloppe avec OMXCodec pour la MPEG4Writer à MPEG4Writer :

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

mVideoOutSource est ma classe MediaSource personnalisée, omxEncMeta est la suivante:

 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 omxEncMeta = new MetaData; omxEncMeta->setCSsortingng(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); omxEncMeta->setInt32(kKeyColorFormat, colorFormat); omxEncMeta->setInt32(kKeyWidth, width); omxEncMeta->setInt32(kKeyHeight, height); omxEncMeta->setInt32(kKeySsortingde, width); omxEncMeta->setInt32(kKeySliceHeight, height); omxEncMeta->setInt32(kKeyFrameRate, frameRate); omxEncMeta->setInt32(kKeySampleRate, frameRate); omxEncMeta->setInt32(kKeyBitRate, bitRate); omxEncMeta->setInt32(kKeyIFramesInterval, iFrameInterval); 

mais lorsque j’appelle la méthode start() , le code d’erreur UNKNOWN_ERROR est UNKNOWN_ERROR .

Si j’essaie de donner directement à MPEG4Writer mon MediaSource personnalisé (sans l’envelopper avec OMXCodec il démarre correctement mais finit par arrêter l’enregistrement avec l’erreur Missing codec specific data (après environ 12 images), et je pense que c’est parce que ma MediaSource fournit uniquement des informations sur les images réelles, mais rien sur le format du codec.

Je suis sûr que quelque chose me manque avec OMXCodec , mais je ne peux pas comprendre quoi… Y at-il quelqu’un qui pourrait me fournir un exemple MediaSource de MediaSource personnalisé pour l’encodage? Ou donnez-moi des indices sur la raison pour laquelle cela ne fonctionne pas du tout?
Si vous avez besoin de plus d’informations, n’hésitez pas, merci!

EDIT : Je suis en train de développer ceci contre l’API 14 alors ne me suggérez pas d’utiliser MediaCodec partir de l’API 16 🙂

EDIT : Voici comment je MPEG4Writer :

 int32_t outputFormat = OUTPUT_FORMAT_MPEG_4; int64_t startTimeUs = systemTime() / 1000; int32_t totalBitRate = bitRate; sp meta = new MetaData; meta->setInt64(kKeyTime, startTimeUs); meta->setInt32(kKeyFileType, outputFormat); meta->setInt32(kKeyBitRate, totalBitRate); sp 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!"); } 

Voici la sortie de 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 

Je viens de comprendre mon problème ( stupide ): mVideoEncoder start() sur mVideoEncoder (l’instance OMXCodec ) avant d’appeler start() sur MPEG4Writer , et cela donnait le UNKNOWN_ERROR .

J’ai résolu en appelant start() uniquement sur l’instance MPEG4Writer .

Il y a une erreur que je pense est importante:

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

également

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

Ensuite: assurez-vous que votre source renvoie cette

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

Le MediaBuffer que vous retournez de la source devrait avoir la bonne taille: 480 * 360 * 4 (je pense que c’est le cas).

Vous devez fournir la sortie adb logcat: adb.exe logcat OMXClient: V OMXCodec: V *: W