Skip to content

Commit aec768b

Browse files
committed
ver 2.05
1. fix a major bug causing memory leak. 2. update the ffmpeg to 4.0 version.
1 parent ef37179 commit aec768b

File tree

12 files changed

+73
-58
lines changed

12 files changed

+73
-58
lines changed

Diff for: MpegCoder/MpegBase.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#endif
1010

1111
#define FFMPG3_4
12+
#define FFMPG4_0
1213

1314
extern "C"
1415
{
@@ -26,7 +27,7 @@ extern "C"
2627
#include "libswresample/swresample.h"
2728
}
2829

29-
#define MPEGCODER_CURRENT_VERSION "2.0"
30+
#define MPEGCODER_CURRENT_VERSION "2.05"
3031

3132
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
3233

Diff for: MpegCoder/MpegCoder.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ PyObject *cmpc::CMpegDecoder::_SaveFrame_castToPyFrameArray(uint8_t *data[], int
495495
auto newdata = new uint8_t[fHeight*fWidth * 3];
496496
memcpy(newdata, data[0], fHeight*fWidth * 3);
497497
PyObject *PyFrame = PyArray_SimpleNewFromData(3, dims, NPY_UINT8, reinterpret_cast<void *>(newdata));
498+
PyArray_ENABLEFLAGS((PyArrayObject*)PyFrame, NPY_ARRAY_OWNDATA);
498499
return PyFrame;
499500
}
500501

Diff for: MpegCoder/MpegPyd.h

+5
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ Yuchen's Mpeg Coder - Readme
165165
>>> d.clear() # Disconnect with the stream.
166166
For more instructions, you could tap help(mpegCoder).
167167
================================================================================
168+
V2.05 update report:
169+
1. Fix a severe bug that causes the memory leak when using MpegClient.
170+
This bug also exists in MpegDecoder, but it seems that the bug would not cause
171+
memory leak in that case. (Although we have also fixed it now.)
172+
2. Upgrade to FFMpeg 4.0 Version.
168173
V2.01 update report:
169174
Fix a bug that occurs when the first received frame may has a PTS larger than
170175
zero.

Diff for: MpegCoder/MpegStreamer.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ bool cmpc::CMpegClient::FFmpegSetup() {
195195
#ifndef FFMPG3_4
196196
av_register_all();
197197
#endif
198-
avformat_network_init();
199-
198+
#ifndef FFMPG4_0
199+
avformat_network_init();
200+
#endif
200201
/* open RTSP: register all formats and codecs */
201202
if (avformat_open_input(&PFormatCtx, videoPath.c_str(), nullptr, nullptr) < 0) {
202203
cerr << "Could not open source address " << videoPath << endl;
@@ -794,7 +795,7 @@ PyObject * cmpc::Buffer_List::read() {
794795
if (_Buffer_rpos < 0) {
795796
return nullptr;
796797
}
797-
else if (PyArray_API == nullptr) {
798+
else if (PyArray_API == NULL) {
798799
import_array();
799800
}
800801
auto _Buffer_rend = (_Buffer_rpos + __Read_size) % _Buffer_size;
@@ -803,10 +804,12 @@ PyObject * cmpc::Buffer_List::read() {
803804
auto p = newdata;
804805
for (auto i = _Buffer_rpos; i != _Buffer_rend; i = (i + 1) % _Buffer_size) {
805806
memcpy(p, _Buffer_List[i], _Buffer_capacity * sizeof(uint8_t));
806-
p += _Buffer_capacity;
807+
p += _Buffer_capacity;
807808
}
808809
PyObject *PyFrame = PyArray_SimpleNewFromData(4, dims, NPY_UINT8, reinterpret_cast<void *>(newdata));
810+
PyArray_ENABLEFLAGS((PyArrayObject*)PyFrame, NPY_ARRAY_OWNDATA);
809811
_Buffer_rpos = -1;
810812
__Read_size = 0;
811-
return PyFrame;
813+
return PyArray_Return((PyArrayObject*)PyFrame);
814+
//Py_RETURN_NONE;
812815
}

Diff for: MpegCoder/ReadMe.txt

-27
This file was deleted.

Diff for: MpegCoder_LinuxVer/MpegCoder/MpegCoder.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,6 @@ bool cmpc::CMpegDecoder::FFmpegSetup() { //打开指定路径的视频文件,
200200
meta_protected_clear();
201201
int ret = 0;
202202

203-
// Register all formats and codecs.
204-
av_register_all();
205-
206203
/* register all formats and codecs */
207204
if (avformat_open_input(&PFormatCtx, videoPath.c_str(), nullptr, nullptr) < 0) {
208205
cerr << "Could not open source file " << videoPath << endl;
@@ -493,6 +490,7 @@ PyObject *cmpc::CMpegDecoder::_SaveFrame_castToPyFrameArray(uint8_t *data[], int
493490
auto newdata = new uint8_t[fHeight*fWidth * 3];
494491
memcpy(newdata, data[0], fHeight*fWidth * 3);
495492
PyObject *PyFrame = PyArray_SimpleNewFromData(3, dims, NPY_UINT8, reinterpret_cast<void *>(newdata));
493+
PyArray_ENABLEFLAGS((PyArrayObject*)PyFrame, NPY_ARRAY_OWNDATA);
496494
return PyFrame;
497495
}
498496

@@ -1376,9 +1374,6 @@ bool cmpc::CMpegEncoder::FFmpegSetup() {
13761374
AVCodec *video_codec = nullptr;
13771375
int ret;
13781376

1379-
/* Initialize libavcodec, and register all codecs and formats. */
1380-
av_register_all();
1381-
13821377
Ppacket = av_packet_alloc();
13831378
if (!Ppacket)
13841379
return false;

Diff for: MpegCoder_LinuxVer/MpegCoder/MpegPyd.h

+8
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,14 @@ Yuchen's Mpeg Coder - Readme
164164
>>> d.clear() # Disconnect with the stream.
165165
For more instructions, you could tap help(mpegCoder).
166166
================================================================================
167+
V2.05 update report:
168+
1. Fix a severe bug that causes the memory leak when using MpegClient.
169+
This bug also exists in MpegDecoder, but it seems that the bug would not cause
170+
memory leak in that case. (Although we have also fixed it now.)
171+
2. Upgrade to FFMpeg 4.0 Version.
172+
V2.01 update report:
173+
Fix a bug that occurs when the first received frame may has a PTS larger than
174+
zero.
167175
V2.0 update report:
168176
1. Revise the bug of the encoder which may cause the stream duration is shorter
169177
than the real duration of the video in some not advanced media players.

Diff for: MpegCoder_LinuxVer/MpegCoder/MpegStreamer.cpp

+19-11
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,6 @@ bool cmpc::CMpegClient::FFmpegSetup() {
191191
PFormatCtx = avformat_alloc_context();
192192
PCodecCtx = nullptr;
193193

194-
// Register everything
195-
av_register_all();
196-
avformat_network_init();
197-
198194
/* open RTSP: register all formats and codecs */
199195
if (avformat_open_input(&PFormatCtx, videoPath.c_str(), nullptr, nullptr) < 0) {
200196
cerr << "Could not open source address " << videoPath << endl;
@@ -764,10 +760,20 @@ void cmpc::Buffer_List::freezeWrite(int64_t read_size) {
764760
__Read_size = read_size;
765761
}
766762
bool cmpc::Buffer_List::write(SwsContext *PswsCtx, AVFrame *frame) {
767-
if (frame->pts < next_pts)
768-
return false;
769-
else
770-
next_pts += interval_pts;
763+
if (frame->pts < next_pts) {
764+
if (frame->pts > (next_pts - 2 * interval_pts)) {
765+
return false;
766+
}
767+
else {
768+
next_pts = frame->pts + interval_pts;
769+
}
770+
}
771+
else {
772+
if (next_pts > 0)
773+
next_pts += interval_pts;
774+
else
775+
next_pts = frame->pts;
776+
}
771777
if (_Buffer_pos == _Buffer_rpos) {
772778
return false;
773779
}
@@ -782,7 +788,7 @@ PyObject * cmpc::Buffer_List::read() {
782788
if (_Buffer_rpos < 0) {
783789
return nullptr;
784790
}
785-
else if (PyArray_API == nullptr) {
791+
else if (PyArray_API == NULL) {
786792
import_array();
787793
}
788794
auto _Buffer_rend = (_Buffer_rpos + __Read_size) % _Buffer_size;
@@ -791,10 +797,12 @@ PyObject * cmpc::Buffer_List::read() {
791797
auto p = newdata;
792798
for (auto i = _Buffer_rpos; i != _Buffer_rend; i = (i + 1) % _Buffer_size) {
793799
memcpy(p, _Buffer_List[i], _Buffer_capacity * sizeof(uint8_t));
794-
p += _Buffer_capacity;
800+
p += _Buffer_capacity;
795801
}
796802
PyObject *PyFrame = PyArray_SimpleNewFromData(4, dims, NPY_UINT8, reinterpret_cast<void *>(newdata));
803+
PyArray_ENABLEFLAGS((PyArrayObject*)PyFrame, NPY_ARRAY_OWNDATA);
797804
_Buffer_rpos = -1;
798805
__Read_size = 0;
799-
return PyFrame;
806+
return PyArray_Return((PyArrayObject*)PyFrame);
807+
//Py_RETURN_NONE;
800808
}

Diff for: MpegCoder_LinuxVer/MpegCoder/dllmain.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
*****************************************************************************/
77
PyMODINIT_FUNC // == __decslpec(dllexport) PyObject*, 定义导出函数.
88
PyInit_mpegCoder(void) { //模块外部名称为--CppClass
9-
PyObject* pReturn = 0;
9+
PyObject* pReturn = nullptr;
10+
cout << "create begin" << endl;
1011
C_MPDC_ClassInfo.tp_new = PyType_GenericNew; //此类的new内置函数—建立对象.
1112
C_MPEC_ClassInfo.tp_new = PyType_GenericNew;
1213
C_MPCT_ClassInfo.tp_new = PyType_GenericNew;
14+
cout << "create classinfo" << endl;
1315

1416
/// 完成对象类型的初始化—包括添加其继承特性等等。
1517
/// 如果成功,则返回0,否则返回-1并抛出异常.
@@ -19,15 +21,20 @@ PyInit_mpegCoder(void) { //模块外部名称为--CppClass
1921
return nullptr;
2022
if (PyType_Ready(&C_MPCT_ClassInfo) < 0)
2123
return nullptr;
24+
25+
cout << "check ready" << endl;
2226

2327
pReturn = PyModule_Create(&ModuleInfo); //根据模块信息创建模块,注意该步骤没有注册模块到计数器,所以需要调用Py_INCREF
2428
if (pReturn == 0)
2529
return nullptr;
30+
31+
cout << "create module" << endl;
2632

2733
Py_INCREF(&ModuleInfo);
2834
PyModule_AddFunctions(pReturn, C_MPC_MethodMembers); //将这个函数加入到模块的Dictionary中.
2935
PyModule_AddObject(pReturn, "MpegDecoder", (PyObject*)&C_MPDC_ClassInfo); //将这个类加入到模块的Dictionary中.
3036
PyModule_AddObject(pReturn, "MpegEncoder", (PyObject*)&C_MPEC_ClassInfo);
3137
PyModule_AddObject(pReturn, "MpegClient", (PyObject*)&C_MPCT_ClassInfo);
38+
cout << "add objects" << endl;
3239
return pReturn;
3340
}

Diff for: MpegCoder_LinuxVer/setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
('MINOR_VERSION', '0')],
1515
extra_compile_args = ['-std=c++11','-pthread'],
1616
include_dirs = [PYTHON_INC_DIR, np.get_include(), '{0}/include'.format(FFMPEG_DIR), BASE_SRC_DIR],
17-
#libraries = ['python3.5', 'avcodec', 'avdevice', 'avfilter', 'avformat', 'avutil', 'postproc', 'swresample', 'swscale', 'npymath'],
18-
libraries = ['python3.5', 'avcodec', 'avformat', 'avutil', 'swscale', 'npymath'],
17+
libraries = ['python3.5', 'avcodec', 'avdevice', 'avfilter', 'avformat', 'avutil', 'postproc', 'swresample', 'swscale', 'npymath'],
18+
#libraries = ['python3.5', 'avcodec', 'avformat', 'avutil', 'swscale', 'npymath'],
1919
library_dirs = [PYTHON_LIB_DIR, '{0}/lib'.format(NUMPY_DIR), '{0}/lib'.format(FFMPEG_DIR)],
2020
sources = ['{0}/MpegCoder.cpp'.format(BASE_SRC_DIR), '{0}/dllmain.cpp'.format(BASE_SRC_DIR)])
2121

Diff for: README.md

+11-5
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ For more instructions, you could tap `help(mpegCoder)`.
7070

7171
## Update Report
7272

73+
### V2.05 update report:
74+
75+
1. Fix a severe bug that causes the memory leak when using MpegClient.This bug also exists in MpegDecoder, but it seems that the bug would not cause memory leak in that case. (Although we have also fixed it now.)
76+
77+
2. Upgrade to FFMpeg 4.0 Version.
78+
7379
### V2.01 update report:
7480

7581
1. Fix a bug that occurs when the first received frame may has a PTS larger than zero.
@@ -156,11 +162,11 @@ If you want, you could install `ffmpeg` on Linux: Here are some instructions
156162
1. Provide the decoder which could decode videos in arbitrary formats and arbitrary coding.
157163

158164
## Version of currently used FFmpeg library
159-
* libavcodec.so.58.6.103
160-
* libavformat.so.58.3.100
161-
* libavutil.so.56.5.100
162-
* libswresample.so.3.0.101
163-
* libswscale.so.5.0.101
165+
* libavcodec.so.58.19.100
166+
* libavformat.so.58.13.100
167+
* libavutil.so.56.18.100
168+
* libswresample.so.3.2.100
169+
* libswscale.so.5.2.100
164170

165171
[exp1]:https://github.com/cainmagi/FFmpeg-Encoder-Decoder-for-Python/tree/example-client-check "check the client"
166172
[exp2]:https://github.com/cainmagi/FFmpeg-Encoder-Decoder-for-Python/tree/example-client-player "client with player"

Diff for: docs/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Getting your versions here! You could also visit the [release page](https://gith
2121

2222
| Version | Platform | Python Ver. | Numpy Ver. | FFmpeg Ver. |
2323
| ---------- | ----------- | ----------- | ----------- | ----------- |
24+
| [2.05][down201w] | Windows | 3.6 | 1.14 | 4.0 |
25+
| [2.05][down201w35] | Windows | 3.5 | 1.13 | 4.0 |
2426
| [2.01][down201w] | Windows | 3.6 | 1.14 | 3.4.2 |
2527
| [2.0][down20l] | Linux | 3.5 | 1.13 | 3.3 |
2628
| [2.0][down20w] | Windows | 3.5 | 1.13 | 3.3 |
@@ -90,6 +92,12 @@ For more instructions, you could tap `help(mpegCoder)`.
9092

9193
## Update Report
9294

95+
### V2.05 update report:
96+
97+
1. Fix a severe bug that causes the memory leak when using MpegClient.This bug also exists in MpegDecoder, but it seems that the bug would not cause memory leak in that case. (Although we have also fixed it now.)
98+
99+
2. Upgrade to FFMpeg 4.0 Version.
100+
93101
### V2.01 update report:
94102

95103
1. Fix a bug that occurs when the first received frame may has a PTS larger than zero.

0 commit comments

Comments
 (0)