After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 763401 - Zero-copy video playback doesn't work on Android 4.x (QA 1.7.90)
Zero-copy video playback doesn't work on Android 4.x (QA 1.7.90)
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
1.7.90
Other Linux
: Normal blocker
: 1.7.91
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-03-09 23:10 UTC by Gregoire
Modified: 2016-03-11 15:56 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Log video not playing (27.50 KB, application/zip)
2016-03-09 23:10 UTC, Gregoire
  Details
log6 (25.61 KB, application/zip)
2016-03-10 09:59 UTC, Gregoire
  Details
Log with playbin (200.67 KB, application/zip)
2016-03-10 17:55 UTC, Gregoire
  Details
amcvideodec: getOutputBuffers() returns a NULL array when a surface was configured (2.56 KB, patch)
2016-03-11 08:12 UTC, Sebastian Dröge (slomo)
none Details | Review
amc: Correctly handle NULL input buffers (5.20 KB, patch)
2016-03-11 08:12 UTC, Sebastian Dröge (slomo)
committed Details | Review
amcvideodec: getOutputBuffers() returns a NULL array when a surface was configured (2.56 KB, patch)
2016-03-11 08:13 UTC, Sebastian Dröge (slomo)
committed Details | Review

Description Gregoire 2016-03-09 23:10:06 UTC
Created attachment 323557 [details]
Log video not playing

Video playback on Nexus 7 2013 Android 4.4.3 doesn't work if zero-copy (direct frame passing from decoder to GPU) is used. No video is displayed.

Also, video is played if frame copy occurs between decoder and GPU.

The exact same problem occurs on two TCL Alcatel OneTouch devices (phone and Hero8 tablet), both running 4.4.2.

The same app, video, gstreamer-1.7.90 are working on Android 5.0 and 6.0.1.

For information, Android 4.x still represents 35% of the installed park of Android worldwide.

Attached debug log *:5 on the Alcatel phone.
Comment 1 Matthew Waters (ystreet00) 2016-03-10 08:34:25 UTC
This log doesn't contain any output from amcvideodec so:

1. make sure it's actually attempting to use androidmedia
2. add amc*:7 to the debug log categories when you're sure you have 1) sorted.
Comment 2 Sebastian Dröge (slomo) 2016-03-10 08:44:42 UTC
Can you send a new log with *:6? This one suggests that things just hang for some reason after the pipeline goes to READY. Nothing that even looks like mediacodec related things, not dataflow has happened yet.
Comment 3 Gregoire 2016-03-10 09:59:03 UTC
Created attachment 323601 [details]
log6
Comment 4 Gregoire 2016-03-10 10:00:04 UTC
Attached from Nexus 7 2013 running 4.4.3.

If frame is copied via NV12, working.
If zero-copy, not working.

Same app is working on Android 6.0.1.
Comment 5 Sebastian Dröge (slomo) 2016-03-10 10:45:00 UTC
Still nothing with amcvideodec in the log. It looks like all goes to READY state and nothing's wrong at this point.

What is the change you do in your app to go from "If frame is copied via NV12, working" to "If zero-copy, not working"?
Comment 6 Gregoire 2016-03-10 17:54:37 UTC
We might have two issues here.

In both cases, with or without zero-copy, the pipeline is the same: filesrc ! decodebin ! glimagesink

In case of direct copy, I intercept the autoplug-query of decodebin: g_signal_connect(G_OBJECT(ElementD), "autoplug-query", G_CALLBACK(autoplug_query_cb), data);

For GST_QUERY_CAPS and GST_QUERY_CONTEXT, I mimic what playbin is doing. I have read my code and I might use string comparison that only works for 5.x/6.x. I need to check. If https://bugzilla.gnome.org/show_bug.cgi?id=742924 was fixed, I would not have a problem. Will that bug fix in the near future?


Second part: if I update the pipeline to playbin, I start to see some decoding messages. Keep in mind once again that the same app is working on 6.x with zero copy.
Comment 7 Gregoire 2016-03-10 17:55:34 UTC
Created attachment 323656 [details]
Log with playbin
Comment 8 Gregoire 2016-03-10 21:07:29 UTC
Just to make it clear, pipeline with playbin on Android 4.4 is not working, meaning that the screen stays black.
Comment 9 Matthew Waters (ystreet00) 2016-03-11 04:42:18 UTC
Errm

gstamcvideodec.c:1250:gst_amc_video_dec_loop:<...> dequeueOutputBuffer() returned -2147483648 (0x80000000)
gstamcvideodec.c:1293:gst_amc_video_dec_loop:<...> Failure dequeueing output buffer
gstamcvideodec.c:1533:gst_amc_video_dec_loop:<...> error: Failed to get buffer 0

So something in gst_amc_codec_dequeue_output_buffer() returns G_MININT.

Could you find out which failure case it's hitting (add some meaningful GST_ERROR()'s at each failure case) ?

Side note: I just tried zero-copy on an android 4.4.2 device I have and things worked marvellously so it's not Android version specific.
Comment 10 Matthew Waters (ystreet00) 2016-03-11 04:44:52 UTC
Another data point to test is with some other video files as "width=(int)1280, height=(int)1440, framerate=(fraction)154/3" isn't exactly cheap and it may be baulking at the ~50fps frame rate.
Comment 11 Gregoire 2016-03-11 05:18:17 UTC
Just as a reminder, the same app works on Android 6.0.1.

This is the code that is hit: line 545 of gstamc.c

  if (ret == INFO_OUTPUT_BUFFERS_CHANGED || ret == INFO_OUTPUT_FORMAT_CHANGED
      || (ret >= 0 && !codec->output_buffers
          && !media_codec.get_output_buffer)) {
    if (!media_codec.get_output_buffer) {
      if (codec->output_buffers)
        gst_amc_jni_free_buffer_array (env, codec->output_buffers,
            codec->n_output_buffers);
      codec->output_buffers =
          gst_amc_codec_get_output_buffers (codec,
          &codec->n_output_buffers, err);
      if (!codec->output_buffers) {
        ret = G_MININT;
        goto done;
      }
    }

Twice it hits this test and it never reaches line 560. Then, it fails in gstamcvideodec.c line 1293.
Comment 12 Gregoire 2016-03-11 05:29:00 UTC
Problem also occurs with big bunny h264.
Comment 13 Sebastian Dröge (slomo) 2016-03-11 07:38:10 UTC
So which of the conditions is it?

> ret == INFO_OUTPUT_BUFFERS_CHANGED || ret == INFO_OUTPUT_FORMAT_CHANGED || (ret >= 0 && !codec->output_buffers && media_codec.get_output_buffer)

And what does err->message contain after gst_amc_codec_get_output_buffers() (I assume that's the one that fails?)?
Comment 14 Sebastian Dröge (slomo) 2016-03-11 07:50:15 UTC
Ok so the problem is in gst_amc_jni_get_buffer_array(), where it gets NULL for the first element of the output buffer array.
Comment 15 Sebastian Dröge (slomo) 2016-03-11 07:51:22 UTC
And the reason is:

> The data processing is nearly identical to the ByteBuffer mode when using an
> output Surface; however, the output buffers will not be accessible, and are
> represented as null values. E.g. getOutputBuffer/Image(int) will return null
> and getOutputBuffers() will return an array containing only null-s.

Let's try a fix for this
Comment 16 Gregoire 2016-03-11 07:52:44 UTC
For the records, it's ret == INFO_OUTPUT_FORMAT_CHANGED only. And the message is: 

03-10 23:48:00.744: E/GStreamer+amc(3435): 0:00:12.279907226 0x7ee23920 gstamc.c:556:gst_amc_codec_dequeue_output_buffer: Failed to get buffer 0
Comment 17 Sebastian Dröge (slomo) 2016-03-11 08:12:21 UTC
Created attachment 323683 [details] [review]
amcvideodec: getOutputBuffers() returns a NULL array when a surface was configured

So don't error out if it does.
Comment 18 Sebastian Dröge (slomo) 2016-03-11 08:12:26 UTC
Created attachment 323684 [details] [review]
amc: Correctly handle NULL input buffers
Comment 19 Sebastian Dröge (slomo) 2016-03-11 08:13:46 UTC
Created attachment 323685 [details] [review]
amcvideodec: getOutputBuffers() returns a NULL array when a surface was configured

So don't error out if it does.
Comment 20 Matthew Waters (ystreet00) 2016-03-11 08:41:44 UTC
Review of attachment 323684 [details] [review]:

Looks sane.
Comment 21 Matthew Waters (ystreet00) 2016-03-11 08:43:17 UTC
Review of attachment 323685 [details] [review]:

Looks sane.

Maybe add a reference/copy verbatim the doc snippet somewhere (message, comment, ...)
Comment 22 Gregoire 2016-03-11 08:46:21 UTC
playbin is now working on Android 4.4 with the patches 323684 and 323685. Also, it seems working when doing zero-copy through decodebin with the autoplugin-query mimic of playbin.
Comment 23 Sebastian Dröge (slomo) 2016-03-11 08:48:20 UTC
Attachment 323684 [details] pushed as 610705c - amc: Correctly handle NULL input buffers
Attachment 323685 [details] pushed as 9132b72 - amcvideodec: getOutputBuffers() returns a NULL array when a surface was configured