Skip to content

Commit

Permalink
Merge pull request #1 from bbc/show_inside_bin_elements
Browse files Browse the repository at this point in the history
Show inside bin elements in element debug view
  • Loading branch information
matthew1000 authored Nov 6, 2018
2 parents bd36c36 + 7ecb187 commit 8b47ea6
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 21 deletions.
4 changes: 2 additions & 2 deletions brave/abstract_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def print_state_summary(self):
for id, obj in self.items():
obj.print_state_summary()

def get_pipeline_details(self):
def get_pipeline_details(self, show_inside_bin_elements):
details = {}
for id, obj in self.items():
if hasattr(obj, 'pipeline'):
details[id] = get_pipeline_details(obj.pipeline)
details[id] = get_pipeline_details(obj.pipeline, show_inside_bin_elements)
return details
9 changes: 5 additions & 4 deletions brave/api/route_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ async def mixers(request):


async def elements(request):
show_inside_bin_elements = 'show_inside_bin_elements' in request.args
session = brave.session.get_session()
return sanic.response.json({
'inputs': session.inputs.get_pipeline_details(),
'overlays': session.overlays.get_pipeline_details(),
'outputs': session.outputs.get_pipeline_details(),
'mixers': session.mixers.get_pipeline_details()
'inputs': session.inputs.get_pipeline_details(show_inside_bin_elements),
'overlays': session.overlays.get_pipeline_details(show_inside_bin_elements),
'outputs': session.outputs.get_pipeline_details(show_inside_bin_elements),
'mixers': session.mixers.get_pipeline_details(show_inside_bin_elements)
})


Expand Down
25 changes: 18 additions & 7 deletions brave/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,29 @@ def create_intersink_channel_name():
return 'inter_channel_' + str(channel_count)


def get_pipeline_details(pipeline):
def get_pipeline_details(pipeline, show_inside_bin_elements=True):
'''
Given a GStreamer pipeline, returns an object of details about itself.
This is used for debugging.
'''
elements = []

def handle_each_element(element):
def handle_each_element(element, parent_element=None):
details = {
'name': element.name,
'type': element.get_factory().name,
'state': element.get_state(0).state.value_nick.upper(),
'pads': {}
}

inter_elements = ['interaudiosrc', 'interaudiosink', 'intervideosrc', 'intervideosink']
if details['type'] in inter_elements:
details['channel'] = element.get_property('channel')
if parent_element is not None:
details['parent'] = parent_element.name

if element.get_factory() is not None:
details['type'] = element.get_factory().name

inter_elements = ['interaudiosrc', 'interaudiosink', 'intervideosrc', 'intervideosink']
if details['type'] in inter_elements:
details['channel'] = element.get_property('channel')

def handle_pad(pad):
details['pads'][pad.name] = {
Expand All @@ -65,14 +70,20 @@ def handle_pad(pad):
if pad.is_linked():
peer = pad.get_peer()
details['pads'][pad.name]['peer'] = {
'element_name': peer.get_parent_element().name,
'pad_name': peer.name
}
parent = peer.get_parent_element()
if parent:
details['pads'][pad.name]['peer']['element_name'] = peer.get_parent_element().name

pad_iterator = element.iterate_pads()
pad_iterator.foreach(handle_pad)
elements.append(details)

if show_inside_bin_elements and hasattr(element, 'iterate_elements'):
iterator = element.iterate_elements()
iterator.foreach(handle_each_element, element)

iterator = pipeline.iterate_elements()
iterator.foreach(handle_each_element)

Expand Down
30 changes: 22 additions & 8 deletions public/elements_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
<title>Brave - elements table</title>
</head>
<body>
<main role="main" class="container">
<button style="float:right" onclick="refresh()">Refresh</button>
<h3>All GStreamer elements</h3>
<p>This view is for debugging. It shows all GStreamer elements and their status.</p>
<main class="container-fluid">
<h1>Internal elements</h1>
<div>
<button style="float:right" class="btn btn-primary" onclick="refresh()">Refresh</button>
<button style="float:right" class="btn btn-primary" id="show-hide-bin-elements"></button>
<p>This view is for debugging. It shows all GStreamer elements and their status.</p>
</div>
<div id="main"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script>
<script>

function elementColumns(element) {
var cells = []
Expand Down Expand Up @@ -98,7 +101,7 @@ <h3>All GStreamer elements</h3>

function refresh() {
$.ajax({
url: 'api/elements'
url: 'api/elements' + (show_inside_bin_elements ? '?show_inside_bin_elements=yes' : '')
}).then(function(data) {
$('#main').empty()
Object.keys(data).forEach(function(blockType) {
Expand All @@ -109,18 +112,29 @@ <h3>All GStreamer elements</h3>
header.append(' ')
.append($('<span></span>').append(state).addClass(data[blockType][blockId].state))
}

table = $('<table class="table table-bordered table-hover"></table>')
table.append(tableHeader)
tbody = $('<tbody></tbody>')
table.append(tbody)
if (data[blockType][blockId].elements) addElements(tbody, data[blockType][blockId].elements)
if (data[blockType][blockId].elements) {
addElements(tbody, data[blockType][blockId].elements)
header.append(' (' + data[blockType][blockId].elements.length + ' elements)')
}
$('#main').append(header, table)
})
})
})
}

const show_inside_bin_elements = (new window.URLSearchParams(window.location.search)).get('show_inside_bin_elements') !== null
$('#show-hide-bin-elements').text(show_inside_bin_elements ? 'Hide inner bin elements' : 'Show inner bin elements')
$('#show-hide-bin-elements').click(() => {
window.location = show_inside_bin_elements ? '?' : '?show_inside_bin_elements=yes'
})

refresh()
</script>

</main>
</body>
</html>
35 changes: 35 additions & 0 deletions tests/test_elements_api_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import time, pytest
from utils import *


def test_elements_api_endpoint(run_brave):
'''
Check that /api/elements returns a list of element details,
including when "?show_inside_bin_elements=yes"
'''
run_brave()
time.sleep(0.5)
check_brave_is_running()
add_input({'type': 'image', 'props': {'uri': 'file://' + test_directory() + '/assets/image_640_360.png'}})
time.sleep(1)

subtest_elements_endpoint()
subtest_elements_endpoint_with_bin_elements()

def subtest_elements_endpoint():
elements_response = api_get('/api/elements')
assert elements_response.status_code == 200
elements_object = elements_response.json()
assert len(elements_object['inputs'].items()) == 1
assert len(elements_object['mixers'].items()) == 1
assert len(elements_object['outputs'].items()) == 0
assert len(elements_object['inputs']['0']['elements']) == 5

def subtest_elements_endpoint_with_bin_elements():
elements_response = api_get('/api/elements?show_inside_bin_elements=yes')
assert elements_response.status_code == 200
elements_object = elements_response.json()
assert len(elements_object['inputs'].items()) == 1
assert len(elements_object['mixers'].items()) == 1
assert len(elements_object['outputs'].items()) == 0
assert len(elements_object['inputs']['0']['elements']) == 10

0 comments on commit 8b47ea6

Please sign in to comment.