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? но я не думаю, что это проблема здесь