1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/desktop_capture/desktop_frame_win.h"
12 
13 #include <utility>
14 
15 #include "rtc_base/logging.h"
16 
17 namespace webrtc {
18 
DesktopFrameWin(DesktopSize size,int stride,uint8_t * data,std::unique_ptr<SharedMemory> shared_memory,HBITMAP bitmap)19 DesktopFrameWin::DesktopFrameWin(DesktopSize size,
20                                  int stride,
21                                  uint8_t* data,
22                                  std::unique_ptr<SharedMemory> shared_memory,
23                                  HBITMAP bitmap)
24     : DesktopFrame(size, stride, data, shared_memory.get()),
25       bitmap_(bitmap),
26       owned_shared_memory_(std::move(shared_memory)) {}
27 
~DesktopFrameWin()28 DesktopFrameWin::~DesktopFrameWin() {
29   DeleteObject(bitmap_);
30 }
31 
32 // static
Create(DesktopSize size,SharedMemoryFactory * shared_memory_factory,HDC hdc)33 std::unique_ptr<DesktopFrameWin> DesktopFrameWin::Create(
34     DesktopSize size,
35     SharedMemoryFactory* shared_memory_factory,
36     HDC hdc) {
37   int bytes_per_row = size.width() * kBytesPerPixel;
38   int buffer_size = bytes_per_row * size.height();
39 
40   // Describe a device independent bitmap (DIB) that is the size of the desktop.
41   BITMAPINFO bmi = {};
42   bmi.bmiHeader.biHeight = -size.height();
43   bmi.bmiHeader.biWidth = size.width();
44   bmi.bmiHeader.biPlanes = 1;
45   bmi.bmiHeader.biBitCount = DesktopFrameWin::kBytesPerPixel * 8;
46   bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
47   bmi.bmiHeader.biSizeImage = bytes_per_row * size.height();
48 
49   std::unique_ptr<SharedMemory> shared_memory;
50   HANDLE section_handle = nullptr;
51   if (shared_memory_factory) {
52     shared_memory = shared_memory_factory->CreateSharedMemory(buffer_size);
53     section_handle = shared_memory->handle();
54   }
55   void* data = nullptr;
56   HBITMAP bitmap =
57       CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &data, section_handle, 0);
58   if (!bitmap) {
59     RTC_LOG(LS_WARNING) << "Failed to allocate new window frame "
60                         << GetLastError();
61     return nullptr;
62   }
63 
64   return std::unique_ptr<DesktopFrameWin>(
65       new DesktopFrameWin(size, bytes_per_row, reinterpret_cast<uint8_t*>(data),
66                           std::move(shared_memory), bitmap));
67 }
68 
69 }  // namespace webrtc
70