summaryrefslogtreecommitdiff
path: root/chromium/media/video/fake_video_encode_accelerator.cc
blob: 8e23df5f60ca4471361f2783c098f314068ad993 (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
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/video/fake_video_encode_accelerator.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"

namespace media {

static const unsigned int kMinimumInputCount = 1;
static const size_t kMinimumOutputBufferSize = 123456;

FakeVideoEncodeAccelerator::FakeVideoEncodeAccelerator(
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
    : task_runner_(task_runner),
      will_initialization_succeed_(true),
      client_(NULL),
      next_frame_is_first_frame_(true),
      weak_this_factory_(this) {}

FakeVideoEncodeAccelerator::~FakeVideoEncodeAccelerator() {
  weak_this_factory_.InvalidateWeakPtrs();
}

VideoEncodeAccelerator::SupportedProfiles
FakeVideoEncodeAccelerator::GetSupportedProfiles() {
  SupportedProfiles profiles;
  SupportedProfile profile;
  profile.max_resolution.SetSize(1920, 1088);
  profile.max_framerate_numerator = 30;
  profile.max_framerate_denominator = 1;

  profile.profile = media::H264PROFILE_MAIN;
  profiles.push_back(profile);
  profile.profile = media::VP8PROFILE_ANY;
  profiles.push_back(profile);
  return profiles;
}

bool FakeVideoEncodeAccelerator::Initialize(
    VideoFrame::Format input_format,
    const gfx::Size& input_visible_size,
    VideoCodecProfile output_profile,
    uint32 initial_bitrate,
    Client* client) {
  if (!will_initialization_succeed_) {
    return false;
  }
  if (output_profile == VIDEO_CODEC_PROFILE_UNKNOWN ||
      output_profile > VIDEO_CODEC_PROFILE_MAX) {
    return false;
  }
  client_ = client;
  task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers,
                 weak_this_factory_.GetWeakPtr(),
                 kMinimumInputCount,
                 input_visible_size,
                 kMinimumOutputBufferSize));
  return true;
}

void FakeVideoEncodeAccelerator::Encode(
    const scoped_refptr<VideoFrame>& frame,
    bool force_keyframe) {
  DCHECK(client_);
  queued_frames_.push(force_keyframe);
  EncodeTask();
}

void FakeVideoEncodeAccelerator::UseOutputBitstreamBuffer(
    const BitstreamBuffer& buffer) {
  available_buffers_.push_back(buffer);
  EncodeTask();
}

void FakeVideoEncodeAccelerator::RequestEncodingParametersChange(
    uint32 bitrate,
    uint32 framerate) {
  stored_bitrates_.push_back(bitrate);
}

void FakeVideoEncodeAccelerator::Destroy() { delete this; }

void FakeVideoEncodeAccelerator::SendDummyFrameForTesting(bool key_frame) {
  task_runner_->PostTask(
        FROM_HERE,
        base::Bind(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady,
                   weak_this_factory_.GetWeakPtr(),
                   0,
                   23,
                   key_frame));
}

void FakeVideoEncodeAccelerator::SetWillInitializationSucceed(
    bool will_initialization_succeed) {
  will_initialization_succeed_ = will_initialization_succeed;
}

void FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers(
    unsigned int input_count,
    const gfx::Size& input_coded_size,
    size_t output_buffer_size) const {
  client_->RequireBitstreamBuffers(
      input_count, input_coded_size, output_buffer_size);
}

void FakeVideoEncodeAccelerator::EncodeTask() {
  while (!queued_frames_.empty() && !available_buffers_.empty()) {
    bool force_key_frame = queued_frames_.front();
    queued_frames_.pop();
    int32 bitstream_buffer_id = available_buffers_.front().id();
    available_buffers_.pop_front();
    bool key_frame = next_frame_is_first_frame_ || force_key_frame;
    next_frame_is_first_frame_ = false;
    task_runner_->PostTask(
        FROM_HERE,
        base::Bind(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady,
                   weak_this_factory_.GetWeakPtr(),
                   bitstream_buffer_id,
                   kMinimumOutputBufferSize,
                   key_frame));
  }
}

void FakeVideoEncodeAccelerator::DoBitstreamBufferReady(
    int32 bitstream_buffer_id,
    size_t payload_size,
    bool key_frame) const {
  client_->BitstreamBufferReady(bitstream_buffer_id,
                                payload_size,
                                key_frame);
}

}  // namespace media