LCOV - code coverage report
Current view: top level - dom/media/platforms/ffmpeg - FFmpegDataDecoder.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 78 1.3 %
Date: 2017-07-14 16:53:18 Functions: 0 75 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : 
       8             : #include <string.h>
       9             : #ifdef __GNUC__
      10             : #include <unistd.h>
      11             : #endif
      12             : 
      13             : #include "FFmpegLog.h"
      14             : #include "FFmpegDataDecoder.h"
      15             : #include "mozilla/TaskQueue.h"
      16             : #include "prsystem.h"
      17             : 
      18             : namespace mozilla {
      19             : 
      20          15 : StaticMutex FFmpegDataDecoder<LIBAV_VER>::sMonitor;
      21             : 
      22           0 : FFmpegDataDecoder<LIBAV_VER>::FFmpegDataDecoder(FFmpegLibWrapper* aLib,
      23             :                                                 TaskQueue* aTaskQueue,
      24           0 :                                                 AVCodecID aCodecID)
      25             :   : mLib(aLib)
      26             :   , mCodecContext(nullptr)
      27             :   , mFrame(NULL)
      28             :   , mExtraData(nullptr)
      29             :   , mCodecID(aCodecID)
      30           0 :   , mTaskQueue(aTaskQueue)
      31             : {
      32           0 :   MOZ_ASSERT(aLib);
      33           0 :   MOZ_COUNT_CTOR(FFmpegDataDecoder);
      34           0 : }
      35             : 
      36           0 : FFmpegDataDecoder<LIBAV_VER>::~FFmpegDataDecoder()
      37             : {
      38           0 :   MOZ_COUNT_DTOR(FFmpegDataDecoder);
      39           0 : }
      40             : 
      41             : nsresult
      42           0 : FFmpegDataDecoder<LIBAV_VER>::InitDecoder()
      43             : {
      44           0 :   FFMPEG_LOG("Initialising FFmpeg decoder.");
      45             : 
      46           0 :   AVCodec* codec = FindAVCodec(mLib, mCodecID);
      47           0 :   if (!codec) {
      48           0 :     NS_WARNING("Couldn't find ffmpeg decoder");
      49           0 :     return NS_ERROR_FAILURE;
      50             :   }
      51             : 
      52           0 :   StaticMutexAutoLock mon(sMonitor);
      53             : 
      54           0 :   if (!(mCodecContext = mLib->avcodec_alloc_context3(codec))) {
      55           0 :     NS_WARNING("Couldn't init ffmpeg context");
      56           0 :     return NS_ERROR_FAILURE;
      57             :   }
      58             : 
      59           0 :   mCodecContext->opaque = this;
      60             : 
      61           0 :   InitCodecContext();
      62             : 
      63           0 :   if (mExtraData) {
      64           0 :     mCodecContext->extradata_size = mExtraData->Length();
      65             :     // FFmpeg may use SIMD instructions to access the data which reads the
      66             :     // data in 32 bytes block. Must ensure we have enough data to read.
      67           0 :     mExtraData->AppendElements(FF_INPUT_BUFFER_PADDING_SIZE);
      68           0 :     mCodecContext->extradata = mExtraData->Elements();
      69             :   } else {
      70           0 :     mCodecContext->extradata_size = 0;
      71             :   }
      72             : 
      73           0 :   if (codec->capabilities & CODEC_CAP_DR1) {
      74           0 :     mCodecContext->flags |= CODEC_FLAG_EMU_EDGE;
      75             :   }
      76             : 
      77           0 :   if (mLib->avcodec_open2(mCodecContext, codec, nullptr) < 0) {
      78           0 :     NS_WARNING("Couldn't initialise ffmpeg decoder");
      79           0 :     mLib->avcodec_close(mCodecContext);
      80           0 :     mLib->av_freep(&mCodecContext);
      81           0 :     return NS_ERROR_FAILURE;
      82             :   }
      83             : 
      84           0 :   FFMPEG_LOG("FFmpeg init successful.");
      85           0 :   return NS_OK;
      86             : }
      87             : 
      88             : RefPtr<ShutdownPromise>
      89           0 : FFmpegDataDecoder<LIBAV_VER>::Shutdown()
      90             : {
      91           0 :   if (mTaskQueue) {
      92           0 :     RefPtr<FFmpegDataDecoder<LIBAV_VER>> self = this;
      93           0 :     return InvokeAsync(mTaskQueue, __func__, [self, this]() {
      94           0 :       ProcessShutdown();
      95           0 :       return ShutdownPromise::CreateAndResolve(true, __func__);
      96           0 :     });
      97             :   }
      98           0 :   ProcessShutdown();
      99           0 :   return ShutdownPromise::CreateAndResolve(true, __func__);
     100             : }
     101             : 
     102             : RefPtr<MediaDataDecoder::DecodePromise>
     103           0 : FFmpegDataDecoder<LIBAV_VER>::Decode(MediaRawData* aSample)
     104             : {
     105             :   return InvokeAsync<MediaRawData*>(mTaskQueue, this, __func__,
     106           0 :                                     &FFmpegDataDecoder::ProcessDecode, aSample);
     107             : }
     108             : 
     109             : RefPtr<MediaDataDecoder::FlushPromise>
     110           0 : FFmpegDataDecoder<LIBAV_VER>::Flush()
     111             : {
     112             :   return InvokeAsync(mTaskQueue, this, __func__,
     113           0 :                      &FFmpegDataDecoder<LIBAV_VER>::ProcessFlush);
     114             : }
     115             : 
     116             : RefPtr<MediaDataDecoder::DecodePromise>
     117           0 : FFmpegDataDecoder<LIBAV_VER>::Drain()
     118             : {
     119             :   return InvokeAsync(mTaskQueue, this, __func__,
     120           0 :                      &FFmpegDataDecoder<LIBAV_VER>::ProcessDrain);
     121             : }
     122             : 
     123             : RefPtr<MediaDataDecoder::FlushPromise>
     124           0 : FFmpegDataDecoder<LIBAV_VER>::ProcessFlush()
     125             : {
     126           0 :   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     127           0 :   if (mCodecContext) {
     128           0 :     mLib->avcodec_flush_buffers(mCodecContext);
     129             :   }
     130           0 :   return FlushPromise::CreateAndResolve(true, __func__);
     131             : }
     132             : 
     133             : void
     134           0 : FFmpegDataDecoder<LIBAV_VER>::ProcessShutdown()
     135             : {
     136           0 :   StaticMutexAutoLock mon(sMonitor);
     137             : 
     138           0 :   if (mCodecContext) {
     139           0 :     mLib->avcodec_close(mCodecContext);
     140           0 :     mLib->av_freep(&mCodecContext);
     141             : #if LIBAVCODEC_VERSION_MAJOR >= 55
     142           0 :     mLib->av_frame_free(&mFrame);
     143             : #elif LIBAVCODEC_VERSION_MAJOR == 54
     144           0 :     mLib->avcodec_free_frame(&mFrame);
     145             : #else
     146           0 :     mLib->av_freep(&mFrame);
     147             : #endif
     148             :   }
     149           0 : }
     150             : 
     151             : AVFrame*
     152           0 : FFmpegDataDecoder<LIBAV_VER>::PrepareFrame()
     153             : {
     154           0 :   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     155             : #if LIBAVCODEC_VERSION_MAJOR >= 55
     156           0 :   if (mFrame) {
     157           0 :     mLib->av_frame_unref(mFrame);
     158             :   } else {
     159           0 :     mFrame = mLib->av_frame_alloc();
     160             :   }
     161             : #elif LIBAVCODEC_VERSION_MAJOR == 54
     162           0 :   if (mFrame) {
     163           0 :     mLib->avcodec_get_frame_defaults(mFrame);
     164             :   } else {
     165           0 :     mFrame = mLib->avcodec_alloc_frame();
     166             :   }
     167             : #else
     168           0 :   mLib->av_freep(&mFrame);
     169           0 :   mFrame = mLib->avcodec_alloc_frame();
     170             : #endif
     171           0 :   return mFrame;
     172             : }
     173             : 
     174             : /* static */ AVCodec*
     175           0 : FFmpegDataDecoder<LIBAV_VER>::FindAVCodec(FFmpegLibWrapper* aLib,
     176             :                                           AVCodecID aCodec)
     177             : {
     178           0 :   return aLib->avcodec_find_decoder(aCodec);
     179             : }
     180             : 
     181             : } // namespace mozilla

Generated by: LCOV version 1.13