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);
}
}
Here's what I'm getting:
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.
If I take off the format.get()
in AMediaCodec_configure
and put nullptr
into there, I get no W/GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
errors, so the problem is in javaSurface
for sure.
I tried to make javaSurface
a global reference:
this->globalJavaSurface = env->NewGlobalRef(javaSurface);
this->surface.reset(ANativeWindow_fromSurface(env, globalJavaSurface));
but I still get the error.
The Surface that arrives at MediaCodecDecoder
's constructor is created from a SurfaceTexture
that is attached to the screen: Surface surface = new Surface(surfaceTexture);
As you can see by the output, decoding is working because it detects the width and height of the 2 streams I added.
ps: note that I'm calling queueInputBuffer with presentationTimeoutUS equal to 10000 because I don't know what to put there: Which presentationTimeUs to use in Media Codec if I'm not using MediaExtractor? but I don't think this is a problem here
User contributions licensed under CC BY-SA 3.0