OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/webm/chromeos/webm_encoder.h" | 5 #include "media/webm/chromeos/webm_encoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_generic_obj.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "libyuv/convert.h" | 11 #include "libyuv/convert.h" |
12 #include "libyuv/video_common.h" | 12 #include "libyuv/video_common.h" |
13 #include "third_party/skia/include/core/SkBitmap.h" | 13 #include "third_party/skia/include/core/SkBitmap.h" |
14 | 14 |
15 extern "C" { | 15 extern "C" { |
16 // Getting the right degree of C compatibility has been a constant struggle. | 16 // Getting the right degree of C compatibility has been a constant struggle. |
17 // - Stroustrup, C++ Report, 12(7), July/August 2000. | 17 // - Stroustrup, C++ Report, 12(7), July/August 2000. |
18 #define private priv | 18 #define private priv |
19 #include "third_party/libvpx/source/libvpx/libmkv/EbmlIDs.h" | 19 #include "third_party/libvpx/source/libvpx/libmkv/EbmlIDs.h" |
20 #include "third_party/libvpx/source/libvpx/libmkv/EbmlWriter.h" | 20 #include "third_party/libvpx/source/libvpx/libmkv/EbmlWriter.h" |
21 #undef private | 21 #undef private |
22 } | 22 } |
23 | 23 |
24 // Number of encoder threads to use. | 24 // Number of encoder threads to use. |
25 static const int kNumEncoderThreads = 2; | 25 static const int kNumEncoderThreads = 2; |
26 | 26 |
27 // Need a fixed size serializer for the track ID. libmkv provides a 64 bit | 27 // Need a fixed size serializer for the track ID. libmkv provides a 64 bit |
28 // one, but not a 32 bit one. | 28 // one, but not a 32 bit one. |
29 static void Ebml_SerializeUnsigned32(EbmlGlobal* ebml, | 29 static void Ebml_SerializeUnsigned32(EbmlGlobal* ebml, |
30 unsigned long class_id, | 30 unsigned long class_id, |
31 uint64_t value) { | 31 uint64_t value) { |
32 uint8 size_serialized = 4 | 0x80; | 32 uint8 size_serialized = 4 | 0x80; |
33 Ebml_WriteID(ebml, class_id); | 33 Ebml_WriteID(ebml, class_id); |
34 Ebml_Serialize(ebml, &size_serialized, sizeof(size_serialized), 1); | 34 Ebml_Serialize(ebml, &size_serialized, sizeof(size_serialized), 1); |
35 Ebml_Serialize(ebml, &value, sizeof(value), 4); | 35 Ebml_Serialize(ebml, &value, sizeof(value), 4); |
36 } | 36 } |
37 | 37 |
38 // Wrapper functor for vpx_codec_destroy(). | 38 // Wrapper functor for vpx_codec_destroy(). |
39 class VpxCodecDestroyHelper { | 39 struct VpxCodecDeleter { |
40 public: | |
41 void operator()(vpx_codec_ctx_t* codec) { | 40 void operator()(vpx_codec_ctx_t* codec) { |
42 vpx_codec_destroy(codec); | 41 vpx_codec_destroy(codec); |
43 } | 42 } |
44 }; | 43 }; |
45 | 44 |
46 // Wrapper functor for vpx_img_free(). | 45 // Wrapper functor for vpx_img_free(). |
47 class VpxImgFreeHelper { | 46 struct VpxImgDeleter { |
48 public: | |
49 void operator()(vpx_image_t* image) { | 47 void operator()(vpx_image_t* image) { |
50 vpx_img_free(image); | 48 vpx_img_free(image); |
51 } | 49 } |
52 }; | 50 }; |
53 | 51 |
54 namespace media { | 52 namespace media { |
55 | 53 |
56 namespace chromeos { | 54 namespace chromeos { |
57 | 55 |
58 WebmEncoder::WebmEncoder(const base::FilePath& output_path, | 56 WebmEncoder::WebmEncoder(const base::FilePath& output_path, |
(...skipping 23 matching lines...) Expand all Loading... |
82 height_ = sprite.width(); | 80 height_ = sprite.width(); |
83 fps_.num = fps_n; | 81 fps_.num = fps_n; |
84 fps_.den = fps_d; | 82 fps_.den = fps_d; |
85 | 83 |
86 // Sprite is tiled vertically. | 84 // Sprite is tiled vertically. |
87 frame_count_ = sprite.height() / width_; | 85 frame_count_ = sprite.height() / width_; |
88 | 86 |
89 vpx_image_t image; | 87 vpx_image_t image; |
90 vpx_img_alloc(&image, VPX_IMG_FMT_I420, width_, height_, 16); | 88 vpx_img_alloc(&image, VPX_IMG_FMT_I420, width_, height_, 16); |
91 // Ensure that image is freed after return. | 89 // Ensure that image is freed after return. |
92 ScopedGenericObj<vpx_image_t*, VpxImgFreeHelper> image_ptr(&image); | 90 scoped_ptr<vpx_image_t, VpxImgDeleter> image_ptr(&image); |
93 | 91 |
94 const vpx_codec_iface_t* codec_iface = vpx_codec_vp8_cx(); | 92 const vpx_codec_iface_t* codec_iface = vpx_codec_vp8_cx(); |
95 DCHECK(codec_iface); | 93 DCHECK(codec_iface); |
96 vpx_codec_err_t ret = vpx_codec_enc_config_default(codec_iface, &config_, 0); | 94 vpx_codec_err_t ret = vpx_codec_enc_config_default(codec_iface, &config_, 0); |
97 DCHECK_EQ(VPX_CODEC_OK, ret); | 95 DCHECK_EQ(VPX_CODEC_OK, ret); |
98 | 96 |
99 config_.rc_target_bitrate = bitrate_; | 97 config_.rc_target_bitrate = bitrate_; |
100 config_.g_w = width_; | 98 config_.g_w = width_; |
101 config_.g_h = height_; | 99 config_.g_h = height_; |
102 config_.g_pass = VPX_RC_ONE_PASS; | 100 config_.g_pass = VPX_RC_ONE_PASS; |
103 config_.g_profile = 0; // Default profile. | 101 config_.g_profile = 0; // Default profile. |
104 config_.g_threads = kNumEncoderThreads; | 102 config_.g_threads = kNumEncoderThreads; |
105 config_.rc_min_quantizer = 0; | 103 config_.rc_min_quantizer = 0; |
106 config_.rc_max_quantizer = 63; // Maximum possible range. | 104 config_.rc_max_quantizer = 63; // Maximum possible range. |
107 config_.g_timebase.num = fps_.den; | 105 config_.g_timebase.num = fps_.den; |
108 config_.g_timebase.den = fps_.num; | 106 config_.g_timebase.den = fps_.num; |
109 config_.kf_mode = VPX_KF_AUTO; // Auto key frames. | 107 config_.kf_mode = VPX_KF_AUTO; // Auto key frames. |
110 | 108 |
111 vpx_codec_ctx_t codec; | 109 vpx_codec_ctx_t codec; |
112 ret = vpx_codec_enc_init(&codec, codec_iface, &config_, 0); | 110 ret = vpx_codec_enc_init(&codec, codec_iface, &config_, 0); |
113 if (ret != VPX_CODEC_OK) | 111 if (ret != VPX_CODEC_OK) |
114 return false; | 112 return false; |
115 // Ensure that codec context is freed after return. | 113 // Ensure that codec context is freed after return. |
116 ScopedGenericObj<vpx_codec_ctx_t*, VpxCodecDestroyHelper> codec_ptr(&codec); | 114 scoped_ptr<vpx_codec_ctx_t, VpxCodecDeleter> codec_ptr(&codec); |
117 | 115 |
118 SkAutoLockPixels lock_sprite(sprite); | 116 SkAutoLockPixels lock_sprite(sprite); |
119 | 117 |
120 const uint8* src = reinterpret_cast<const uint8*>(sprite.getAddr32(0, 0)); | 118 const uint8* src = reinterpret_cast<const uint8*>(sprite.getAddr32(0, 0)); |
121 size_t src_frame_size = sprite.getSize(); | 119 size_t src_frame_size = sprite.getSize(); |
122 int crop_y = 0; | 120 int crop_y = 0; |
123 | 121 |
124 if (!WriteWebmHeader()) | 122 if (!WriteWebmHeader()) |
125 return false; | 123 return false; |
126 | 124 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 case 8: | 312 case 8: |
315 return EbmlSerializeHelper(static_cast<const int64_t*>(buffer), len); | 313 return EbmlSerializeHelper(static_cast<const int64_t*>(buffer), len); |
316 default: | 314 default: |
317 NOTREACHED() << "Invalid EbmlSerialize length: " << len; | 315 NOTREACHED() << "Invalid EbmlSerialize length: " << len; |
318 } | 316 } |
319 } | 317 } |
320 | 318 |
321 } // namespace chromeos | 319 } // namespace chromeos |
322 | 320 |
323 } // namespace media | 321 } // namespace media |
OLD | NEW |