GNOME Bugzilla – Bug 760553
deinterlace: Bug in caps passthrough lead to black screen with Android HW decoder
Last modified: 2016-03-11 15:56:10 UTC
Created attachment 318914 [details] log when it works I am using gstreamer to send h264 video over RTSP. With 1.6.2 and 1.7.1 I always get a black screen instead of seeing video on the client. I can see the client is connecting and fetching video from the server, and disconnects normally at exit, it just never displays the video. logcat from 1.6.1 (last working version) and 1.6.2 (first not-working version) attached.
Created attachment 318915 [details] log when it doesn't work
This is most likely fixed by this commit commit 22a0914cce9f6352e3042b9f1f7b9cacac2db0b7 Author: Sebastian Dröge <sebastian@centricular.com> Date: Mon Dec 28 15:53:59 2015 +0200 gl: Add \0 terminators for the Apple sync extension Otherwise GL initialization might check for extensions forever and never finishes. Your debug log does not contain any useful information from GStreamer, so please test if the commit is solving it for you. Otherwise a debug log with gl*:6 would be useful to have. If it's not fixed by that commit, please reopen :)
I have build the SDK using Cerbero. I am not sure what version Cerbero uses by default but from what I can tell it looks like it uses origin/master on all repositories by default. Anyway, the resulting SDK still gives a black screen. Additionally the server now stops even sending frames after about 12 have been transmitted. How do I change the debug level on Android?
What's your application doing, what is the pipeline? The easiest way to change the debug level everywhere would be by changing it in gstreamer_android-1.0.c.in (from the GStreamer binary tree) and then just rebuilding the application. Basically this line here: http://cgit.freedesktop.org/gstreamer/cerbero/tree/data/ndk-build/gstreamer_android-1.0.c.in#n481 (Related bug #756929 about making setting of the debug level easier)
My application is a fork of com.gst_sdk_tutorials.tutorial_5 It is modified to remove the file open dialog and instead use a hard coded rtsp URL. It is further modified to catch the source_setup signal and change the latency property on the source to 50. The pipeline is gst_parse_launch("playbin", &error); What do I need to change the line to in order to get the information you need?
I changed the line to GST_LEVEL_LOG and the resulting log file is now 12MB so I uploaded it here: http://al.robotfuzz.com/~al/random/verbose-log.txt
It looks like this does not include all lines, like some are dropped by adb logcat somehow. Anyway, which version of GStreamer is that? Latest GIT master as of when? This might be related to the recent changes from bug #758212, which would be these commits: http://cgit.freedesktop.org/gstreamer/gst-plugins-base/commit/?id=9713ab06cd081c520ab14641df1e974b5bbbe50c http://cgit.freedesktop.org/gstreamer/gst-plugins-base/commit/?id=fccf83e69f108fd1bdc10b785761c54d3f413b36 or http://cgit.freedesktop.org/gstreamer/gst-plugins-base/commit/?id=81c52aaa1695cd1d0ca9004aa668b9ed85db2da9 Can you check if reverting any of these make a difference for you?
This is probably the most relevant line from your log: D/GStreamer+GST_PADS(13116): 0:00:16.577488692 0x617efef0 gstpad.c:3065:gst_pad_query_accept_caps_default:<deinterlace:sink> allowed caps subset EMPTY, caps video/x-raw(memory:GLMemory), format=(string)RGBA, width=(int)960, height=(int)540, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)sRGB, framerate=(fraction)0/1, texture-target=(string)external-oes
amcviddec tries to negotiate GL memory (for zerocopy rendering) and seems to get the answer that downstream supports that. However the CAPS event with GL memory is then rejected by the deinterlace element inside playsink.
I initially built using Cerbero on Wednesday. Jan 13 23:13 (UTC) gstreamer-1.0-android-armv7-1.7.1.tar.bz2 Rebuilt with gst-plugins-base @ 1b412a523d1ed950a1822ae4a01c8ce8aa29b34f and no change in behaviour.
Ok, thanks. So this is unrelated to those changes. Can you try if it works after setting the flags property on playbin to 0x00000417 (i.e. disabling the deinterlacer)? I guess it's then related to dc0e2281b90bba438e6723620d4da7aea8a00946 or 82d62b9edd04bb7f5a1fece9d803e02629ddefd1 in gst-plugins-good.
data->pipeline = gst_parse_launch("playbin flags=0x00000417", &error); This makes it work correctly. I am not sure why the deinterlacer is even getting involved. The source video should not be interlaced.
The deinterlacer should work in passthrough mode here, but apparently does not properly passthrough caps :)
Can you get a debug log with deinterlace:6, please? If you could get a GST_DEBUG=2,deinterlace:6,*EVENT*:6,*PAD*:6,*CAPS*:6,*QUERY*:6 that would help debugging a lot. Thanks
Weird that this log that is apparently complete has no mention of any log from a "gstdeinterlace.c" entry
I don't know how to make the log any more verbose. It is already set to a default level of log. As I understand it this is the most verbose possible level and should result in every possible debug statement being printed.
gst_pad_query_accept_caps_default:<deinterlace:sink> fallback ACCEPT_CAPS query, consider implementing a specialized version This deinterlace version is saying it is using the default accept-caps query while we have a proper implementation since October. There seems to be something wrong here.
Indeed, all very confusing. Alistair, can you build a new version of GStreamer for Android from latest GIT? For that first run ./cerbero-uninstalled -c config/cross-android-armv7.cbc wipe (or whatever config you're using)
Wonder if bug #720388 is related?
After building from latest git, my application no longer compiles. It produces the following errors: gstavdeinterlace.c:379: error: undefined reference to 'av_buffersrc_add_frame' gstavdeinterlace.c:306: error: undefined reference to 'avfilter_graph_free' gstavdeinterlace.c:329: error: undefined reference to 'avfilter_graph_alloc' gstavdeinterlace.c:333: error: undefined reference to 'avfilter_graph_parse2' gstavdeinterlace.c:340: error: undefined reference to 'avfilter_graph_config' gstavdeinterlace.c:345: error: undefined reference to 'avfilter_graph_get_filter' gstavdeinterlace.c:347: error: undefined reference to 'avfilter_graph_get_filter' gstavdeinterlace.c:384: error: undefined reference to 'av_buffersink_get_frame' gstavdeinterlace.c:306: error: undefined reference to 'avfilter_graph_free' collect2: error: ld returned 1 exit status make: *** [buildsharedlibrary_armeabi] Error 1
This looks like your build is in an inconsistent state. Try the wipe command as given above and then try building from scratch again.
I used the wipe command.
Can you remove the whole dist and sources directories from cerbero, then wipe, then try again? Something seems very broken there
Sounds very much like bug #720388. I wonder why Matthew didn't see that failing :) Should be fixed before 1.7.2.
I've also created bug #760883 for the original bug here (the 1.6.1->1.6.2 regression).
I ran the wipe command, and then deleted the entire ~/cerbero directory. The same thing happened. My application build script runs git clean -d -f -x to remove all files not checked in to git, including ones which are ignored, so there is no problem with stale files there either. When you say to delete the dist directory from cerbero, do you mean the one in ~/cerbero or the one in the actual cerbero source directory? I assume the former since the cerbero source directory does not have a sub folder called sources.
The libav problem is most likely fixed now by http://cgit.freedesktop.org/gstreamer/cerbero/commit/?id=1c7efc274241c146189360f2af73f74bcaebfa45 I'll do a rebuild now and check.
http://cgit.freedesktop.org/gstreamer/gst-libav/commit/?id=9dd7bcc486038be57f8e60a8c5fd0ce7b3cdd31b after this it works for real.
I can't reproduce this here it seems (with local files or RTSP streams containing h264). Can you provide a sample RTSP stream with this behaviour, or a gst-rtsp-server test-launch command that you're using?
I'll work on fixing bug #720388, and related problems. That might also help here.
Today I tried to build the SDK completely from scratch, using the following steps: ./cerbero-uninstalled -c config/cross-android-armv7.cbc wipe rm -rf ~/cerbero git clean -d -f -x git pull ./cerbero-uninstalled -c config/cross-android-armv7.cbc bootstrap ./cerbero-uninstalled -c config/cross-android-armv7.cbc package gstreamer-1.0 It failed with the following errors: ... [(87/87) gst-editing-services-1.0-static -> fetch ] [(87/87) gst-editing-services-1.0-static -> extract ] [(87/87) gst-editing-services-1.0-static -> configure ] [(87/87) gst-editing-services-1.0-static -> compile ] [(87/87) gst-editing-services-1.0-static -> install ] [(87/87) gst-editing-services-1.0-static -> post_install ] WARNING: No specific packager available for the distro version android_gingerbread, using generic packager for distro android -----> Creating package for gstreamer-1.0 ***** Error running 'package' command: The following files required by this package are missing: lib/pkgconfig/gstreamer-bad-base-1.0.pc lib/pkgconfig/gstreamer-bad-video-1.0.pc lib/pkgconfig/gstreamer-bad-audio-1.0.pc This seems related to the last commit: "gst-plugins-bad-1.0: Ship badaudio/video/base libraries, headers and .pc files" The source of my rtsp server is here: https://github.com/ali1234/piroverd/blob/master/main.cpp
Build errors reported on https://bugzilla.gnome.org/show_bug.cgi?id=760733
Can you test the patches in bug #720388?
The patches there are merged now, please retest. I think this should all be good now. Please reopen this bug otherwise. *** This bug has been marked as a duplicate of bug 720388 ***
It still doesn't work. Identical symptoms as before. Log file: http://al.robotfuzz.com/~al/random/gstnew.txt
I don't see any problem in the log unfortunately. It seems like the decoder consumes two frames, never outputs anything and then the pipeline is just shut down. What is the application you're using here?
Can you also check if these changes here help? https://bugzilla.gnome.org/show_bug.cgi?id=761014#c36
Okay I went back to the original tutorial 5: http://cgit.freedesktop.org/~slomo/gst-sdk-tutorials/tree/gst-sdk/tutorials/android-tutorial-5 To reproduce the bug I only need to make two changes: First in Tutorial-5.java change the media URL to my RTSP server. Second, in jni/Android.mk, add $(GSTREAMER_PLUGINS_CODECS_RESTRICTED) to $GSTREAMER_PLUGINS. After doing this, I run it and press the play button, and I see the following error after about 5 seconds: "Error received from element amcvideodecomxqcomvideodecoderavc0: Internal data stream error." However, if I go back and also set the playbin flags to 0x417, then the RTSP stream is played correctly. Also the example sintel video appears to play correctly regardless of whether restricted codecs are used, and regardless of whether the playbin flags are set. I don't remember exactly why I added restricted codecs, but it seems to make the video play MUCH smoother (when it works). I pushed my example code to https://github.com/ali1234/android-tutorial-5 The first commit is an exact copy of the android-tutorial-5 directory from your repo.
Okay regarding that bug, if "with/without hardware acceleration" means "with/without restricted codecs" then that does look very related...
While waiting for the SDK to build I tried to play the videos attached on #761014 in my modified tutorial 5. I found the same results as I get with my RTSP server: * The videos will play if restricted codecs are not included. * If restricted codecs are included I get "Internal data stream error." * If restricted codecs are included and I set the flags on playbin then the videos play.
Restricted codecs would mean ffmpeg, but you get an error from amcviddec if you enable restricted codecs?
Yes, unless I disable the deinterlacer with playbin flags.
That's weird, none of the restricted plugins should be used here and even if they are... amcviddec is there in both cases anyway. What are the settings for gst-rtsp-server that you're using, how do you start it? If it's with a specific media file, can you also share that one?
The source of my rtsp server is here: https://github.com/ali1234/piroverd/blob/master/main.cpp I can also reproduce it with local-25fps.mp4 from http://www.gentil.com/tmp/sdcard-gstreamer-1.7.1.zip
If libav is added to tutorial-5, any of the files http://www.gentil.com/tmp/sdcard-gstreamer-1.7.1.zip plays (internal data stream error from the amcvideodec-... plugin). But if libav is NOT added, since Sebastian's fix, any of the files can be played though there is the performance issue probably related to glupload as described in https://bugzilla.gnome.org/show_bug.cgi?id=761014. I start to believe that if one wants/intends to use hardware acceleration, libav should be avoided. As a helper, it's interested to dump the live elements of the pipeline with the following code: void dumpBin_(GstElement* a, char *sz) { GstIterator *it = gst_bin_iterate_elements((GstBin*)a); GValue point = G_VALUE_INIT; while (gst_iterator_next (it, &point) == GST_ITERATOR_OK) { GstElement *e = (GstElement*)(g_value_peek_pointer(&point)); strcat(sz, " "); strcat(sz, gst_element_get_name(e)); //GST_DEBUG ("element -> %s", gst_element_get_name(e)); dumpBin_(e, sz); } } void dumpBin(CustomData *data) { char sz[1024]; strcpy(sz, "DUMPELEMENTS:"); dumpBin_(data->pipeline, sz); GST_DEBUG("%s", sz); }
Can you retest with latest master?
Ping?
With latest master as of two hours ago there is no change in behavior.
Can you get a new log with that version?
If there are no updates here soonish, I'll make this a non-blocker for 1.8 and go ahead with the release.
Still broken in latest master. No change in behavior.
See comment 49.
Log: http://al.robotfuzz.com/~al/random/gstreamer.txt
Why is this calling gst_pad_query_caps_default() with the deinterlace sinkpad? deinterlace has its own handling of the caps query... Anyway, the problem is that ACCEPT_CAPS happens with video/x-raw(memory:GLMemory), format=(string)RGBA. And this uses the default ACCEPT_CAPS handling (deinterlace overrides that on the sinkpad!). And the resulting caps query returns video/x-raw, format=(string)I420 with the default CAPS query handler based on the template caps (deinterlace has different template caps). I'm not sure where all this comes from, it doesn't make any sense at all :) It's as if a different element than our deinterlace is used here.
Oops and that's exactly what is happening here: D/GStreamer+playsink(13514): 0:00:16.955212181 0x618330f0 gstplaysink.c:1491:gen_video_deinterlace_chain:<playsink> creating deinterlace V/GStreamer+GST_ELEMENT_FACTORY(13514): 0:00:16.955376348 0x618330f0 gstelementfactory.c:143:gst_element_factory_find no such element factory "deinterlace" V/GStreamer+GST_ELEMENT_FACTORY(13514): 0:00:16.955619108 0x618330f0 gstelementfactory.c:445:gst_element_factory_make:<avdeinterlace> found factory 0x6184c3f0 I/GStreamer+GST_ELEMENT_FACTORY(13514): 0:00:16.955782858 0x618330f0 gstelementfactory.c:362:gst_element_factory_create creating element "avdeinterlace" named "deinterlace" It's using avdeinterlace instead, because deinterlace is not included in your application. Maybe we should stop having avdeinterlace as fallback in playsink? And you should include deinterlace in your app :)
Created attachment 322907 [details] [review] Revert "playbin: use avdeinterlace for deinterlacing until deinterlace is ported" This reverts commit 0615794300234e3efbcb49a524efdee11171ab4c. deinterlace was ported at some point in the last 4 years and has better video format support, and especially better negotiation than avdeinterlace. Having avdeinterlace but not deinterlace causes various problems in zerocopy scenarios.
Attachment 322907 [details] pushed as e2c992d - Revert "playbin: use avdeinterlace for deinterlacing until deinterlace is ported"
Well I kind of understood some of that. I'm not sure how I'm supposed to know that I need to include deinterlace? Especially since my app never ever deals with interlaced video. If a deinterlacer is required to play non-interlaced video, why isn't it included by default?
You have to select which plugins your application should include. If you need deinterlacing, you need to include it. If it's not included it will just not deinterlace (after the fix above).
I must say that I saw a kind of similar situation in my application. When I was adding libav, I had deinterlace coming from nowhere (well not nowhere...) and I was not seen it when not integrating libav. The problem disappeared after fixing all the 1.7 problems a few weeks ago. I need to test latest git in my application.