ffmpeg.cpp 4.89 KB
Newer Older
1
#include <c10/util/Exception.h>
2
#include <libtorio/ffmpeg/ffmpeg.h>
3
#include <sstream>
moto's avatar
moto committed
4
#include <stdexcept>
5
6
#include <string>
#include <vector>
7

8
9
namespace torchaudio::io {

10
////////////////////////////////////////////////////////////////////////////////
moto's avatar
moto committed
11
// AVDictionary
12
////////////////////////////////////////////////////////////////////////////////
13
AVDictionary* get_option_dict(const c10::optional<OptionDict>& option) {
14
  AVDictionary* opt = nullptr;
15
  if (option) {
16
    for (auto const& [key, value] : option.value()) {
17
      av_dict_set(&opt, key.c_str(), value.c_str(), 0);
18
    }
19
20
21
22
  }
  return opt;
}

moto's avatar
moto committed
23
void clean_up_dict(AVDictionary* p) {
24
25
26
27
  if (p) {
    std::vector<std::string> unused_keys;
    // Check and copy unused keys, clean up the original dictionary
    AVDictionaryEntry* t = nullptr;
28
    while ((t = av_dict_get(p, "", t, AV_DICT_IGNORE_SUFFIX))) {
29
30
      unused_keys.emplace_back(t->key);
    }
31
    av_dict_free(&p);
32
33
34
35
    TORCH_CHECK(
        unused_keys.empty(),
        "Unexpected options: ",
        c10::Join(", ", unused_keys));
36
37
38
  }
}

moto's avatar
moto committed
39
40
41
////////////////////////////////////////////////////////////////////////////////
// AVFormatContext
////////////////////////////////////////////////////////////////////////////////
42
void AVFormatInputContextDeleter::operator()(AVFormatContext* p) {
43
  avformat_close_input(&p);
moto's avatar
moto committed
44
45
};

46
47
AVFormatInputContextPtr::AVFormatInputContextPtr(AVFormatContext* p)
    : Wrapper<AVFormatContext, AVFormatInputContextDeleter>(p) {}
48

moto's avatar
moto committed
49
void AVFormatOutputContextDeleter::operator()(AVFormatContext* p) {
50
  avformat_free_context(p);
moto's avatar
moto committed
51
52
53
54
55
};

AVFormatOutputContextPtr::AVFormatOutputContextPtr(AVFormatContext* p)
    : Wrapper<AVFormatContext, AVFormatOutputContextDeleter>(p) {}

56
57
58
59
////////////////////////////////////////////////////////////////////////////////
// AVIO
////////////////////////////////////////////////////////////////////////////////
void AVIOContextDeleter::operator()(AVIOContext* p) {
60
61
62
  avio_flush(p);
  av_freep(&p->buffer);
  av_freep(&p);
63
64
65
66
67
};

AVIOContextPtr::AVIOContextPtr(AVIOContext* p)
    : Wrapper<AVIOContext, AVIOContextDeleter>(p) {}

68
69
70
71
////////////////////////////////////////////////////////////////////////////////
// AVPacket
////////////////////////////////////////////////////////////////////////////////
void AVPacketDeleter::operator()(AVPacket* p) {
72
  av_packet_free(&p);
73
74
};

75
AVPacketPtr::AVPacketPtr(AVPacket* p) : Wrapper<AVPacket, AVPacketDeleter>(p) {}
76

77
AVPacketPtr alloc_avpacket() {
78
  AVPacket* p = av_packet_alloc();
79
80
81
  TORCH_CHECK(p, "Failed to allocate AVPacket object.");
  return AVPacketPtr{p};
}
82
83
84
85
86
87

////////////////////////////////////////////////////////////////////////////////
// AVPacket - buffer unref
////////////////////////////////////////////////////////////////////////////////
AutoPacketUnref::AutoPacketUnref(AVPacketPtr& p) : p_(p){};
AutoPacketUnref::~AutoPacketUnref() {
88
  av_packet_unref(p_);
89
90
91
92
93
94
95
96
97
}
AutoPacketUnref::operator AVPacket*() const {
  return p_;
}

////////////////////////////////////////////////////////////////////////////////
// AVFrame
////////////////////////////////////////////////////////////////////////////////
void AVFrameDeleter::operator()(AVFrame* p) {
98
  av_frame_free(&p);
99
100
};

101
102
103
AVFramePtr::AVFramePtr(AVFrame* p) : Wrapper<AVFrame, AVFrameDeleter>(p) {}

AVFramePtr alloc_avframe() {
104
  AVFrame* p = av_frame_alloc();
105
106
107
  TORCH_CHECK(p, "Failed to allocate AVFrame object.");
  return AVFramePtr{p};
};
108
109
110
111
112

////////////////////////////////////////////////////////////////////////////////
// AVCodecContext
////////////////////////////////////////////////////////////////////////////////
void AVCodecContextDeleter::operator()(AVCodecContext* p) {
113
  avcodec_free_context(&p);
114
115
};

116
117
AVCodecContextPtr::AVCodecContextPtr(AVCodecContext* p)
    : Wrapper<AVCodecContext, AVCodecContextDeleter>(p) {}
118
119
120
121
122

////////////////////////////////////////////////////////////////////////////////
// AVBufferRefPtr
////////////////////////////////////////////////////////////////////////////////
void AutoBufferUnref::operator()(AVBufferRef* p) {
123
  av_buffer_unref(&p);
124
125
}

moto's avatar
moto committed
126
127
AVBufferRefPtr::AVBufferRefPtr(AVBufferRef* p)
    : Wrapper<AVBufferRef, AutoBufferUnref>(p) {}
128

129
130
131
132
////////////////////////////////////////////////////////////////////////////////
// AVFilterGraph
////////////////////////////////////////////////////////////////////////////////
void AVFilterGraphDeleter::operator()(AVFilterGraph* p) {
133
  avfilter_graph_free(&p);
134
135
};

136
137
AVFilterGraphPtr::AVFilterGraphPtr(AVFilterGraph* p)
    : Wrapper<AVFilterGraph, AVFilterGraphDeleter>(p) {}
138
139
140
141
142

////////////////////////////////////////////////////////////////////////////////
// AVCodecParameters
////////////////////////////////////////////////////////////////////////////////
void AVCodecParametersDeleter::operator()(AVCodecParameters* codecpar) {
143
  avcodec_parameters_free(&codecpar);
144
145
}

146
147
AVCodecParametersPtr::AVCodecParametersPtr(AVCodecParameters* p)
    : Wrapper<AVCodecParameters, AVCodecParametersDeleter>(p) {}
148

149
} // namespace torchaudio::io