GitHub PushEvent at 2014-08-28 12:25:04
Repository: stb-tester
Actor: szemate
Payload: {"shas":[["85b83abc7385b4c223d7b583ca433bf58ec00b87","70ef5ae0bbb1aaaec4bbbd9af6e4df4e6a56b055@youview.com","stbt.py: Drop the last sample on underrun\n\n`stbt._display.last_sample` stores the most recent GSt buffer until\n`stbt.gst_samples` removes it or it's replaced by a newer buffer.\nTo put it other way, if the video stream stops then `gst_samples`\nyields the very last sample of the video stream even though it's called\nminutes later.\n\nThis behaviour has unwanted effects in the following situations:\n\n1.\n    stbt.press(\"POWER_OFF\")\n    time.sleep(5)\n    # Make sure that the device under test is off\n    try:\n        stbt.get_frame()\n    except stbt.NoVideo:\n        pass\n    else:\n        raise stbt.UITestFailure(\"The device is still on\")\n\nIn this case `stbt.get_frame` never raises NoVideo, as it returns the\nsample that had been stored *before* the box was powered off.\n\n2.\n    stbt.wait_for_match(\"menu.png\")\n    stbt.press(\"POWER_OFF\")\n    time.sleep(5)\n    stbt.press(\"POWER_ON\")\n    # Make sure that we no longer see menu.png because\n    # it should disappear if the device under test is restarted\n    try:\n        stbt.wait_for_match(\"menu.png\")\n    except stbt.MatchTimeout:\n        pass\n    else:\n        raise stbt.UITestFailure(\"menu.png hasn't disappeared\")\n\nIn this case we have a race condition between stbt and the device under\ntest. The device needs some time to start delivering frames after it's\npowered on; if it doesn't happen before `gst_samples` is called then\n`wait_for_match(\"menu.png\")` returns false positive as the first sample\nthat `gst_samples` yields is the one that had been stored *before* the\ndevice was powered off.\n\nNote that these issues only occur with Blackmagic and HD PVR capture\ndevices because VidiUs emit all-blue frames if they don't receive\nvideo.\n\nA solution is to drop `last_sample` if the user data queue sends an\nunderrun message. However, in my experience capturing video with HD PVR\nresults in a lot of underrun messages even though the video stream\nappears to be continuous. The underrun messages are so frequent that\ndropping the last sample after each message results in deleting valuable\nvideo frames and the video output is lagging. To work around this issue,\nthe same timer is used that \"restart source\" is using; it's cancelled\nif the video stream continues, as signalled by a \"running\" message.","Mate Szendro",true],["ca96b3d3d857279cd75b98811f73a1628fddd768","70ef5ae0bbb1aaaec4bbbd9af6e4df4e6a56b055@youview.com","stbt.py: Stop sink pipeline while the source pipeline is restarting\n\nA VidiU capture device restarts its encoder every time video resolution\nchanges. It results in an EOS message sent to the source bus\nthat triggers restarting the source pipeline, as implemented in\n6b7ba0a3.\n\nThat patch is effective with a simple sink pipeline; however, if the\nvideo saving pipeline is active (--save-video option), tests fail\nwith one of the following errors:\n1. GStreamer raises a general stream error: \"streaming task paused,\n   reason not-negotiated (-4)\".\n2. If there are multiple subsequent encoder restarts, the second EOS\n   message is not sent, therefore the source pipeline never gets\n   restarted for the second time, and the test hangs forever or times\n   out with NoVideo.\nThey are not specific to vp8enc; theoraenc and x264enc also produce\nthe above errors.\n\nIf we stop video encoding when the source pipeline sends the EOS\nmessage, and don't restart it until the source pipeline is successfully\nrestarted, we can avoid the above failures.\n\nNote that it's not enough to set the sink pipeline to STATE_PAUSED.\nWhen we restart video recording, the video encoder raises the error\n\"negotiation problem ... encoder not initialized\". We have to restart\nthe encoder in order to successfully resume video recording.\n\nUnfortunately the fix has side-effects:\n* As the entire sink pipeline is stopped during source pipeline restart,\n  the xvimagesink output window is getting closed for this duration.\n  As we don't see any video during a pipeline restart anyway, only a\n  black or blue screen, it's not a big deal.\n* Every time the video encoder restarts it overwrites the video file.\n  A solution is provided in a following commit.\n\nFixes https://github.com/drothlis/stb-tester/issues/211.","Mate Szendro",true],["6dc2f38338038b9690639098ceeee0547763bda1","70ef5ae0bbb1aaaec4bbbd9af6e4df4e6a56b055@youview.com","stbt.py: Re-timestamp buffers after source pipeline restart\n\nEvery time the source pipeline is rebuilt, timestamps of the video\nbuffers restart counting from zero. It implies the following issues:\n\n* If the source pipeline is restarted while `gst_samples` is running,\n  the actual timeout value is getting unpredictable, as `gst_samples`\n  times out if `timestamp - self.start_timestamp > timeout_secs` and\n  both `timestamp` and `self.start_timestamp` are reset to 0 while\n  `timeout_secs` stays the same. E.g. if we are running\n\n    `wait_for_match('something.png', timeout_secs=20)`\n\n  and the source pipeline restarts after 10 seconds, it raises\n  `MatchTimeout` after ~30 seconds.\n\n* `--save-video` produces a corrupted video file because the timestamps\n  are not in increasing order. Even though some players are able to play\n  it, it is not possible to rebuild the video index (e.g. with `ffmpeg`\n  or `avconv`) to make it seekable.\n\nThis commit modifies `on_new_sample` to offset the timestamp of every\nbuffer by the last video timestamp before the most recent source\npipeline restart, and also by the duration of the pipeline restart\nto make `gst_samples` time out at the expected time.\n\nNote that this fix doesn't substitute the patch \"Stop sink pipeline\nwhile the source pipeline is restarting\". Even though timestamps are\nin the right order, without that patch restarting the source pipeline\nresults in one of the GStreamer errors \"streaming task paused, reason\nnot-negotiated (-4)\" or \"negotiation problem ... encoder not\ninitialized\".","Mate Szendro",true],["283bfed226b819abf76558d747140573b297fd1f","70ef5ae0bbb1aaaec4bbbd9af6e4df4e6a56b055@youview.com","stbt.py: Create a new video file each time video recording is restarted\n\nThe commit \"Stop sink pipeline while the source pipeline is restarting\"\nhas an issue that filesink overwrites the video file every time it gets\nrestarted. A possible solution would be to use the filesink in \"append\"\nmode, but appending the next video doesn't recreate the video file\nheader, and therefore the output file would not be seekable.\n\nA working, though slightly inconvenient solution is to save video to a\nnew file after every filesink restart. Running\n\n    stbt run --save-video video.webm test.py\n\nwith a test that involves 2 source pipeline restarts will create\n3 files: video.webm, video1.webm and video2.webm.","Mate Szendro",true],["c60415a1dba87250b7831ef3a5ba3b05f9432da7","70ef5ae0bbb1aaaec4bbbd9af6e4df4e6a56b055@youview.com","stbt.py: Save streamable video\n\nThis reverts \"Create a new video file each time video recording is\nrestarted\" and replaces with an alternative solution.\n\nSave a single streamable file, i.e. no indexes and duration are written.\nIt's possible to build the video index to make it seekable after the\ntest is completed with an external application, e.g.\n\n    ffmpeg|avconv -i video.webm -c copy video.seekable.webm","Mate Szendro",true]],"size":5,"ref":"refs/heads/sut-restart-stability-fixes","head":"c60415a1dba87250b7831ef3a5ba3b05f9432da7"}