问题
Briefly, I'm combining two open source apps into a new VR app, so this only runs on the Note 4 and S6 using the GearVR headset. My app works on kitkat, but the video is black on lollipop. The two source apps both work fine on lollipop.
I have a surface created from a gl texture:
glGenTextures( 1, &textureId );
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
That gets put into a SurfaceTexture that gets put into a Surface, that gets passed around a bit, then sent to a video decoder:
videoDecoder = MediaCodec.createByCodecName(decoderName);
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
videoDecoder.configure(videoFormat, ((SurfaceHolder)renderTarget).getSurface(), null, 0);
videoDecoder.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
// OMX.qcom.video.decoder.avc gets picked for decodername
// Width and height at 1280x720 everywhere
The texture is updated and bound to a surface and rendered.
This works perfectly on kitkat. On lollipop, the video is completely black.
You can see a diff of the logs (good kitkat red, bad lollipop green) here:
https://www.diffchecker.com/lxxopmhc
Nothing stands out to me as particularly informative.
(The message do not know color format 0x7fa30c04 = 2141391876
from what I can find is just from the thing that turns decoder IDs into names, and shouldn't affect anything. Another decoder doesn't give this message, but also doesn't work.)
Adding an explicit color format to the MediaFormat, and twiddling with color formats and image sizes everywhere else doesn't have any effect (only black screen, no errors)
I can lock a canvas on the surface and drawARGB(255,0,255,0), screen turns green.
I created a subclass of surface that logged every public method and passed that to the decoder, and none of them got called (other than the initialization when I created it) on kitkat or lollipop, working or not, so that told me nothing at all.
The code for doing the video decoder setup came from Moonlight, which works perfectly fine on lollipop:
github.com/moonlight-stream/moonlight-android
The other half is Oculus Cinema, which displays on the surface using android.media.MediaPlayer and works fine on lollipop.
So my questions are what changed on lollipop or what have I done wrong, and how can I debug this problem any further?
My code is here:
https://github.com/GTMoogle/StreamTheater
Update 6/2:
Tried following suggestion from Q11 of http://bigflake.com/mediacodec/ to set the buffer position and limits, but still no output, though I might have implemented it incorrectly. Also took care of some depricated calls, also no effect.
Up-Update: The BufferInfo from the dequeueOutputBuffer seems to always have a size of 8, 0 offset, no flags set. Not sure what a healthy stream looks like yet.
回答1:
Ahhah. Eventually found it.
For some reason updateTexImage isn't changing the timestamp of the surface texture. Mediacodec was setting it on kitkat, so either the input buffer doesn't have a timestamp set correctly and mediacodec was cleaning up after it, or mediacodec is no longer setting it when updating the texture?
I can debug it, but I can at least for the moment just always update instead of check whether the timestamp changed.
来源:https://stackoverflow.com/questions/30405018/android-video-decoder-not-drawing-to-gles-surface-on-lollipop-only