-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathwrappers.cpp
More file actions
138 lines (116 loc) · 3.17 KB
/
Copy pathwrappers.cpp
File metadata and controls
138 lines (116 loc) · 3.17 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "libspdl/core/detail/ffmpeg/wrappers.h"
#include "libspdl/core/detail/ffmpeg/logging.h"
#include "libspdl/core/detail/tracing.h"
namespace spdl::core::detail {
void AVIOContextDeleter::operator()(AVIOContext* p) {
TRACE_EVENT("decoding", "AVIOContext::~AVIOContext");
if (p) {
avio_flush(p);
av_freep(&p->buffer);
}
av_freep(&p);
}
void AVFormatInputContextDeleter::operator()(AVFormatContext* p) {
TRACE_EVENT("decoding", "avformat_close_input");
avformat_close_input(&p);
}
void AVFormatOutputContextDeleter::operator()(AVFormatContext* p) {
avformat_free_context(p);
}
void AVCodecContextDeleter::operator()(AVCodecContext* p) {
// Tracing because it takes as long as 300ms in case of cuvid decoder.
TRACE_EVENT("decoding", "avcodec_free_context");
avcodec_free_context(&p);
}
void AVBSFContextDeleter::operator()(AVBSFContext* p) {
av_bsf_free(&p);
}
void AVCodecParametersDeleter::operator()(AVCodecParameters* p) {
avcodec_parameters_free(&p);
}
void AVPacketDeleter::operator()(AVPacket* p) {
if (p) {
av_packet_unref(p);
av_packet_free(&p);
}
}
void AVFrameDeleter::operator()(AVFrame* p) {
if (p) {
av_frame_unref(p);
av_frame_free(&p);
}
}
void AVBufferRefDeleter::operator()(AVBufferRef* p) {
TRACE_EVENT("decoding", "av_buffer_unref");
av_buffer_unref(&p);
}
void AVFilterGraphDeleter::operator()(AVFilterGraph* p) {
avfilter_graph_free(&p);
}
AVFrameAutoUnref::AVFrameAutoUnref(AVFrame* p_) : p(p_) {}
AVFrameAutoUnref::~AVFrameAutoUnref() {
av_frame_unref(p);
}
AVFrame* make_reference(AVFrame* src) {
AVFrame* dst{CHECK_AVALLOCATE(av_frame_alloc())};
auto err = av_frame_ref(dst, src);
if (err < 0) {
av_frame_free(&dst);
}
CHECK_AVERROR(err, "Failed to create a new reference to an AVFrame.")
return dst;
}
OptionDict parse_dict(const AVDictionary* metadata) {
AVDictionaryEntry* tag = nullptr;
OptionDict ret;
while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
ret.emplace(std::string(tag->key), std::string(tag->value));
}
return ret;
}
} // namespace spdl::core::detail
#ifdef SPDL_DEBUG_REFCOUNT
#include <fmt/core.h>
#include <fmt/format.h>
#include <glog/logging.h>
extern "C" {
#include <stdatomic.h>
struct AVBuffer {
uint8_t* data;
size_t size;
atomic_uint refcount;
void (*free)(void* opaque, uint8_t* data);
void* opaque;
int flags;
int flags_internal;
};
}
namespace spdl::core::detail {
void debug_log_avframe_refcount(AVFrame* p) {
for (int i = 0; i < AV_NUM_DATA_POINTERS; ++i) {
if (!p->data[i]) {
break;
}
auto buf = p->buf[i]->buffer;
VLOG(5) << fmt::format(
"Refcount {}: {} ({} -> {})",
i,
buf->refcount,
(void*)(buf->data),
(void*)(p->data[i]));
}
}
void debug_log_avpacket_refcount(AVPacket* p) {
auto buf = p->buf->buffer;
LOG(INFO) << fmt::format(
"Refcount: {} ({})", buf->refcount, (void*)(buf->data));
}
} // namespace spdl::core::detail
#endif