我正在尝试对字节数组缓冲区中的视频进行编码,因此我正在使用本机代码中的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
的工作示例进行编码吗?或给我一些提示,为什么这根本不起作用?如果您需要更多信息,请问,谢谢!
编辑:我正在针对API 14进行开发,因此请不要建议我使用API 16中的
MediaSource
:)编辑:这就是我启动
MediaCodec
的方式: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(
MPEG4Writer
)的输出: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
最佳答案
我只是想出了一个(愚蠢的)问题:我先在start()
上调用mVideoEncoder
,然后再在OMXCodec
上调用start()
,然后在MPEG4Writer
上调用了UNKNOWN_ERROR
,这就是start()
。
我只通过在MPEG4Writer
实例上调用ojit_code来解决。