FfmpegAudioStream.cpp 2.9 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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "FfmpegAudioStream.h"
#include "FfmpegUtil.h"

using namespace std;

namespace {

bool operator==(const AudioFormat& x, const AVCodecContext& y) {
  return x.samples == y.sample_rate && x.channels == y.channels &&
      x.format == y.sample_fmt;
}

AudioFormat& toAudioFormat(
    AudioFormat& audioFormat,
    const AVCodecContext& codecCtx) {
  audioFormat.samples = codecCtx.sample_rate;
  audioFormat.channels = codecCtx.channels;
  audioFormat.format = codecCtx.sample_fmt;

  return audioFormat;
}

} // namespace

FfmpegAudioStream::FfmpegAudioStream(
    AVFormatContext* inputCtx,
    int index,
    enum AVMediaType avMediaType,
    MediaFormat mediaFormat,
    double seekFrameMargin)
    : FfmpegStream(inputCtx, index, avMediaType, seekFrameMargin),
      mediaFormat_(mediaFormat) {}

FfmpegAudioStream::~FfmpegAudioStream() {}

void FfmpegAudioStream::checkStreamDecodeParams() {
  auto timeBase = getTimeBase();
  if (timeBase.first > 0) {
    CHECK_EQ(timeBase.first, inputCtx_->streams[index_]->time_base.num);
    CHECK_EQ(timeBase.second, inputCtx_->streams[index_]->time_base.den);
  }
}

void FfmpegAudioStream::updateStreamDecodeParams() {
  auto timeBase = getTimeBase();
  if (timeBase.first == 0) {
    mediaFormat_.format.audio.timeBaseNum =
        inputCtx_->streams[index_]->time_base.num;
    mediaFormat_.format.audio.timeBaseDen =
        inputCtx_->streams[index_]->time_base.den;
  }
}

int FfmpegAudioStream::initFormat() {
  AudioFormat& format = mediaFormat_.format.audio;

  if (format.samples == 0) {
    format.samples = codecCtx_->sample_rate;
  }
  if (format.channels == 0) {
    format.channels = codecCtx_->channels;
  }
  if (format.format == AV_SAMPLE_FMT_NONE) {
    format.format = codecCtx_->sample_fmt;
    VLOG(2) << "set stream format sample_fmt: " << format.format;
  }

  checkStreamDecodeParams();

  updateStreamDecodeParams();

  if (format.samples > 0 && format.channels > 0 &&
      format.format != AV_SAMPLE_FMT_NONE) {
    return 0;
  } else {
    return -1;
  }
}

unique_ptr<DecodedFrame> FfmpegAudioStream::sampleFrameData() {
  AudioFormat& audioFormat = mediaFormat_.format.audio;

  if (!sampler_ || !(sampler_->getInFormat() == *codecCtx_)) {
    AudioFormat newInFormat;
    newInFormat = toAudioFormat(newInFormat, *codecCtx_);
    sampler_ = make_unique<FfmpegAudioSampler>(newInFormat, audioFormat);
    VLOG(1) << "Set sampler input audio format"
            << ", samples: " << newInFormat.samples
            << ", channels: " << newInFormat.channels
            << ", format: " << newInFormat.format
            << " : output audio sampler format"
            << ", samples: " << audioFormat.samples
            << ", channels: " << audioFormat.channels
            << ", format: " << audioFormat.format;
    int ret = sampler_->init();
    if (ret < 0) {
      VLOG(1) << "Fail to initialize audio sampler";
      return nullptr;
    }
  }
  return sampler_->sample(frame_);
}