Skip to content
This repository has been archived by the owner on Jan 28, 2022. It is now read-only.

Commit

Permalink
service: get the number of audio/video streams from the playbin
Browse files Browse the repository at this point in the history
Let's still keep the URL-based detection for a while, until we fix the
client library as well.
  • Loading branch information
mardy committed May 27, 2021
1 parent 783ae81 commit 45a49dd
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/core/media/gstreamer/playbin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ void gstreamer::Playbin::source_setup(GstElement*,
static_cast<Playbin*>(user_data)->setup_source(source);
}

void gstreamer::Playbin::streams_changed(GstElement *pipeline,
gpointer /*user_data*/)
{
/* We are possibly in a GStreamer working thread, so we notify the main
* thread of this event through a message in the bus */
gst_element_post_message(pipeline,
gst_message_new_application(GST_OBJECT(pipeline),
gst_structure_new_empty("streams-changed")));
}

gstreamer::Playbin::Playbin(const core::ubuntu::media::Player::PlayerKey key_in)
: pipeline(gst_element_factory_make("playbin", pipeline_name().c_str())),
bus{gst_element_get_bus(pipeline)},
Expand Down Expand Up @@ -165,6 +175,14 @@ gstreamer::Playbin::Playbin(const core::ubuntu::media::Player::PlayerKey key_in)
G_CALLBACK(source_setup),
this
);

m_audioChangedHandlerId = g_signal_connect(
pipeline, "audio-changed",
G_CALLBACK(streams_changed), this);

m_videoChangedHandlerId = g_signal_connect(
pipeline, "video-changed",
G_CALLBACK(streams_changed), this);
}

// Note that we might be accessing freed memory here, so activate DEBUG_REFS
Expand Down Expand Up @@ -193,6 +211,8 @@ gstreamer::Playbin::~Playbin()

g_signal_handler_disconnect(pipeline, about_to_finish_handler_id);
g_signal_handler_disconnect(pipeline, source_setup_handler_id);
g_signal_handler_disconnect(pipeline, m_audioChangedHandlerId);
g_signal_handler_disconnect(pipeline, m_videoChangedHandlerId);

if (pipeline)
gst_object_unref(pipeline);
Expand Down Expand Up @@ -328,6 +348,10 @@ void gstreamer::Playbin::process_message_element(GstMessage *message)
{
send_frame_ready();
}
else if (g_strcmp0("streams-changed", struct_name) == 0)
{
updateMediaFileType();
}
else
{
MH_ERROR("Unknown GST_MESSAGE_ELEMENT with struct %s", struct_name);
Expand Down Expand Up @@ -363,6 +387,7 @@ void gstreamer::Playbin::on_new_message(const Bus::Message& message)
}
Q_EMIT stateChanged(message.detail.state_changed, message.source);
break;
case GST_MESSAGE_APPLICATION:
case GST_MESSAGE_ELEMENT:
if (gst_is_missing_plugin_message(message.message))
process_missing_plugin_message(message.message);
Expand Down Expand Up @@ -627,6 +652,20 @@ void gstreamer::Playbin::setup_source(GstElement *source)
}
}

void gstreamer::Playbin::updateMediaFileType()
{
int videoStreamCount = 0, audioStreamCount = 0;
g_object_get(pipeline, "n-video", &videoStreamCount, NULL);
g_object_get(pipeline, "n-audio", &audioStreamCount, NULL);
MH_DEBUG("streams changed: file has %d video streams and %d audio streams",
videoStreamCount, audioStreamCount);

if (videoStreamCount > 0)
setMediaFileType(MEDIA_FILE_TYPE_VIDEO);
else if (audioStreamCount > 0)
setMediaFileType(MEDIA_FILE_TYPE_AUDIO);
}

QUrl gstreamer::Playbin::uri() const
{
gchar* data = nullptr;
Expand Down
4 changes: 4 additions & 0 deletions src/core/media/gstreamer/playbin.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Playbin: public QObject
static void source_setup(GstElement*,
GstElement *source,
gpointer user_data);
static void streams_changed(GstElement*, gpointer user_data);

Playbin(const core::ubuntu::media::Player::PlayerKey key);
~Playbin();
Expand Down Expand Up @@ -103,6 +104,7 @@ class Playbin: public QObject
QUrl uri() const;

void setup_source(GstElement *source);
void updateMediaFileType();

// Sets the pipeline's state (stopped, playing, paused, etc).
bool set_state(GstState new_state);
Expand Down Expand Up @@ -131,6 +133,8 @@ class Playbin: public QObject
core::ubuntu::media::Player::Lifetime player_lifetime;
gulong about_to_finish_handler_id;
gulong source_setup_handler_id;
gulong m_audioChangedHandlerId;
gulong m_videoChangedHandlerId;
bool is_missing_audio_codec;
bool is_missing_video_codec;
gint audio_stream_id;
Expand Down
3 changes: 3 additions & 0 deletions tests/service/functional/MediaHub.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ def check_value(interface, changed, invalidated):
self.unsubscribe_properties_changed(check_value)
return True if self.props.get(name) == value else False

def get_prop(self, name):
return self.__properties.Get(self.interface_name, name)

def open_uri(self, uri):
return self.__player.OpenUri(uri)

Expand Down
37 changes: 37 additions & 0 deletions tests/service/functional/test_media_hub_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,40 @@ def do_GET(self):
assert 'Authorization' in request.headers
assert request.headers['Authorization'] == 'Basic dG9tOlA0c3M6dyVyZCQ='
httpd.server_close()

@pytest.mark.parametrize('file_name,expected_is_video,expected_is_audio',
[
('test-audio.ogg', False, True),
('test-video.ogg', True, False),
])
def test_play_remote_media(self, bus_obj, media_hub_service_full,
data_path, file_name,
expected_is_video, expected_is_audio):
request = None

class HttpHandler(HttpServer.HttpRequestHandler):
def do_GET(self):
print('HTTP server captured request!')
self.send_response(200)
self.send_header('Content-type', 'application/octet-stream')
self.send_header('Content-Disposition', 'attachment; filename="song.ogg"')
self.end_headers()

audio_file = data_path.joinpath(self.path[1:])
with audio_file.open('rb') as f:
self.wfile.write(f.read())

httpd = HttpServer.HttpServer(HttpHandler)

media_hub = MediaHub.Service(bus_obj)
(object_path, uuid) = media_hub.create_session()
player = MediaHub.Player(bus_obj, object_path)

audio_file = 'http://127.0.0.1:8000/' + file_name
player.open_uri(audio_file)
player.play()
httpd.handle_request()
assert player.wait_for_prop('PlaybackStatus', 'Playing')
assert player.get_prop('IsAudioSource') == expected_is_audio
assert player.get_prop('IsVideoSource') == expected_is_video
httpd.server_close()

0 comments on commit 45a49dd

Please sign in to comment.