summaryrefslogtreecommitdiffstats
path: root/xbmc/interfaces/legacy/RenderCapture.h
blob: cf1b93131f44bf5d03464574018ac97d4ed5d3cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include "AddonClass.h"
#include "Exception.h"
#include "ServiceBroker.h"
#include "application/ApplicationComponents.h"
#include "application/ApplicationPlayer.h"
#include "commons/Buffer.h"

#include <climits>

namespace XBMCAddon
{
  namespace xbmc
  {
    XBMCCOMMONS_STANDARD_EXCEPTION(RenderCaptureException);

    //
    /// \defgroup python_xbmc_RenderCapture RenderCapture
    /// \ingroup python_xbmc
    /// @{
    /// @brief **Kodi's render capture.**
    ///
    /// \python_class{ RenderCapture() }
    ///
    ///
    ///--------------------------------------------------------------------------
    ///
    //
    class RenderCapture : public AddonClass
    {
      unsigned int m_captureId;
      unsigned int m_width;
      unsigned int m_height;
      uint8_t *m_buffer;

    public:
      inline RenderCapture()
      {
        m_captureId = UINT_MAX;
        m_buffer = nullptr;
        m_width = 0;
        m_height = 0;
      }
      inline ~RenderCapture() override
      {
        auto& components = CServiceBroker::GetAppComponents();
        const auto appPlayer = components.GetComponent<CApplicationPlayer>();
        appPlayer->RenderCaptureRelease(m_captureId);
        delete [] m_buffer;
      }

#ifdef DOXYGEN_SHOULD_USE_THIS
      ///
      /// \ingroup python_xbmc_RenderCapture
      /// @brief \python_func{ getWidth() }
      /// Get width
      ///
      /// To get width of captured image as set during RenderCapture.capture().
      /// Returns 0 prior to calling capture.
      ///
      /// @return                        Width or 0 prior to calling capture
      ///
      getWidth();
#else
      inline int getWidth() { return m_width; }
#endif

#ifdef DOXYGEN_SHOULD_USE_THIS
      ///
      /// \ingroup python_xbmc_RenderCapture
      /// @brief \python_func{ getHeight() }
      /// Get height
      ///
      /// To get height of captured image as set during RenderCapture.capture().
      /// Returns 0 prior to calling capture.
      ///
      /// @return                        height or 0 prior to calling capture
      getHeight();
#else
      inline int getHeight() { return m_height; }
#endif

#ifdef DOXYGEN_SHOULD_USE_THIS
      ///
      /// \ingroup python_xbmc_RenderCapture
      /// @brief \python_func{ getAspectRatio() }
      /// Get aspect ratio of currently displayed video.
      ///
      /// @return                        Aspect ratio
      /// @warning This may be called prior to calling RenderCapture.capture().
      ///
      getAspectRatio();
#else
      inline float getAspectRatio()
      {
        const auto& components = CServiceBroker::GetAppComponents();
        const auto appPlayer = components.GetComponent<CApplicationPlayer>();
        return appPlayer->GetRenderAspectRatio();
      }
#endif

#ifdef DOXYGEN_SHOULD_USE_THIS
      ///
      /// \ingroup python_xbmc_RenderCapture
      /// @brief \python_func{ getImageFormat() }
      /// Get image format
      ///
      /// @return                        Format of captured image: 'BGRA'
      ///
      ///
      ///-----------------------------------------------------------------------
      /// @python_v17 Image will now always be returned in BGRA
      ///
      getImageFormat()
#else
      inline const char* getImageFormat()
#endif
      {
        return "BGRA";
      }

#ifdef DOXYGEN_SHOULD_USE_THIS
      ///
      /// \ingroup python_xbmc_RenderCapture
      /// @brief \python_func{ getImage([msecs]) }
      /// Returns captured image as a bytearray.
      ///
      /// @param msecs               [opt] Milliseconds to wait. Waits
      ///                            1000ms if not specified
      /// @return                    Captured image as a bytearray
      ///
      /// @note The size of the image is m_width * m_height * 4
      ///
      ///
      ///-----------------------------------------------------------------------
      /// @python_v17 Added the option to specify wait time in msec.
      ///
      getImage(...)
#else
      inline XbmcCommons::Buffer getImage(unsigned int msecs = 0)
#endif
      {
        if (!GetPixels(msecs))
          return XbmcCommons::Buffer(0);

        size_t size = m_width * m_height * 4;
        return XbmcCommons::Buffer(m_buffer, size);
      }

#ifdef DOXYGEN_SHOULD_USE_THIS
      ///
      /// \ingroup python_xbmc_RenderCapture
      /// @brief \python_func{ capture(width, height) }
      /// Issue capture request.
      ///
      /// @param width               Width capture image should be rendered to
      /// @param height              Height capture image should should be rendered to
      ///
      ///
      ///-----------------------------------------------------------------------
      /// @python_v17 Removed the option to pass **flags**
      ///
      capture(...)
#else
      inline void capture(int width, int height)
#endif
      {
        auto& components = CServiceBroker::GetAppComponents();
        const auto appPlayer = components.GetComponent<CApplicationPlayer>();

        if (m_buffer)
        {
          appPlayer->RenderCaptureRelease(m_captureId);
          delete [] m_buffer;
        }
        m_captureId = appPlayer->RenderCaptureAlloc();
        m_width = width;
        m_height = height;
        m_buffer = new uint8_t[m_width*m_height*4];
        appPlayer->RenderCapture(m_captureId, m_width, m_height, CAPTUREFLAG_CONTINUOUS);
      }

// hide these from swig
#ifndef SWIG
      inline bool GetPixels(unsigned int msec)
      {
        auto& components = CServiceBroker::GetAppComponents();
        const auto appPlayer = components.GetComponent<CApplicationPlayer>();
        return appPlayer->RenderCaptureGetPixels(m_captureId, msec, m_buffer,
                                                 m_width * m_height * 4);
      }
#endif

    };
    //@}
  }
}