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

#include <SkVideoDecoder.h>

Public Member Functions

 SkVideoDecoder (GrRecordingContext *=nullptr)
 
 ~SkVideoDecoder ()
 
void reset ()
 
void setGrContext (GrRecordingContext *rContext)
 
bool loadStream (std::unique_ptr< SkStream >)
 
bool rewind ()
 
SkISize dimensions () const
 
double duration () const
 
sk_sp< SkImagenextImage (double *timeStamp=nullptr)
 

Detailed Description

Definition at line 23 of file SkVideoDecoder.h.

Constructor & Destructor Documentation

◆ SkVideoDecoder()

SkVideoDecoder::SkVideoDecoder ( GrRecordingContext rContext = nullptr)

Definition at line 314 of file SkVideoDecoder.cpp.

314: fRecordingContext(rContext) {}

◆ ~SkVideoDecoder()

SkVideoDecoder::~SkVideoDecoder ( )

Definition at line 316 of file SkVideoDecoder.cpp.

316 {
317 this->reset();
318}

Member Function Documentation

◆ dimensions()

SkISize SkVideoDecoder::dimensions ( ) const

Definition at line 412 of file SkVideoDecoder.cpp.

412 {
413 if (!fFormatCtx) {
414 return {0, 0};
415 }
416
417 AVStream* strm = fFormatCtx->streams[fStreamIndex];
418 return {strm->codecpar->width, strm->codecpar->height};
419}

◆ duration()

double SkVideoDecoder::duration ( ) const

Definition at line 421 of file SkVideoDecoder.cpp.

421 {
422 if (!fFormatCtx) {
423 return 0;
424 }
425
426 AVStream* strm = fFormatCtx->streams[fStreamIndex];
427 AVRational base = strm->time_base;
428 return 1.0 * strm->duration * base.num / base.den;
429}

◆ loadStream()

bool SkVideoDecoder::loadStream ( std::unique_ptr< SkStream stream)

Definition at line 344 of file SkVideoDecoder.cpp.

344 {
345 this->reset();
346 if (!stream) {
347 return false;
348 }
349
350 int bufferSize = 4 * 1024;
351 uint8_t* buffer = (uint8_t*)av_malloc(bufferSize);
352 if (!buffer) {
353 return false;
354 }
355
356 fStream = std::move(stream);
357 fStreamCtx = avio_alloc_context(buffer, bufferSize, 0, fStream.get(),
359 if (!fStreamCtx) {
360 av_freep(buffer);
361 this->reset();
362 return false;
363 }
364
365 fFormatCtx = avformat_alloc_context();
366 if (!fFormatCtx) {
367 this->reset();
368 return false;
369 }
370 fFormatCtx->pb = fStreamCtx;
371
372 int err = avformat_open_input(&fFormatCtx, nullptr, nullptr, nullptr);
373 if (err < 0) {
374 SkDebugf("avformat_open_input failed %d\n", err);
375 return false;
376 }
377
378 const AVCodec* codec;
379 fStreamIndex = av_find_best_stream(fFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);
380 if (fStreamIndex < 0) {
381 SkDebugf("av_find_best_stream failed %d\n", fStreamIndex);
382 this->reset();
383 return false;
384 }
385
386 SkASSERT(codec);
387 fDecoderCtx = avcodec_alloc_context3(codec);
388
389 AVStream* strm = fFormatCtx->streams[fStreamIndex];
390 if ((err = avcodec_parameters_to_context(fDecoderCtx, strm->codecpar)) < 0) {
391 SkDebugf("avcodec_parameters_to_context failed %d\n", err);
392 this->reset();
393 return false;
394 }
395
396 if ((err = avcodec_open2(fDecoderCtx, codec, nullptr)) < 0) {
397 SkDebugf("avcodec_open2 failed %d\n", err);
398 this->reset();
399 return false;
400 }
401
402 fFrame = av_frame_alloc();
403 SkASSERT(fFrame);
404
405 av_init_packet(&fPacket); // is there a "free" call?
406
407 fMode = kProcessing_Mode;
408
409 return true;
410}
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static int skstream_read_packet(void *ctx, uint8_t *dstBuffer, int dstSize)
static int64_t skstream_seek_packet(void *ctx, int64_t pos, int whence)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126

◆ nextImage()

sk_sp< SkImage > SkVideoDecoder::nextImage ( double *  timeStamp = nullptr)

Definition at line 260 of file SkVideoDecoder.cpp.

260 {
261 double defaultTimeStampStorage = 0;
262 if (!timeStamp) {
263 timeStamp = &defaultTimeStampStorage;
264 }
265
266 if (fFormatCtx == nullptr) {
267 return nullptr;
268 }
269
270 if (fMode == kProcessing_Mode) {
271 // We sit in a loop, waiting for the codec to have received enough data (packets)
272 // to have at least one frame available.
273 // Treat non-zero return as EOF (or error, which we will decide is also EOF)
274 while (!av_read_frame(fFormatCtx, &fPacket)) {
275 if (fPacket.stream_index != fStreamIndex) {
276 // got a packet for a stream other than our (video) stream, so continue
277 continue;
278 }
279
280 int ret = avcodec_send_packet(fDecoderCtx, &fPacket);
281 if (ret == AVERROR(EAGAIN)) {
282 // may signal that we have plenty already, encouraging us to call receive_frame
283 // so we don't treat this as an error.
284 ret = 0;
285 }
286 (void)check_err(ret); // we try to continue if there was an error
287
288 int silentList[] = {
289 -35, // Resource temporarily unavailable (need more packets)
290 0,
291 };
292 if (check_err(avcodec_receive_frame(fDecoderCtx, fFrame), silentList)) {
293 // this may be just "needs more input", so we try to continue
294 } else {
295 *timeStamp = this->computeTimeStamp(fFrame);
296 return this->convertFrame(fFrame);
297 }
298 }
299
300 fMode = kDraining_Mode;
301 (void)avcodec_send_packet(fDecoderCtx, nullptr); // signal to start draining
302 }
303 if (fMode == kDraining_Mode) {
304 if (avcodec_receive_frame(fDecoderCtx, fFrame) >= 0) {
305 *timeStamp = this->computeTimeStamp(fFrame);
306 return this->convertFrame(fFrame);
307 }
308 // else we decide we're done
309 fMode = kDone_Mode;
310 }
311 return nullptr;
312}
static bool check_err(int err, const int silentList[]=nullptr)

◆ reset()

void SkVideoDecoder::reset ( )

Definition at line 320 of file SkVideoDecoder.cpp.

320 {
321 if (fFrame) {
322 av_frame_free(&fFrame);
323 fFrame = nullptr;
324 }
325 if (fDecoderCtx) {
326 avcodec_free_context(&fDecoderCtx);
327 fDecoderCtx = nullptr;
328 }
329 if (fFormatCtx) {
330 avformat_close_input(&fFormatCtx);
331 fFormatCtx = nullptr;
332 }
333 if (fStreamCtx) {
334 av_freep(&fStreamCtx->buffer);
335 avio_context_free(&fStreamCtx);
336 fStreamCtx = nullptr;
337 }
338
339 fStream.reset(nullptr);
340 fStreamIndex = -1;
341 fMode = kDone_Mode;
342}

◆ rewind()

bool SkVideoDecoder::rewind ( )

Definition at line 431 of file SkVideoDecoder.cpp.

431 {
432 auto stream = std::move(fStream);
433 this->reset();
434 if (stream) {
435 stream->rewind();
436 }
437 return this->loadStream(std::move(stream));
438}
bool loadStream(std::unique_ptr< SkStream >)

◆ setGrContext()

void SkVideoDecoder::setGrContext ( GrRecordingContext rContext)
inline

Definition at line 29 of file SkVideoDecoder.h.

29{ fRecordingContext = rContext; }

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