~ubuntu-branches/ubuntu/vivid/media-hub/vivid-updates

« back to all changes in this revision

Viewing changes to src/core/media/video/hybris_gl_sink.cpp

  • Committer: Package Import Robot
  • Author(s): CI Train Bot, Thomas Voss, CI Train Bot, Jim Hodapp, Ricardo Mendoza, Ricardo Salveti de Araujo, thomas-voss
  • Date: 2015-03-20 13:16:48 UTC
  • mfrom: (1.1.34)
  • Revision ID: package-import@ubuntu.com-20150320131648-dv8aynyyjib9v2sr
Tags: 3.0.0+15.04.20150320-0ubuntu1
[ Thomas Voss ]
* Refactor client-facing interfaces to pull out explicit dependency on hybris-based media layer.

[ CI Train Bot ]
* New rebuild forced.

[ Jim Hodapp ]
* Disconnect playback_status_changed_signal in ~Private() to avoid a
  deadlock.
* Prevent a 0 position from being reported to the app which happens
  while seeking. Covers bad behavior that happens from GStreamer. Also
  expose the about_to_finish signal to the client. Enable playback
  again after manually seeking all the way to EOS. Also only send
  VideoDimensionsChanged signal only when necessary.

[ Ricardo Mendoza ]
* Add an interface apparmor::ubuntu::RequestAuthenticator that is used
  to authenticate incoming open uri requests. Add an interface
  apparmor::ubuntu::RequestContextResolver that is used to resolve a
  dbus name to an apparmor::ubuntu::Context. Provide an implementation
  apparmor::ubuntu::ExistingAuthenticator that takes the impl. from
  player_skeleton.cpp and uses it to implement the interface. Provide
  an implementation apparmor::ubuntu::RequestContextResolver that
  reaches out to the dbus daemon to resolve a given bus name to an
  apparmor profile. Remove obsolete query for the apparmor profile in
  ServiceSkeleton. Adjust the implementation in media::PlayerSkeleton
  to rely on Request{Authenticator, ContextResolver}. removed:
  src/core/media/apparmor.h added: src/core/media/apparmor/
  src/core/media/apparmor/context.cpp
  src/core/media/apparmor/context.h src/core/media/apparmor/dbus.h
  src/core/media/apparmor/ubuntu.cpp src/core/media/apparmor/ubuntu.h
* Introduce an interface media::audio::OutputObserver that allows the
  core classes to observer the state of external audio outputs
  (headphones/headsets). Provide an implementation of
  media::audio::OutputObserver that relies on Pulseaudio to monitor
  the availability of ports on the default sink. Adjust
  media::ServiceImplementation to use media::audio::OutputObserver,
  defaulting to media::audio::PulseAudioOutputObserver.
* Migrate all Player DBus methods to use transact_method() instead of
  invoke_method_synchronously(), to prevent bus executor deadlocks.

[ Ricardo Salveti de Araujo ]
* Add an interface apparmor::ubuntu::RequestAuthenticator that is used
  to authenticate incoming open uri requests. Add an interface
  apparmor::ubuntu::RequestContextResolver that is used to resolve a
  dbus name to an apparmor::ubuntu::Context. Provide an implementation
  apparmor::ubuntu::ExistingAuthenticator that takes the impl. from
  player_skeleton.cpp and uses it to implement the interface. Provide
  an implementation apparmor::ubuntu::RequestContextResolver that
  reaches out to the dbus daemon to resolve a given bus name to an
  apparmor profile. Remove obsolete query for the apparmor profile in
  ServiceSkeleton. Adjust the implementation in media::PlayerSkeleton
  to rely on Request{Authenticator, ContextResolver}. removed:
  src/core/media/apparmor.h added: src/core/media/apparmor/
  src/core/media/apparmor/context.cpp
  src/core/media/apparmor/context.h src/core/media/apparmor/dbus.h
  src/core/media/apparmor/ubuntu.cpp src/core/media/apparmor/ubuntu.h
* Move src/core/media/call-monitor to src/core/media/telephony.
  Introduce a proper interface media::telephony::CallMonitor. Slightly
  adjust existing implementation based on Qt. Adjust
  media::ServiceImplementation to account for changes in
  media::telephony::CallMonitor.

[ thomas-voss ]
* Add an interface apparmor::ubuntu::RequestAuthenticator that is used
  to authenticate incoming open uri requests. Add an interface
  apparmor::ubuntu::RequestContextResolver that is used to resolve a
  dbus name to an apparmor::ubuntu::Context. Provide an implementation
  apparmor::ubuntu::ExistingAuthenticator that takes the impl. from
  player_skeleton.cpp and uses it to implement the interface. Provide
  an implementation apparmor::ubuntu::RequestContextResolver that
  reaches out to the dbus daemon to resolve a given bus name to an
  apparmor profile. Remove obsolete query for the apparmor profile in
  ServiceSkeleton. Adjust the implementation in media::PlayerSkeleton
  to rely on Request{Authenticator, ContextResolver}. removed:
  src/core/media/apparmor.h added: src/core/media/apparmor/
  src/core/media/apparmor/context.cpp
  src/core/media/apparmor/context.h src/core/media/apparmor/dbus.h
  src/core/media/apparmor/ubuntu.cpp src/core/media/apparmor/ubuntu.h
* Add an interface media::ClientDeathObserver that abstracts away
  receiving key-based death notifications for clients associated to
  media::Player instances server-side Provide an implementation
  media::HybrisClientDeathObserver that relies on hybris and
  ultimately on Android's onBinderDied to receive death notifications.
  Adjust media::PlayerStub and media::PlayerImplementation to account
  for the new interface. Adjust the CMake setup for tests to link
  media-hub-service instead of recompiling large parts of the
  implementation classes.
* Decouple PlayerSkeleton and PlayerImplementation by making
  PlayerImplementation being able to inherit from arbitrary base
  classes, as long as they provide the set of properties and signals
  defined by media::Player.
* Decouple the ServiceSkeleton from the ServiceImplementation by
  introducing a common interface media::KeyedPlayerStore for storing
  running Player sessions indexed by the Player::Key. Provide a
  default implementation HashedKeyedPlayerStore relying on a hash map
  for keeping track of player instances. Adjust implementation to
  account for ServiceImplementation no longer inheriting from
  ServiceSkeleton.
* Introduce a common class media::helper::ExternalHelpers that
  provides a convenient way to:
* Introduce an interface media::RecorderObserver that allows the core
  classes to monitor the overall state of the system. Provide an
  implementation of media::RecorderObserver relying on Hybris to
  interface with the Android side. Adjust the ServiceImplementation to
  connect to the platform-default media::RecorderObserver.
* Introduce an interface media::audio::OutputObserver that allows the
  core classes to observer the state of external audio outputs
  (headphones/headsets). Provide an implementation of
  media::audio::OutputObserver that relies on Pulseaudio to monitor
  the availability of ports on the default sink. Adjust
  media::ServiceImplementation to use media::audio::OutputObserver,
  defaulting to media::audio::PulseAudioOutputObserver.
* Introduce an interface media::power::BatteryObserver to monitor the
  current battery level of the system. The core reacts to low/very low
  battery levels by pausing all multimedia playback sessions and
  resumes them whenever the user has been notified of the critical
  battery level. Provide an implementation of
  media::power::BatteryObserver using
  com.canonical.indicator.power.Battery. Adjust
  media::ServiceImplementation to use media::power::BatteryObserver.
* Move gstreamer::Playbin implementation to its own cpp file, thus
  internalizing the Hybris setup portions. Make sure that media-hub-
  service knows about
  media::Player::Error::OutOfProcessBufferStreamingNotSupported by
  linking with media-hub-client.
* Move src/core/media/call-monitor to src/core/media/telephony.
  Introduce a proper interface media::telephony::CallMonitor. Slightly
  adjust existing implementation based on Qt. Adjust
  media::ServiceImplementation to account for changes in
  media::telephony::CallMonitor.
* Replace home-grown mask type for the video size with a std::tuple,
  i.e., media::video::Dimensions. Introduce a simple TaggedInteger
  class to distinguish between Width, Height and other dimensions.
  Adjust interfaces of media::Player to rely on the new type. Adjust
  implementation classes to account for interface changes. Adjust
  Codec implementation for sending the tagged integer via the bus.
  Adjust gstreamer::Engine and gstreamer::Playbin to hand out the
  correct types.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2014 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU Lesser General Public License version 3,
 
6
 * as published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU Lesser General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authored by: Thomas Voß <thomas.voss@canonical.com>
 
17
 */
 
18
 
 
19
#include <core/media/video/hybris_gl_sink.h>
 
20
 
 
21
#if defined(MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
 
22
// Hybris
 
23
#include <hybris/media/media_codec_layer.h>
 
24
#include <hybris/media/surface_texture_client_hybris.h>
 
25
 
 
26
namespace media = core::ubuntu::media;
 
27
namespace video = core::ubuntu::media::video;
 
28
 
 
29
struct video::HybrisGlSink::Private
 
30
{
 
31
    static void on_frame_available_callback(GLConsumerWrapperHybris, void* context)
 
32
    {
 
33
        if (not context)
 
34
            return;
 
35
 
 
36
        auto thiz = static_cast<Private*>(context);
 
37
 
 
38
        thiz->frame_available();
 
39
    }
 
40
 
 
41
    Private(std::uint32_t gl_texture)
 
42
        : gl_texture{gl_texture},
 
43
          graphics_buffer_consumer{decoding_service_get_igraphicbufferconsumer()},
 
44
          gl_texture_consumer{gl_consumer_create_by_id_with_igbc(gl_texture, graphics_buffer_consumer)}
 
45
    {
 
46
        if (not graphics_buffer_consumer) throw std::runtime_error
 
47
        {
 
48
            "video::HybrisGlSink: Could not connect to remote buffer queue."
 
49
        };
 
50
 
 
51
        if (not gl_texture_consumer) throw std::runtime_error
 
52
        {
 
53
            "video::HybrisGlSink: Could not associate local texture id with remote buffer streak."
 
54
        };
 
55
 
 
56
        gl_consumer_set_frame_available_cb(gl_texture_consumer, Private::on_frame_available_callback, this);
 
57
    }
 
58
 
 
59
    ~Private()
 
60
    {
 
61
        gl_consumer_set_frame_available_cb(gl_texture_consumer, Private::on_frame_available_callback, nullptr);
 
62
    }
 
63
 
 
64
    std::uint32_t gl_texture;
 
65
    core::Signal<void> frame_available;
 
66
    IGBCWrapperHybris graphics_buffer_consumer;
 
67
    GLConsumerWrapperHybris gl_texture_consumer;
 
68
};
 
69
 
 
70
std::function<video::Sink::Ptr(std::uint32_t)> video::HybrisGlSink::factory_for_key(const media::Player::PlayerKey& key)
 
71
{
 
72
    // It's okay-ish to use static map here. Point being that we currently have no way
 
73
    // of terminating the session with the decoding service anyway.
 
74
    static std::map<media::Player::PlayerKey, DSSessionWrapperHybris> lut;
 
75
    static std::mutex lut_guard;
 
76
 
 
77
    // Scoping access to the lut to ensure that the lock is kept for as short as possible.
 
78
    {
 
79
        std::lock_guard<std::mutex> lg{lut_guard};
 
80
        if (lut.count(key) == 0)
 
81
            lut[key] = decoding_service_create_session(key);
 
82
    }
 
83
 
 
84
    return [](std::uint32_t texture)
 
85
    {
 
86
        return video::Sink::Ptr{new video::HybrisGlSink{texture}};
 
87
    };
 
88
}
 
89
 
 
90
video::HybrisGlSink::HybrisGlSink(std::uint32_t gl_texture) : d{new Private{gl_texture}}
 
91
{
 
92
}
 
93
 
 
94
video::HybrisGlSink::~HybrisGlSink()
 
95
{
 
96
}
 
97
 
 
98
const core::Signal<void>& video::HybrisGlSink::frame_available() const
 
99
{
 
100
    return d->frame_available;
 
101
}
 
102
 
 
103
bool video::HybrisGlSink::transformation_matrix(float* matrix) const
 
104
{
 
105
    // TODO: The underlying API really should tell us if everything is ok.
 
106
    gl_consumer_get_transformation_matrix(d->gl_texture_consumer, matrix);
 
107
    return true;
 
108
}
 
109
 
 
110
bool video::HybrisGlSink::swap_buffers() const
 
111
{
 
112
    // TODO: The underlying API really should tell us if everything is ok.
 
113
    gl_consumer_update_texture(d->gl_texture_consumer);
 
114
    return true;
 
115
}
 
116
#endif // MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER