Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
SkVideoEncoder Class Reference

#include <SkVideoEncoder.h>

Public Member Functions

 SkVideoEncoder ()
 
 ~SkVideoEncoder ()
 
bool beginRecording (SkISize, int fps)
 
bool addFrame (const SkPixmap &)
 
SkCanvasbeginFrame ()
 
bool endFrame ()
 
sk_sp< SkDataendRecording ()
 

Detailed Description

Definition at line 28 of file SkVideoEncoder.h.

Constructor & Destructor Documentation

◆ SkVideoEncoder()

SkVideoEncoder::SkVideoEncoder ( )

Definition at line 112 of file SkVideoEncoder.cpp.

112 {
113 fInfo = SkImageInfo::MakeUnknown();
114}
static SkImageInfo MakeUnknown()
Definition: SkImageInfo.h:357

◆ ~SkVideoEncoder()

SkVideoEncoder::~SkVideoEncoder ( )

Definition at line 116 of file SkVideoEncoder.cpp.

116 {
117 this->reset();
118
119 if (fSWScaleCtx) {
120 sws_freeContext(fSWScaleCtx);
121 }
122}

Member Function Documentation

◆ addFrame()

bool SkVideoEncoder::addFrame ( const SkPixmap pm)

If you have your own pixmap, call addFrame(). Note this may fail if it uses an unsupported ColorType (requires kN32_SkColorType) or AlphaType, or the dimensions don't match those set in beginRecording.

Definition at line 257 of file SkVideoEncoder.cpp.

257 {
258 if (!is_valid(pm.dimensions())) {
259 return false;
260 }
261 if (pm.info().colorType() != fInfo.colorType()) {
262 return false;
263 }
264 /* make sure the frame data is writable */
265 if (check_err(av_frame_make_writable(fFrame))) {
266 return false;
267 }
268
269 fFrame->pts = fCurrentPTS;
270 fCurrentPTS += fDeltaPTS;
271
272 const uint8_t* src[] = { (const uint8_t*)pm.addr() };
273 const int strides[] = { SkToInt(pm.rowBytes()) };
274 sws_scale(fSWScaleCtx, src, strides, 0, fInfo.height(), fFrame->data, fFrame->linesize);
275
276 return this->sendFrame(fFrame);
277}
constexpr int SkToInt(S x)
Definition: SkTo.h:29
static bool check_err(int err, const int silentList[]=nullptr)
static bool is_valid(SkISize dim)
size_t rowBytes() const
Definition: SkPixmap.h:145
const SkImageInfo & info() const
Definition: SkPixmap.h:135
const void * addr() const
Definition: SkPixmap.h:153
SkISize dimensions() const
Definition: SkPixmap.h:171
SkColorType colorType() const
Definition: SkImageInfo.h:373
int height() const
Definition: SkImageInfo.h:371

◆ beginFrame()

SkCanvas * SkVideoEncoder::beginFrame ( )

As an alternative to calling addFrame(), you can call beginFrame/endFrame, and the encoder will manage allocating a surface/canvas for you.

SkCanvas* canvas = encoder.beginFrame(); // your drawing code here, drawing into canvas encoder.endFrame();

Definition at line 304 of file SkVideoEncoder.cpp.

304 {
305 if (!fSurface) {
306 fSurface = SkSurfaces::Raster(fInfo);
307 if (!fSurface) {
308 return nullptr;
309 }
310 }
311 SkCanvas* canvas = fSurface->getCanvas();
312 canvas->restoreToCount(1);
313 canvas->clear(0);
314 return canvas;
315}
void clear(SkColor color)
Definition: SkCanvas.h:1199
void restoreToCount(int saveCount)
Definition: SkCanvas.cpp:478
SkCanvas * getCanvas()
Definition: SkSurface.cpp:82
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)

◆ beginRecording()

bool SkVideoEncoder::beginRecording ( SkISize  dim,
int  fps 
)

Begins a new recording. Balance this (after adding all of your frames) with a call to endRecording().

Definition at line 228 of file SkVideoEncoder.cpp.

228 {
229 if (!is_valid(dim)) {
230 return false;
231 }
232
234 sk_sp<SkColorSpace> cs = nullptr; // should we use this?
235 fInfo = SkImageInfo::MakeN32(dim.width(), dim.height(), alphaType, cs);
236 if (!this->init(fps)) {
237 return false;
238 }
239
240 fCurrentPTS = 0;
241 fDeltaPTS = 1;
242
243 const auto fmt = kN32_SkColorType == kRGBA_8888_SkColorType ? AV_PIX_FMT_RGBA : AV_PIX_FMT_BGRA;
244 SkASSERT(sws_isSupportedInput(fmt) > 0);
245 SkASSERT(sws_isSupportedOutput(AV_PIX_FMT_YUV420P) > 0);
246 // sws_getCachedContext takes in either null or a previous ctx. It returns either a new ctx,
247 // or the same as the input if it is compatible with the inputs. Thus we never have to
248 // explicitly release our ctx until the destructor, since sws_getCachedContext takes care
249 // of freeing the old as needed if/when it returns a new one.
250 fSWScaleCtx = sws_getCachedContext(fSWScaleCtx,
251 dim.width(), dim.height(), fmt,
252 dim.width(), dim.height(), AV_PIX_FMT_YUV420P,
253 SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);
254 return fSWScaleCtx != nullptr;
255}
SkAlphaType
Definition: SkAlphaType.h:26
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
static SkString fmt(SkColor4f c)
Definition: p3.cpp:43
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)

◆ endFrame()

bool SkVideoEncoder::endFrame ( )

Definition at line 317 of file SkVideoEncoder.cpp.

317 {
318 if (!fSurface) {
319 return false;
320 }
321 SkPixmap pm;
322 return fSurface->peekPixels(&pm) && this->addFrame(pm);
323}
bool peekPixels(SkPixmap *pixmap)
Definition: SkSurface.cpp:121
bool addFrame(const SkPixmap &)

◆ endRecording()

sk_sp< SkData > SkVideoEncoder::endRecording ( )

Call this after having added all of your frames. After calling this, no more frames can be added to this recording. To record a new video, call beginRecording().

Definition at line 325 of file SkVideoEncoder.cpp.

325 {
326 if (!fFormatCtx) {
327 return nullptr;
328 }
329
330 this->sendFrame(nullptr);
331 av_write_trailer(fFormatCtx);
332
333 sk_sp<SkData> data = fWStream->detachAsData();
334 this->reset();
335 return data;
336}
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

The documentation for this class was generated from the following files: