Skip to content

Commit 4e7caee

Browse files
committed
[dev] add RAII support for AVCodec and AVCodecContext pointer
1 parent 19d298a commit 4e7caee

13 files changed

+436
-192
lines changed

src/ffmepg_transcode/ffmpeg_decode.cpp

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,54 +17,43 @@ extern "C" {
1717

1818
FFmpegDecode::FFmpegDecode(std::string decoder_name)
1919
: m_decoder_name(decoder_name)
20-
, m_decoder(nullptr)
21-
, m_decoder_context(nullptr)
20+
, m_codec_context(nullptr)
2221
{
2322
}
2423

2524

2625
FFmpegDecode::~FFmpegDecode()
2726
{
28-
if (m_decoder_context != nullptr) {
29-
avcodec_close(m_decoder_context);
30-
avcodec_free_context(&m_decoder_context);
31-
m_decoder_context = nullptr;
32-
}
33-
m_decoder = nullptr;
34-
m_decoder_name.clear();
27+
teardown();
3528
}
3629

3730

3831
bool FFmpegDecode::setup() {
39-
do {
40-
m_decoder = (AVCodec *)avcodec_find_decoder_by_name(m_decoder_name.c_str());
41-
if (nullptr == m_decoder) {
42-
SPDLOG_ERROR("avcodec_find_decoder_by_name error, m_decoder_name: {}", m_decoder_name);
43-
return false;
44-
}
32+
m_codec_context = new FFmpegCodecContext("", m_decoder_name);
33+
if (m_codec_context->is_null()) {
34+
return false;
35+
}
4536

46-
m_decoder_context = avcodec_alloc_context3(m_decoder);
47-
if (!m_decoder_context) {
48-
SPDLOG_ERROR("avcodec_alloc_context3 error, m_decoder_name: {}", m_decoder_name);
49-
return false;
50-
}
51-
52-
AVDictionary *options = nullptr;
53-
av_dict_set(&options, "threads", "1", 0);
54-
55-
int code = avcodec_open2(m_decoder_context, m_decoder, &options);
56-
if (code < 0) {
57-
SPDLOG_ERROR("avcodec_open2 error, code: {}, msg: {}, m_decoder_name: {}", code, ffmpeg_error_str(code), m_decoder_name);
58-
return false;
59-
}
60-
} while (false);
37+
if (!m_codec_context->open({ {"threads", "1"} })) {
38+
return false;
39+
}
6140

6241
return true;
6342
}
6443

6544

45+
void FFmpegDecode::teardown()
46+
{
47+
if (m_codec_context != nullptr) {
48+
delete m_codec_context;
49+
m_codec_context = nullptr;
50+
}
51+
m_decoder_name.clear();
52+
}
53+
54+
6655
bool FFmpegDecode::send_packet(FFmpegPacket &packet) {
67-
int code = avcodec_send_packet(m_decoder_context, packet.raw_ptr());
56+
int code = avcodec_send_packet(m_codec_context->raw_ptr(), packet.raw_ptr());
6857
if (code < 0) {
6958
SPDLOG_WARN("avcodec_send_packet error, code: {}, msg: {}", code, ffmpeg_error_str(code));
7059
return false;
@@ -84,7 +73,7 @@ FFmpegFrame FFmpegDecode::receive_frame() {
8473
break;
8574
}
8675

87-
code = avcodec_receive_frame(m_decoder_context, frame.raw_ptr());
76+
code = avcodec_receive_frame(m_codec_context->raw_ptr(), frame.raw_ptr());
8877
if (code == AVERROR(EAGAIN) || code == AVERROR_EOF) {
8978
break;
9079
}

src/ffmepg_transcode/ffmpeg_decode.hpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
// project
77
#include "ffmpeg_types.hpp"
88

9-
// ffmpeg
10-
struct AVCodec;
11-
struct AVCodecContext;
12-
139

1410

1511
class FFmpegDecode {
@@ -18,6 +14,7 @@ class FFmpegDecode {
1814
~FFmpegDecode();
1915

2016
bool setup();
17+
void teardown();
2118

2219
bool send_packet(FFmpegPacket &packet);
2320
FFmpegFrame receive_frame();
@@ -26,7 +23,6 @@ class FFmpegDecode {
2623
private:
2724
std::string m_decoder_name;
2825

29-
AVCodec *m_decoder;
30-
AVCodecContext *m_decoder_context;
26+
FFmpegCodecContext *m_codec_context;
3127
};
3228

src/ffmepg_transcode/ffmpeg_demux.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,7 @@ FFmpegDemux::FFmpegDemux(std::string input_url)
2727

2828
FFmpegDemux::~FFmpegDemux()
2929
{
30-
if (m_format_context != nullptr) {
31-
avformat_close_input(&m_format_context);
32-
m_format_context = nullptr;
33-
}
34-
m_video_stream_index = -1;
35-
m_video_stream = nullptr;
36-
m_input_url.clear();
30+
teardown();
3731
}
3832

3933

@@ -70,6 +64,18 @@ bool FFmpegDemux::setup() {
7064
}
7165

7266

67+
void FFmpegDemux::teardown()
68+
{
69+
if (m_format_context != nullptr) {
70+
avformat_close_input(&m_format_context);
71+
m_format_context = nullptr;
72+
}
73+
m_video_stream_index = -1;
74+
m_video_stream = nullptr;
75+
m_input_url.clear();
76+
}
77+
78+
7379
FFmpegPacket FFmpegDemux::read_frame() {
7480
FFmpegPacket packet;
7581
if (packet.is_null()) {

src/ffmepg_transcode/ffmpeg_demux.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class FFmpegDemux {
1818
~FFmpegDemux();
1919

2020
bool setup();
21+
void teardown();
2122

2223
FFmpegPacket read_frame();
2324

src/ffmepg_transcode/ffmpeg_encode.cpp

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,80 +22,69 @@ FFmpegEncode::FFmpegEncode(std::string encoder_name, int width, int height, int6
2222
, m_height(height)
2323
, m_bitrate(bitrate)
2424
, m_pixel_format(pixel_format)
25-
, m_encoder(nullptr)
26-
, m_encoder_context(nullptr)
25+
, m_codec_context(nullptr)
2726
{
28-
2927
}
3028

3129

3230
FFmpegEncode::~FFmpegEncode()
3331
{
34-
if (m_encoder_context != nullptr) {
35-
avcodec_close(m_encoder_context);
36-
avcodec_free_context(&m_encoder_context);
37-
m_encoder_context = nullptr;
38-
}
39-
m_encoder = nullptr;
40-
m_pixel_format = AV_PIX_FMT_NONE;
41-
m_encoder_name.clear();
32+
teardown();
4233
}
4334

4435

4536
bool FFmpegEncode::setup() {
46-
do {
47-
m_encoder = (AVCodec *)avcodec_find_encoder_by_name(m_encoder_name.c_str());
48-
if (nullptr == m_encoder) {
49-
SPDLOG_ERROR("avcodec_find_encoder_by_name error, m_encoder_name: {}", m_encoder_name);
50-
return false;
51-
}
52-
53-
m_encoder_context = avcodec_alloc_context3(m_encoder);
54-
if (!m_encoder_context) {
55-
SPDLOG_ERROR("avcodec_alloc_context3 error, m_encoder_name: {}", m_encoder_name);
56-
return false;
57-
}
37+
m_codec_context = new FFmpegCodecContext(m_encoder_name, "");
38+
if (m_codec_context->is_null()) {
39+
return false;
40+
}
5841

59-
m_encoder_context->pix_fmt = (enum AVPixelFormat)m_pixel_format;
60-
m_encoder_context->width = m_width;
61-
m_encoder_context->height = m_height;
62-
m_encoder_context->time_base = { 1, 25 };
63-
m_encoder_context->framerate = { 1, 25 };
64-
m_encoder_context->bit_rate = m_bitrate;
65-
m_encoder_context->bit_rate_tolerance = (int)(m_bitrate / 4);
66-
m_encoder_context->gop_size = 50;
67-
m_encoder_context->max_b_frames = 0;
68-
69-
int code = 0;
70-
code = av_opt_set(m_encoder_context->priv_data, "preset", "ultrafast", 0);
71-
if (code < 0) {
72-
SPDLOG_ERROR("av_opt_set(preset, ultrafast) error, code: {}, msg: {}, m_encoder_name: {}", code, ffmpeg_error_str(code), m_encoder_name);
73-
}
74-
code = av_opt_set(m_encoder_context->priv_data, "tune", "zerolatency", 0);
75-
if (code < 0) {
76-
SPDLOG_ERROR("av_opt_set(tune, zerolatency) error, code: {}, msg: {}, m_encoder_name: {}", code, ffmpeg_error_str(code), m_encoder_name);
77-
}
42+
m_codec_context->raw_ptr()->pix_fmt = (enum AVPixelFormat)m_pixel_format;
43+
m_codec_context->raw_ptr()->width = m_width;
44+
m_codec_context->raw_ptr()->height = m_height;
45+
m_codec_context->raw_ptr()->time_base = { 1, 25 };
46+
m_codec_context->raw_ptr()->framerate = { 1, 25 };
47+
m_codec_context->raw_ptr()->bit_rate = m_bitrate;
48+
m_codec_context->raw_ptr()->bit_rate_tolerance = (int)(m_bitrate / 4);
49+
m_codec_context->raw_ptr()->gop_size = 50;
50+
m_codec_context->raw_ptr()->max_b_frames = 0;
7851

79-
AVDictionary *options = nullptr;
80-
av_dict_set(&options, "threads", "1", 0);
52+
int code = 0;
53+
code = av_opt_set(m_codec_context->raw_ptr()->priv_data, "preset", "ultrafast", 0);
54+
if (code < 0) {
55+
SPDLOG_ERROR("av_opt_set(preset, ultrafast) error, code: {}, msg: {}, m_encoder_name: {}", code, ffmpeg_error_str(code), m_encoder_name);
56+
}
57+
code = av_opt_set(m_codec_context->raw_ptr()->priv_data, "tune", "zerolatency", 0);
58+
if (code < 0) {
59+
SPDLOG_ERROR("av_opt_set(tune, zerolatency) error, code: {}, msg: {}, m_encoder_name: {}", code, ffmpeg_error_str(code), m_encoder_name);
60+
}
8161

82-
if (m_encoder_name == "libx265") {
83-
av_opt_set(m_encoder_context->priv_data, "x265-params", "threads=1", 0);
84-
}
62+
if (m_encoder_name == "libx265") {
63+
av_opt_set(m_codec_context->raw_ptr()->priv_data, "x265-params", "threads=1", 0);
64+
}
8565

86-
code = avcodec_open2(m_encoder_context, m_encoder, &options);
87-
if (code < 0) {
88-
SPDLOG_ERROR("avcodec_open2 error, code: {}, msg: {}, m_encoder_name: {}", code, ffmpeg_error_str(code), m_encoder_name);
89-
return false;
90-
}
91-
} while (false);
66+
if (!m_codec_context->open({ {"threads", "1"} })) {
67+
return false;
68+
}
9269

9370
return true;
9471
}
9572

9673

74+
void FFmpegEncode::teardown()
75+
{
76+
if (m_codec_context != nullptr) {
77+
delete m_codec_context;
78+
m_codec_context = nullptr;
79+
}
80+
81+
m_pixel_format = AV_PIX_FMT_NONE;
82+
m_encoder_name.clear();
83+
}
84+
85+
9786
bool FFmpegEncode::send_frame(FFmpegFrame &frame) {
98-
int code = avcodec_send_frame(m_encoder_context, frame.raw_ptr());
87+
int code = avcodec_send_frame(m_codec_context->raw_ptr(), frame.raw_ptr());
9988
if (code < 0) {
10089
SPDLOG_WARN("avcodec_send_frame error, code: {}, msg: {}", code, ffmpeg_error_str(code));
10190
return false;
@@ -114,7 +103,7 @@ FFmpegPacket FFmpegEncode::receive_packet() {
114103
break;
115104
}
116105

117-
code = avcodec_receive_packet(m_encoder_context, packet.raw_ptr());
106+
code = avcodec_receive_packet(m_codec_context->raw_ptr(), packet.raw_ptr());
118107
if (code == AVERROR(EAGAIN) || code == AVERROR_EOF) {
119108
break;
120109
}

src/ffmepg_transcode/ffmpeg_encode.hpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,17 @@
99
// project
1010
#include "ffmpeg_types.hpp"
1111

12-
// ffmpeg
13-
struct AVCodec;
14-
struct AVCodecContext;
15-
1612

1713

1814
class FFmpegEncode {
1915
public:
2016
FFmpegEncode(std::string encoder_name, int width, int height, int64_t bitrate, int pixel_format);
21-
2217
~FFmpegEncode();
2318

2419
bool setup();
20+
void teardown();
2521

2622
bool send_frame(FFmpegFrame &frame);
27-
2823
FFmpegPacket receive_packet();
2924

3025

@@ -37,7 +32,6 @@ class FFmpegEncode {
3732

3833
int m_pixel_format;
3934

40-
AVCodec *m_encoder;
41-
AVCodecContext *m_encoder_context;
35+
FFmpegCodecContext *m_codec_context;
4236
};
4337

src/ffmepg_transcode/ffmpeg_scale.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ FFmpegScale::FFmpegScale(int src_width, int src_height, int src_pixel_format, in
2929

3030
FFmpegScale::~FFmpegScale()
3131
{
32-
if (m_SwsContext != nullptr) {
33-
sws_freeContext(m_SwsContext);
34-
m_SwsContext = nullptr;
35-
}
32+
teardown();
3633
}
3734

3835

@@ -51,6 +48,15 @@ bool FFmpegScale::setup() {
5148
}
5249

5350

51+
void FFmpegScale::teardown()
52+
{
53+
if (m_SwsContext != nullptr) {
54+
sws_freeContext(m_SwsContext);
55+
m_SwsContext = nullptr;
56+
}
57+
}
58+
59+
5460
FFmpegFrame FFmpegScale::scale(FFmpegFrame &frame) {
5561
do {
5662
FFmpegFrame scaled_frame;

src/ffmepg_transcode/ffmpeg_scale.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class FFmpegScale {
1414
~FFmpegScale();
1515

1616
bool setup();
17+
void teardown();
1718

1819
FFmpegFrame scale(FFmpegFrame &frame);
1920

0 commit comments

Comments
 (0)