summaryrefslogtreecommitdiff
path: root/sys/mediafoundation/gstmfvideobuffer.h
blob: a12b12a84c372e54e848e7b338ce42885556766b (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
/* GStreamer
 * Copyright (C) 2020 Seungha Yang <seungha@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef __GST_MF_VIDEO_BUFFER_H__
#define __GST_MF_VIDEO_BUFFER_H__

#include <gst/gst.h>
#include <gst/video/video.h>
#include <windows.h>
#include <mfobjects.h>
#include <mferror.h>
#include <mutex>

#ifndef __cplusplus
#error IGstMFVideoBuffer interface doesn't provide C API
#endif

/* Define UUID for QueryInterface() */
class DECLSPEC_UUID("ce922806-a8a6-4e1e-871f-e0cdd5fc9899")
IGstMFVideoBuffer : public IMFMediaBuffer, public IMF2DBuffer
{
public:
  static HRESULT CreateInstance (GstVideoInfo * info,
                                 IMFMediaBuffer ** buffer);

  static HRESULT CreateInstanceWrapped (GstVideoInfo * info,
                                        BYTE * data,
                                        DWORD length,
                                        IMFMediaBuffer ** buffer);

  /* notify will be called right after this object is destroyed */
  HRESULT SetUserData (gpointer user_data,
                       GDestroyNotify notify);

  HRESULT GetUserData (gpointer * user_data);

  /* IUnknown interface */
  STDMETHODIMP_ (ULONG) AddRef (void);
  STDMETHODIMP_ (ULONG) Release (void);
  STDMETHODIMP QueryInterface (REFIID riid,
                               void ** object);

  /* IMFMediaBuffer interface
   *
   * Caller of this interface expects returned raw memory layout via Lock()
   * has no padding with default stride. If stored memory layout consists of
   * non-default stride and/or with some padding, then Lock() / Unlock() would
   * cause memory copy therefore.
   * Caller should avoid to use this interface as much as possible
   * if IMF2DBuffer interface available.
   */
  STDMETHODIMP Lock (BYTE ** buffer,
                     DWORD * max_length,
                     DWORD * current_length);
  STDMETHODIMP Unlock (void);
  STDMETHODIMP GetCurrentLength (DWORD * length);
  STDMETHODIMP SetCurrentLength (DWORD length);
  STDMETHODIMP GetMaxLength (DWORD * length);

  /* IMF2DBuffer interface
   *
   * this interface supports any raw memory layout with non-default stride.
   * But more complex layout (padding at bottom for instance) is not supported.
   */
  STDMETHODIMP Lock2D (BYTE ** buffer,
                       LONG * pitch);
  STDMETHODIMP Unlock2D (void);
  STDMETHODIMP GetScanline0AndPitch (BYTE ** buffer,
                                     LONG * pitch);
  STDMETHODIMP IsContiguousFormat (BOOL * contiguous);
  STDMETHODIMP GetContiguousLength (DWORD * length);
  STDMETHODIMP ContiguousCopyTo (BYTE * dest_buffer,
                                 DWORD dest_buffer_length);
  STDMETHODIMP ContiguousCopyFrom (const BYTE * src_buffer,
                                   DWORD src_buffer_length);

private:
  IGstMFVideoBuffer (void);
  ~IGstMFVideoBuffer (void);

  HRESULT Initialize (GstVideoInfo * info);
  HRESULT InitializeWrapped (GstVideoInfo * info,
                             BYTE * data,
                             DWORD length);

private:
  volatile ULONG ref_count_;
  DWORD current_len_;
  DWORD contiguous_len_;
  BYTE *data_;
  BYTE *contiguous_data_;
  GstVideoInfo *info_;
  GstVideoInfo *contiguous_info_;
  BOOL contiguous_;
  std::mutex lock_;
  bool locked_;
  bool wrapped_;

  gpointer user_data_;
  GDestroyNotify notify_;
};

#endif /* __GST_MF_VIDEO_BUFFER_H__ */