tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

h264_decoder_impl.h (3913B)


      1 /*
      2 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 *
     10 */
     11 
     12 #ifndef MODULES_VIDEO_CODING_CODECS_H264_H264_DECODER_IMPL_H_
     13 #define MODULES_VIDEO_CODING_CODECS_H264_H264_DECODER_IMPL_H_
     14 
     15 // Everything declared in this header is only required when WebRTC is
     16 // build with H264 support, please do not move anything out of the
     17 // #ifdef unless needed and tested.
     18 #ifdef WEBRTC_USE_H264
     19 
     20 #if defined(WEBRTC_WIN) && !defined(__clang__)
     21 #error "See: bugs.webrtc.org/9213#c13."
     22 #endif
     23 
     24 // CAVEAT: According to ffmpeg docs for avcodec_send_packet, ffmpeg requires a
     25 // few extra padding bytes after the end of input. And in addition, docs for
     26 // AV_INPUT_BUFFER_PADDING_SIZE says "If the first 23 bits of the additional
     27 // bytes are not 0, then damaged MPEG bitstreams could cause overread and
     28 // segfault."
     29 //
     30 // WebRTC doesn't ensure any such padding, and REQUIRES ffmpeg to be compiled
     31 // with CONFIG_SAFE_BITSTREAM_READER, which is intended to eliminate
     32 // out-of-bounds reads. ffmpeg docs doesn't say explicitly what effects this
     33 // flag has on the h.264 decoder or avcodec_send_packet, though, so this is in
     34 // some way depending on undocumented behavior. If any problems turn up, we may
     35 // have to add an extra copy operation, to enforce padding before buffers are
     36 // passed to ffmpeg.
     37 extern "C" {
     38 #include <libavcodec/avcodec.h>
     39 }  // extern "C"
     40 
     41 #include <cstdint>
     42 #include <memory>
     43 
     44 #include "api/video/encoded_image.h"
     45 #include "api/video_codecs/video_decoder.h"
     46 #include "common_video/h264/h264_bitstream_parser.h"
     47 #include "common_video/include/video_frame_buffer_pool.h"
     48 #include "modules/video_coding/codecs/h264/include/h264.h"
     49 
     50 namespace webrtc {
     51 
     52 struct AVCodecContextDeleter {
     53  void operator()(AVCodecContext* ptr) const { avcodec_free_context(&ptr); }
     54 };
     55 struct AVFrameDeleter {
     56  void operator()(AVFrame* ptr) const { av_frame_free(&ptr); }
     57 };
     58 
     59 class H264DecoderImpl : public H264Decoder {
     60 public:
     61  H264DecoderImpl();
     62  ~H264DecoderImpl() override;
     63 
     64  bool Configure(const Settings& settings) override;
     65  int32_t Release() override;
     66 
     67  int32_t RegisterDecodeCompleteCallback(
     68      DecodedImageCallback* callback) override;
     69 
     70  // `missing_frames`, `fragmentation` and `render_time_ms` are ignored.
     71  int32_t Decode(const EncodedImage& input_image,
     72                 bool /*missing_frames*/,
     73                 int64_t render_time_ms = -1) override;
     74 
     75  const char* ImplementationName() const override;
     76 
     77 private:
     78  // Called by FFmpeg when it needs a frame buffer to store decoded frames in.
     79  // The `VideoFrame` returned by FFmpeg at `Decode` originate from here. Their
     80  // buffers are reference counted and freed by FFmpeg using `AVFreeBuffer2`.
     81  static int AVGetBuffer2(AVCodecContext* context,
     82                          AVFrame* av_frame,
     83                          int flags);
     84  // Called by FFmpeg when it is done with a video frame, see `AVGetBuffer2`.
     85  static void AVFreeBuffer2(void* opaque, uint8_t* data);
     86 
     87  bool IsInitialized() const;
     88 
     89  // Reports statistics with histograms.
     90  void ReportInit();
     91  void ReportError();
     92 
     93  // Used by ffmpeg via `AVGetBuffer2()` to allocate I420 images.
     94  VideoFrameBufferPool ffmpeg_buffer_pool_;
     95  std::unique_ptr<AVCodecContext, AVCodecContextDeleter> av_context_;
     96  std::unique_ptr<AVFrame, AVFrameDeleter> av_frame_;
     97 
     98  DecodedImageCallback* decoded_image_callback_;
     99 
    100  bool has_reported_init_;
    101  bool has_reported_error_;
    102 
    103  H264BitstreamParser h264_bitstream_parser_;
    104 };
    105 
    106 }  // namespace webrtc
    107 
    108 #endif  // WEBRTC_USE_H264
    109 
    110 #endif  // MODULES_VIDEO_CODING_CODECS_H264_H264_DECODER_IMPL_H_