Прикрепление поверхности к MediaCodec (NDK) дает GrallocMapperPassthrough: дескриптор буфера с недопустимыми битами использования 0x2000 - PullRequest
1 голос
/ 07 ноября 2019
MediaCodecDecoder::MediaCodecDecoder(JNIEnv *env, jobject javaSurface, Codec codec)
{
    this->codec = codec;
    std::string mime = "video/avc";
    if (env && !env->IsSameObject(javaSurface, NULL))
    {
        this->surface.reset(ANativeWindow_fromSurface(env, javaSurface));
        format.reset(AMediaFormat_new());
        AMediaFormat_setString(format.get(), AMEDIAFORMAT_KEY_MIME, mime.c_str());
        AMediaFormat_setInt32(format.get(), AMEDIAFORMAT_KEY_WIDTH, 2304);
        AMediaFormat_setInt32(format.get(), AMEDIAFORMAT_KEY_HEIGHT, 1296);
        aMediaCodec = AMediaCodec_createDecoderByType(mime.c_str());
        media_status_t mediaCodecStatus = AMediaCodec_configure(aMediaCodec,
                                                                format.get(),
                                                                surface.get(),
                                                                nullptr,
                                                                0);
        AMediaCodec_start(aMediaCodec);
    }
}

void MediaCodecDecoder::run()
{

    while(shouldContinue()) {
        ssize_t bufferIndex = -1;
        //Gets new RTSP packet
        std::shared_ptr<EncodedPacket> encodedPacket = onAcquireNewPacket();
        bufferIndex = AMediaCodec_dequeueInputBuffer(aMediaCodec, 5000);
        if (bufferIndex >= 0) {
            size_t bufferSize;
            auto buffer = AMediaCodec_getInputBuffer(aMediaCodec, bufferIndex, &bufferSize);

            if (encodedPacket->getSize() < bufferSize) {
                memcpy(buffer, encodedPacket->getFramePointer(), encodedPacket->getSize());
            }

            AMediaCodec_queueInputBuffer(aMediaCodec, bufferIndex, 0, encodedPacket->getSize(),
                                         10000, 0);
        }
}

Вот что я получаю:

I/MediaCodec: (0x7f589ba200) init name(video/avc) isType(1) encoder(0)
I/OMXClient: Treble IOmx obtained
I/MediaCodec: (0x7f589ba200) Component Allocated (OMX.qcom.video.decoder.avc)
I/MediaCodec: (0x7f589ba200) configure surface(0x7f56270000) crypto(0x0) flags(0)
D/MediaCodec: (0x7f589ba200) configure format: AMessage(what = 0x00000000) = {
          string mime = "video/avc"
          int32_t width = 2304
          int32_t height = 1296
        }
D/SurfaceUtils: connecting to surface 0x7f56270010, reason connectToSurface
I/MediaCodec: [OMX.qcom.video.decoder.avc] setting surface generation to 20434946
D/SurfaceUtils: disconnecting from surface 0x7f56270010, reason connectToSurface(reconnect)
    connecting to surface 0x7f56270010, reason connectToSurface(reconnect)
I/ACodec: DRC Mode: Dynamic Buffer Mode
I/ExtendedACodec: setupVideoDecoder()
I/ACodec: [OMX.qcom.video.decoder.avc] setupVideoDecoder Width Height (2304x1296)
    mime (video/avc) compressionFormat (7)
I/ExtendedACodec: Decoder will be in frame by frame mode
I/MediaCodec: (0x7f589ba200) start
D/SurfaceUtils: set up nativeWindow 0x7f56270010 for 2304x1296, color 0x7fa30c06, rotation 0, usage 0x20002900
I/MediaCodec: (0x7f589ba200) kWhatStartCompleted
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
I/chatty: uid=10102(u0_a102) CodecLooper identical 2 lines
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
D/SurfaceUtils: set up nativeWindow 0x7f5ba36010 for 2304x1296, color 0x7fa30c06, rotation 0, usage 0x20002900
D/MediaCodec: (0x7f589bac00) kWhatOutputBuffersChanged
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
D/SurfaceUtils: set up nativeWindow 0x7f56270010 for 1920x1088, color 0x7fa30c06, rotation 0, usage 0x20002900
D/MediaCodec: (0x7f589ba200) kWhatOutputBuffersChanged
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
I/chatty: uid=10102(u0_a102) CodecLooper identical 2 lines
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
Process 19956 terminated.

Если я снимаю format.get() в AMediaCodec_configure и вставляю туда nullptr, я не получаю W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000 ошибок, так что проблема в javaSurface наверняка .

Я пытался сделать javaSurface глобальной ссылкой:

this->globalJavaSurface = env->NewGlobalRef(javaSurface);
this->surface.reset(ANativeWindow_fromSurface(env, globalJavaSurface));

, ноЯ все еще получаю сообщение об ошибке.

Поверхность, которая прибывает в конструктор MediaCodecDecoder, создается из SurfaceTexture, прикрепленного к экрану: Surface surface = new Surface(surfaceTexture);

Как вы можете видетьпо выводу работает декодирование, потому что оно определяет ширину и высоту двух потоков, которые я добавил.

ps: обратите внимание, что я вызываю queueInputBuffer с presentationTimeoutUS, равным 10000, потому что я не знаю, что туда поместить: Какие presentationTimeU использовать в Media Codec, если я не использую MediaExtractor? но я не думаю, что это проблема здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...