cloudinary / cloudinary_android

Android client for integrating with Cloudinary
MIT License
67 stars 59 forks source link

Transformation job error on Android 5.0 #121

Closed dss-kenya closed 3 years ago

dss-kenya commented 3 years ago

There seems to be an issue uploading videos from Android 5.0. When trying to "preprocess" a video, there is an IllegalStateException thrown with the following stacktrace:

E/TransformationJob: Transformation job error
    java.lang.IllegalStateException
        at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
        at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:1033)
        at com.linkedin.android.litr.codec.MediaCodecEncoder.dequeueOutputFrame(MediaCodecEncoder.java:129)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.writeEncodedOutputFrame(VideoTrackTranscoder.java:228)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.processNextFrame(VideoTrackTranscoder.java:132)
        at com.linkedin.android.litr.TransformationJob.processNextFrame(TransformationJob.java:227)
        at com.linkedin.android.litr.TransformationJob.transform(TransformationJob.java:129)
        at com.linkedin.android.litr.TransformationJob.run(TransformationJob.java:99)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)

Removing all the parameters except for requestId, width, height and frameRate, results in the error below when supplying parameters to videoTranscodingChain

java.lang.Throwable: Explicit termination method 'release' not called
        at dalvik.system.CloseGuard.open(CloseGuard.java:184)
        at android.media.MediaMuxer.<init>(MediaMuxer.java:134)
        at com.linkedin.android.litr.io.MediaMuxerMediaTarget.<init>(MediaMuxerMediaTarget.java:52)
        at com.linkedin.android.litr.MediaTransformer.transform(MediaTransformer.java:105)
        at com.cloudinary.android.preprocess.Transcode.execute(Transcode.java:58)
        at com.cloudinary.android.preprocess.Transcode.execute(Transcode.java:27)
        at com.cloudinary.android.preprocess.PreprocessChain.execute(PreprocessChain.java:77)
        at com.cloudinary.android.UploadRequest.preprocessAndClone(UploadRequest.java:268)
        at com.cloudinary.android.UploadRequest.access$100(UploadRequest.java:32)
        at com.cloudinary.android.UploadRequest$1.run(UploadRequest.java:213)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)

Removing preprocess(....) during an uploadRequest results in the video being uploaded successfully on Android 5.0 but there seem to be playback issues with ExoPlayer.

Any idea what might be missing or messing with preprocess and android 5.0 ?

Code Snippet:

val uploadRequest = mediaManager.upload(fileUri)
                        .options(uploadOptions)
                        .option(CloudinaryConfig.folderKey, signature.folder)
                        .callback(UploadStateEmitter(emitter, CloudinaryConfig))

                    uploadRequest
                        .preprocess(videoPreprocessChainFactory.create(context, uploadRequest.requestId, fileUri))
                        .dispatch(context)

and the parameters are assigned the following values.

val parameters = with(context.resources) {
            Parameters().apply {
                requestId = uploadRequestId
                frameRate = 30
                width = dataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toInt() ?: 0
                height = dataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toInt() ?: 0
                keyFramesInterval = 2
                targetAudioBitrateKbps = 0
                targetVideoBitrateKbps = 3500000
            }
        }

Other logs from a real device:

E/TransformationJob: Transformation job error
    com.linkedin.android.litr.exception.TrackTranscoderException: Failed to configure decoder codec.Media transformation failed for job id: null
    Media format: {csd-1=java.nio.ByteArrayBuffer[position=0,limit=9,capacity=9], mime=video/avc, frame-rate=30, rotation=90, rotation-degrees=90, height=1080, width=1920, max-input-size=1572864, isDMCMMExtractor=1, durationUs=3597477, csd-0=java.nio.ByteArrayBuffer[position=0,limit=20,capacity=20]}
    Selected media codec info: 
    Diagnostic info: android.media.MediaCodec.error_neg_2147479551
        at com.linkedin.android.litr.codec.MediaCodecDecoder.init(MediaCodecDecoder.java:62)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.initCodecs(VideoTrackTranscoder.java:91)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.<init>(VideoTrackTranscoder.java:65)
        at com.linkedin.android.litr.transcoder.TrackTranscoderFactory.create(TrackTranscoderFactory.java:59)
        at com.linkedin.android.litr.TransformationJob.createTrackTranscoders(TransformationJob.java:198)
        at com.linkedin.android.litr.TransformationJob.transform(TransformationJob.java:119)
        at com.linkedin.android.litr.TransformationJob.run(TransformationJob.java:99)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)
     Caused by: android.media.MediaCodec$CodecException: Error 0x80001001
        at android.media.MediaCodec.native_configure(Native Method)
        at android.media.MediaCodec.configure(MediaCodec.java:577)
        at com.linkedin.android.litr.codec.MediaCodecDecoder.init(MediaCodecDecoder.java:49)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.initCodecs(VideoTrackTranscoder.java:91) 
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.<init>(VideoTrackTranscoder.java:65) 
        at com.linkedin.android.litr.transcoder.TrackTranscoderFactory.create(TrackTranscoderFactory.java:59) 
        at com.linkedin.android.litr.TransformationJob.createTrackTranscoders(TransformationJob.java:198) 
        at com.linkedin.android.litr.TransformationJob.transform(TransformationJob.java:119) 
        at com.linkedin.android.litr.TransformationJob.run(TransformationJob.java:99) 
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
        at java.lang.Thread.run(Thread.java:818) 

A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
    java.lang.Throwable: Explicit termination method 'release' not called
        at dalvik.system.CloseGuard.open(CloseGuard.java:184)
        at android.view.Surface.setNativeObjectLocked(Surface.java:423)
        at android.view.Surface.<init>(Surface.java:141)
        at com.linkedin.android.litr.render.VideoRenderInputSurface.<init>(VideoRenderInputSurface.java:61)
        at com.linkedin.android.litr.render.GlVideoRenderer.init(GlVideoRenderer.java:113)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.initCodecs(VideoTrackTranscoder.java:90)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.<init>(VideoTrackTranscoder.java:65)
        at com.linkedin.android.litr.transcoder.TrackTranscoderFactory.create(TrackTranscoderFactory.java:59)
        at com.linkedin.android.litr.TransformationJob.createTrackTranscoders(TransformationJob.java:198)
        at com.linkedin.android.litr.TransformationJob.transform(TransformationJob.java:119)
        at com.linkedin.android.litr.TransformationJob.run(TransformationJob.java:99)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)
michalkcloudinay commented 3 years ago

Hi @dss-kenya,

In order to further investigate, can you please let me know if you are able to play this video with ExoPlayer on android 5.0 without uploading it to Cloudinary?

dss-kenya commented 3 years ago

Hi @michalkcloudinay, Yes, i confirm we can play the video pretty well.

michalkcloudinay commented 3 years ago

Thanks, @dss-kenya for confirming. Can you please open a ticket at support@cloudinary.com and include the video so we can further investigate?