Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: media/base/mac/videotoolbox_helpers.cc

Issue 2529493002: mac: Remove more media/base/mac glue unneeded now that we target 10.9 (Closed)
Patch Set: . Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/base/mac/videotoolbox_helpers.h ('k') | media/capture/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/base/mac/videotoolbox_helpers.h" 5 #include "media/base/mac/videotoolbox_helpers.h"
6 6
7 #include <array> 7 #include <array>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/big_endian.h" 10 #include "base/big_endian.h"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 avcc_buffer += sizeof(NalSizeType); 128 avcc_buffer += sizeof(NalSizeType);
129 129
130 DCHECK_GE(bytes_left, nal_size); 130 DCHECK_GE(bytes_left, nal_size);
131 annexb_buffer->Append(kAnnexBHeaderBytes, sizeof(kAnnexBHeaderBytes)); 131 annexb_buffer->Append(kAnnexBHeaderBytes, sizeof(kAnnexBHeaderBytes));
132 annexb_buffer->Append(avcc_buffer, nal_size); 132 annexb_buffer->Append(avcc_buffer, nal_size);
133 bytes_left -= nal_size; 133 bytes_left -= nal_size;
134 avcc_buffer += nal_size; 134 avcc_buffer += nal_size;
135 } 135 }
136 } 136 }
137 137
138 bool CopySampleBufferToAnnexBBuffer(CoreMediaGlue::CMSampleBufferRef sbuf, 138 bool CopySampleBufferToAnnexBBuffer(CMSampleBufferRef sbuf,
139 AnnexBBuffer* annexb_buffer, 139 AnnexBBuffer* annexb_buffer,
140 bool keyframe) { 140 bool keyframe) {
141 // Perform two pass, one to figure out the total output size, and another to 141 // Perform two pass, one to figure out the total output size, and another to
142 // copy the data after having performed a single output allocation. Note that 142 // copy the data after having performed a single output allocation. Note that
143 // we'll allocate a bit more because we'll count 4 bytes instead of 3 for 143 // we'll allocate a bit more because we'll count 4 bytes instead of 3 for
144 // video NALs. 144 // video NALs.
145 OSStatus status; 145 OSStatus status;
146 146
147 // Get the sample buffer's block buffer and format description. 147 // Get the sample buffer's block buffer and format description.
148 auto* bb = CoreMediaGlue::CMSampleBufferGetDataBuffer(sbuf); 148 auto* bb = CMSampleBufferGetDataBuffer(sbuf);
149 DCHECK(bb); 149 DCHECK(bb);
150 auto* fdesc = CoreMediaGlue::CMSampleBufferGetFormatDescription(sbuf); 150 auto* fdesc = CMSampleBufferGetFormatDescription(sbuf);
151 DCHECK(fdesc); 151 DCHECK(fdesc);
152 152
153 size_t bb_size = CoreMediaGlue::CMBlockBufferGetDataLength(bb); 153 size_t bb_size = CMBlockBufferGetDataLength(bb);
154 size_t total_bytes = bb_size; 154 size_t total_bytes = bb_size;
155 155
156 size_t pset_count; 156 size_t pset_count;
157 int nal_size_field_bytes; 157 int nal_size_field_bytes;
158 status = CoreMediaGlue::CMVideoFormatDescriptionGetH264ParameterSetAtIndex( 158 status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
159 fdesc, 0, nullptr, nullptr, &pset_count, &nal_size_field_bytes); 159 fdesc, 0, nullptr, nullptr, &pset_count, &nal_size_field_bytes);
160 if (status == 160 if (status == kCMFormatDescriptionBridgeError_InvalidParameter) {
161 CoreMediaGlue::kCMFormatDescriptionBridgeError_InvalidParameter) {
162 DLOG(WARNING) << " assuming 2 parameter sets and 4 bytes NAL length header"; 161 DLOG(WARNING) << " assuming 2 parameter sets and 4 bytes NAL length header";
163 pset_count = 2; 162 pset_count = 2;
164 nal_size_field_bytes = 4; 163 nal_size_field_bytes = 4;
165 } else if (status != noErr) { 164 } else if (status != noErr) {
166 DLOG(ERROR) 165 DLOG(ERROR)
167 << " CMVideoFormatDescriptionGetH264ParameterSetAtIndex failed: " 166 << " CMVideoFormatDescriptionGetH264ParameterSetAtIndex failed: "
168 << status; 167 << status;
169 return false; 168 return false;
170 } 169 }
171 170
172 if (keyframe) { 171 if (keyframe) {
173 const uint8_t* pset; 172 const uint8_t* pset;
174 size_t pset_size; 173 size_t pset_size;
175 for (size_t pset_i = 0; pset_i < pset_count; ++pset_i) { 174 for (size_t pset_i = 0; pset_i < pset_count; ++pset_i) {
176 status = 175 status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
177 CoreMediaGlue::CMVideoFormatDescriptionGetH264ParameterSetAtIndex( 176 fdesc, pset_i, &pset, &pset_size, nullptr, nullptr);
178 fdesc, pset_i, &pset, &pset_size, nullptr, nullptr);
179 if (status != noErr) { 177 if (status != noErr) {
180 DLOG(ERROR) 178 DLOG(ERROR)
181 << " CMVideoFormatDescriptionGetH264ParameterSetAtIndex failed: " 179 << " CMVideoFormatDescriptionGetH264ParameterSetAtIndex failed: "
182 << status; 180 << status;
183 return false; 181 return false;
184 } 182 }
185 total_bytes += pset_size + nal_size_field_bytes; 183 total_bytes += pset_size + nal_size_field_bytes;
186 } 184 }
187 } 185 }
188 186
189 if (!annexb_buffer->Reserve(total_bytes)) { 187 if (!annexb_buffer->Reserve(total_bytes)) {
190 DLOG(ERROR) << "Cannot fit encode output into bitstream buffer. Requested:" 188 DLOG(ERROR) << "Cannot fit encode output into bitstream buffer. Requested:"
191 << total_bytes; 189 << total_bytes;
192 return false; 190 return false;
193 } 191 }
194 192
195 // Copy all parameter sets before keyframes. 193 // Copy all parameter sets before keyframes.
196 if (keyframe) { 194 if (keyframe) {
197 const uint8_t* pset; 195 const uint8_t* pset;
198 size_t pset_size; 196 size_t pset_size;
199 for (size_t pset_i = 0; pset_i < pset_count; ++pset_i) { 197 for (size_t pset_i = 0; pset_i < pset_count; ++pset_i) {
200 status = 198 status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
201 CoreMediaGlue::CMVideoFormatDescriptionGetH264ParameterSetAtIndex( 199 fdesc, pset_i, &pset, &pset_size, nullptr, nullptr);
202 fdesc, pset_i, &pset, &pset_size, nullptr, nullptr);
203 if (status != noErr) { 200 if (status != noErr) {
204 DLOG(ERROR) 201 DLOG(ERROR)
205 << " CMVideoFormatDescriptionGetH264ParameterSetAtIndex failed: " 202 << " CMVideoFormatDescriptionGetH264ParameterSetAtIndex failed: "
206 << status; 203 << status;
207 return false; 204 return false;
208 } 205 }
209 annexb_buffer->Append(kAnnexBHeaderBytes, sizeof(kAnnexBHeaderBytes)); 206 annexb_buffer->Append(kAnnexBHeaderBytes, sizeof(kAnnexBHeaderBytes));
210 annexb_buffer->Append(reinterpret_cast<const char*>(pset), pset_size); 207 annexb_buffer->Append(reinterpret_cast<const char*>(pset), pset_size);
211 } 208 }
212 } 209 }
213 210
214 // Block buffers can be composed of non-contiguous chunks. For the sake of 211 // Block buffers can be composed of non-contiguous chunks. For the sake of
215 // keeping this code simple, flatten non-contiguous block buffers. 212 // keeping this code simple, flatten non-contiguous block buffers.
216 base::ScopedCFTypeRef<CoreMediaGlue::CMBlockBufferRef> contiguous_bb( 213 base::ScopedCFTypeRef<CMBlockBufferRef> contiguous_bb(
217 bb, base::scoped_policy::RETAIN); 214 bb, base::scoped_policy::RETAIN);
218 if (!CoreMediaGlue::CMBlockBufferIsRangeContiguous(bb, 0, 0)) { 215 if (!CMBlockBufferIsRangeContiguous(bb, 0, 0)) {
219 contiguous_bb.reset(); 216 contiguous_bb.reset();
220 status = CoreMediaGlue::CMBlockBufferCreateContiguous( 217 status = CMBlockBufferCreateContiguous(kCFAllocatorDefault, bb,
221 kCFAllocatorDefault, bb, kCFAllocatorDefault, nullptr, 0, 0, 0, 218 kCFAllocatorDefault, nullptr, 0, 0,
222 contiguous_bb.InitializeInto()); 219 0, contiguous_bb.InitializeInto());
223 if (status != noErr) { 220 if (status != noErr) {
224 DLOG(ERROR) << " CMBlockBufferCreateContiguous failed: " << status; 221 DLOG(ERROR) << " CMBlockBufferCreateContiguous failed: " << status;
225 return false; 222 return false;
226 } 223 }
227 } 224 }
228 225
229 // Copy all the NAL units. In the process convert them from AVCC format 226 // Copy all the NAL units. In the process convert them from AVCC format
230 // (length header) to AnnexB format (start code). 227 // (length header) to AnnexB format (start code).
231 char* bb_data; 228 char* bb_data;
232 status = CoreMediaGlue::CMBlockBufferGetDataPointer(contiguous_bb, 0, nullptr, 229 status =
233 nullptr, &bb_data); 230 CMBlockBufferGetDataPointer(contiguous_bb, 0, nullptr, nullptr, &bb_data);
234 if (status != noErr) { 231 if (status != noErr) {
235 DLOG(ERROR) << " CMBlockBufferGetDataPointer failed: " << status; 232 DLOG(ERROR) << " CMBlockBufferGetDataPointer failed: " << status;
236 return false; 233 return false;
237 } 234 }
238 235
239 if (nal_size_field_bytes == 1) { 236 if (nal_size_field_bytes == 1) {
240 CopyNalsToAnnexB<uint8_t>(bb_data, bb_size, annexb_buffer); 237 CopyNalsToAnnexB<uint8_t>(bb_data, bb_size, annexb_buffer);
241 } else if (nal_size_field_bytes == 2) { 238 } else if (nal_size_field_bytes == 2) {
242 CopyNalsToAnnexB<uint16_t>(bb_data, bb_size, annexb_buffer); 239 CopyNalsToAnnexB<uint16_t>(bb_data, bb_size, annexb_buffer);
243 } else if (nal_size_field_bytes == 4) { 240 } else if (nal_size_field_bytes == 4) {
244 CopyNalsToAnnexB<uint32_t>(bb_data, bb_size, annexb_buffer); 241 CopyNalsToAnnexB<uint32_t>(bb_data, bb_size, annexb_buffer);
245 } else { 242 } else {
246 NOTREACHED(); 243 NOTREACHED();
247 } 244 }
248 return true; 245 return true;
249 } 246 }
250 247
251 bool CopySampleBufferToAnnexBBuffer(CoreMediaGlue::CMSampleBufferRef sbuf, 248 bool CopySampleBufferToAnnexBBuffer(CMSampleBufferRef sbuf,
252 bool keyframe, 249 bool keyframe,
253 std::string* annexb_buffer) { 250 std::string* annexb_buffer) {
254 StringAnnexBBuffer buffer(annexb_buffer); 251 StringAnnexBBuffer buffer(annexb_buffer);
255 return CopySampleBufferToAnnexBBuffer(sbuf, &buffer, keyframe); 252 return CopySampleBufferToAnnexBBuffer(sbuf, &buffer, keyframe);
256 } 253 }
257 254
258 bool CopySampleBufferToAnnexBBuffer(CoreMediaGlue::CMSampleBufferRef sbuf, 255 bool CopySampleBufferToAnnexBBuffer(CMSampleBufferRef sbuf,
259 bool keyframe, 256 bool keyframe,
260 size_t annexb_buffer_size, 257 size_t annexb_buffer_size,
261 char* annexb_buffer, 258 char* annexb_buffer,
262 size_t* used_buffer_size) { 259 size_t* used_buffer_size) {
263 RawAnnexBBuffer buffer(annexb_buffer, annexb_buffer_size); 260 RawAnnexBBuffer buffer(annexb_buffer, annexb_buffer_size);
264 const bool copy_rv = CopySampleBufferToAnnexBBuffer(sbuf, &buffer, keyframe); 261 const bool copy_rv = CopySampleBufferToAnnexBBuffer(sbuf, &buffer, keyframe);
265 *used_buffer_size = buffer.GetReservedSize(); 262 *used_buffer_size = buffer.GetReservedSize();
266 return copy_rv; 263 return copy_rv;
267 } 264 }
268 265
269 SessionPropertySetter::SessionPropertySetter( 266 SessionPropertySetter::SessionPropertySetter(
270 base::ScopedCFTypeRef<VideoToolboxGlue::VTCompressionSessionRef> session, 267 base::ScopedCFTypeRef<VTCompressionSessionRef> session)
271 const VideoToolboxGlue* const glue) 268 : session_(session) {}
272 : session_(session), glue_(glue) {}
273 269
274 SessionPropertySetter::~SessionPropertySetter() {} 270 SessionPropertySetter::~SessionPropertySetter() {}
275 271
276 bool SessionPropertySetter::Set(CFStringRef key, int32_t value) { 272 bool SessionPropertySetter::Set(CFStringRef key, int32_t value) {
277 DCHECK(session_); 273 DCHECK(session_);
278 DCHECK(glue_);
279 base::ScopedCFTypeRef<CFNumberRef> cfvalue( 274 base::ScopedCFTypeRef<CFNumberRef> cfvalue(
280 CFNumberCreate(nullptr, kCFNumberSInt32Type, &value)); 275 CFNumberCreate(nullptr, kCFNumberSInt32Type, &value));
281 return glue_->VTSessionSetProperty(session_, key, cfvalue) == noErr; 276 return VTSessionSetProperty(session_, key, cfvalue) == noErr;
282 } 277 }
283 278
284 bool SessionPropertySetter::Set(CFStringRef key, bool value) { 279 bool SessionPropertySetter::Set(CFStringRef key, bool value) {
285 DCHECK(session_); 280 DCHECK(session_);
286 DCHECK(glue_);
287 CFBooleanRef cfvalue = (value) ? kCFBooleanTrue : kCFBooleanFalse; 281 CFBooleanRef cfvalue = (value) ? kCFBooleanTrue : kCFBooleanFalse;
288 return glue_->VTSessionSetProperty(session_, key, cfvalue) == noErr; 282 return VTSessionSetProperty(session_, key, cfvalue) == noErr;
289 } 283 }
290 284
291 bool SessionPropertySetter::Set(CFStringRef key, CFStringRef value) { 285 bool SessionPropertySetter::Set(CFStringRef key, CFStringRef value) {
292 DCHECK(session_); 286 DCHECK(session_);
293 DCHECK(glue_); 287 return VTSessionSetProperty(session_, key, value) == noErr;
294 return glue_->VTSessionSetProperty(session_, key, value) == noErr;
295 } 288 }
296 289
297 bool SessionPropertySetter::Set(CFStringRef key, CFArrayRef value) { 290 bool SessionPropertySetter::Set(CFStringRef key, CFArrayRef value) {
298 DCHECK(session_); 291 DCHECK(session_);
299 DCHECK(glue_); 292 return VTSessionSetProperty(session_, key, value) == noErr;
300 return glue_->VTSessionSetProperty(session_, key, value) == noErr;
301 } 293 }
302 294
303 } // namespace video_toolbox 295 } // namespace video_toolbox
304 296
305 } // namespace media 297 } // namespace media
OLDNEW
« no previous file with comments | « media/base/mac/videotoolbox_helpers.h ('k') | media/capture/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698