mockEncoder.hpp 1.73 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm

#pragma once

#include "videoEncoder.hpp"

#include <memory>

#define BUFFER_SIZE 32768
#define GOT_A_NAL_CROSS_BUFFER BUFFER_SIZE + 1
#define GOT_A_NAL_INCLUDE_A_BUFFER BUFFER_SIZE + 2
#define NO_MORE_BUFFER_TO_READ BUFFER_SIZE + 3

namespace VideoStitch {
namespace Output {

struct NaluUnit {
  int type;
  int size;
  unsigned char *data;
};

/**
 * The MockEncoder takes an Annex-B H264 bytesteam, and at each call to encode(),
 * provides the Publisher with the next encoded frame in the bytestream.
 *
 * You can generate an Annex-B bytestream from an MP4 container by extracting the
 * h.264 NAL units from it with FFMpeg:
 * > ffmpeg -i my_movie.mp4 -vcodec copy -vbsf h264_mp4toannexb -an of.h264
 *
 */

class MockEncoder : public VideoEncoder {
 public:
  MockEncoder();
  ~MockEncoder();

  static Potential<VideoEncoder> createMockEncoder();

  bool encode(const Frame &, std::vector<VideoStitch::IO::DataPacket> &packets);
  void getHeaders(VideoStitch::IO::DataPacket &packet);

  char *metadata(char *enc, char *) { return enc; }
  int getBitRate() const { return 1000; }
  bool dynamicBitrateSupported() const { return false; }
  bool setBitRate(uint32_t /*maxBitrate*/, uint32_t /*bufferSize*/) { return false; }

 private:
  static int read_buffer(uint8_t *buf, int buf_size);

  int readFirstNaluFromBuf(NaluUnit &nalu);
  int readOneNaluFromBuf(NaluUnit &nalu, int (*read_buffer)(uint8_t *buf, int buf_size));

  unsigned int nalhead_pos;
  unsigned char *m_pFileBuf;
  unsigned int m_nFileBufSize;
  unsigned char *m_pFileBuf_tmp;
  unsigned char *m_pFileBuf_tmp_old;  // used for realloc

  static FILE *fp_send;
};

}  // namespace Output
}  // namespace VideoStitch