3

バイト配列バッファからビデオをエンコードしようとしています。そのために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正常に開始されますが、最終的にはエラーで記録が停止します(約12フレーム後)。これは、カスタムが実際のフレームに関する情報のみを提供するMissing codec specific dataためだと思います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
4

2 に答える 2

3

私はちょうど私の(ばかげた)問題を理解しました:私は on を呼び出すstart()前にmVideoEncoderOMXCodecインスタンス)を呼び出しstart()ていましたMPEG4Writer、そしてこれは.を与えていましたUNKNOWN_ERROR

インスタンスstart()のみを呼び出すことで解決しました。MPEG4Writer

于 2013-09-12T17:34:52.110 に答える
2

私が重要だと思うエラーがあります:

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

于 2013-09-12T13:30:16.630 に答える