我想在一些设备上使用MP4V ES而不是AVC。编码器使用avc运行良好,但当我用mp4v es替换它时,muxer报告:

E/MPEG4Writer(12517): Missing codec specific data

MediaMuxer error "Failed to stop the muxer"所示,无法播放视频。不同之处在于,我正在向muxer添加正确的曲目/格式,而没有收到任何错误:
...else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
           MediaFormat newFormat = encoder.getOutputFormat();
           mTrackIndex[encID] = mMuxer.addTrack(newFormat);

处理MP4V ES和AVC有什么区别吗?有一点,我只是跳过了“bufferinfo.flags&mediacodec.buffer_flag_codec_config”当它发生时,至于avc它是不需要的。谢谢。

最佳答案

正如ganesh所指出的,不幸的是,如果不修改平台源代码,现在看来这是不可能的。
实际上,有两种方法可以将特定于编解码器的数据传递到内部mpeg4writer类,但这两种方法实际上都无法在未经修改的情况下工作。
正如ganesh所发现的,将mediaformat键重新映射到内部格式的逻辑似乎缺少对h264以外的任何其他视频编解码器的特定于编解码器的数据的处理。修复此问题的测试修改如下:

diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 25afc5b..304fe59 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -549,14 +549,14 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
     // reassemble the csd data into its original form
     sp<ABuffer> csd0;
     if (msg->findBuffer("csd-0", &csd0)) {
-        if (mime.startsWith("video/")) { // do we need to be stricter than this?
+        if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
             sp<ABuffer> csd1;
             if (msg->findBuffer("csd-1", &csd1)) {
                 char avcc[1024]; // that oughta be enough, right?
                 size_t outsize = reassembleAVCC(csd0, csd1, avcc);
                 meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
             }
-        } else if (mime.startsWith("audio/")) {
+        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
             int csd0size = csd0->size();
             char esds[csd0size + 31];
             reassembleESDS(csd0, esds);

其次,原则上,您可以将相同的缓冲区(设置了csd-0标志)传递给MediaCodec.BUFFER_FLAG_CODEC_CONFIG,而不是将特定于编解码器的数据作为MediaMuxer.writeSampleData以mediaformat格式传递。此方法当前不起作用,因为此方法根本不检查编解码器配置标志-可以通过此修改修复:
diff --git a/media/libstagefright/MediaMuxer.cpp b/media/libstagefright/MediaMuxer.cpp
index c7c6f34..d612e01 100644
--- a/media/libstagefright/MediaMuxer.cpp
+++ b/media/libstagefright/MediaMuxer.cpp
@@ -193,6 +193,9 @@ status_t MediaMuxer::writeSampleData(const sp<ABuffer> &buffer, size_t trackInde
     if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
         sampleMetaData->setInt32(kKeyIsSyncFrame, true);
     }
+    if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
+        sampleMetaData->setInt32(kKeyIsCodecConfig, true);
+    }

     sp<MediaAdapter> currentTrack = mTrackList[trackIndex];
     // This pushBuffer will wait until the mediaBuffer is consumed.

据我所见,在使用公共api时,如果不修改平台源代码,现在就无法使用mediamuxer来mux mpeg4视频。考虑到上面utils.cpp中的问题,除了h264之外,不能对任何需要特定于编解码器的数据的视频格式进行mux。如果vp8是一个选项,您可以将其mux到webm文件中(与vorbis音频一起),但是vp8的硬件编码器可能远不如mpeg4的硬件编码器常见。

10-08 19:06