diff --git a/CHANGELOG.md b/CHANGELOG.md index ebcacbb..9c722a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Update Report +### V3.2.0 update report: + +1. Upgrade to `FFMpeg 5.0` Version. + +2. Fix the const assignment bug caused by the codec configuration method. + ### V3.1.0 update report: 1. Support `str()` type for all string arguments. diff --git a/MpegCoder/MpegBase.h b/MpegCoder/MpegBase.h index 70e82ef..74e43bc 100644 --- a/MpegCoder/MpegBase.h +++ b/MpegCoder/MpegBase.h @@ -11,8 +11,9 @@ #define FFMPG3_4 #define FFMPG4_0 #define FFMPG4_4 +#define FFMPG5_0 -#define MPEGCODER_CURRENT_VERSION "3.1.0" +#define MPEGCODER_CURRENT_VERSION "3.2.0" #define STREAM_PIX_FMT AVPixelFormat::AV_PIX_FMT_YUV420P /* default pix_fmt */ diff --git a/MpegCoder/MpegCoder.cpp b/MpegCoder/MpegCoder.cpp index bf9b94e..4f9abf6 100644 --- a/MpegCoder/MpegCoder.cpp +++ b/MpegCoder/MpegCoder.cpp @@ -1092,43 +1092,45 @@ int cmpc::CMpegEncoder::__write_frame() { } /* Add an output stream. */ -bool cmpc::CMpegEncoder::__add_stream(AVCodec** codec) { +const cmpc::AVCodec* cmpc::CMpegEncoder::__add_stream() { /* find the encoder */ AVCodecID codec_id; auto srcwidth = widthSrc > 0 ? widthSrc : width; auto srcheight = heightSrc > 0 ? heightSrc : height; - *codec = avcodec_find_encoder_by_name(codecName.c_str()); - if (!(*codec)) { + auto const_codec = avcodec_find_encoder_by_name(codecName.c_str()); + const AVCodec* codec; + if (!(const_codec)) { codec_id = PFormatCtx->oformat->video_codec; cerr << "Could not find encoder " << codecName << ", use " << avcodec_get_name(codec_id) << " as an alternative." << endl; - *codec = avcodec_find_encoder(codec_id); + codec = avcodec_find_encoder(codec_id); } else { - codec_id = (*codec)->id; - PFormatCtx->oformat->video_codec = codec_id; + codec = const_codec; + codec_id = codec->id; } - if (!(*codec)) { + + if (!codec) { cerr << "Could not find encoder for '" << avcodec_get_name(codec_id) << "'" << endl; - return false; + return nullptr; } PStreamContex.st = avformat_new_stream(PFormatCtx, nullptr); if (!PStreamContex.st) { cerr << "Could not allocate stream" << endl; - return false; + return nullptr; } PStreamContex.st->id = PFormatCtx->nb_streams - 1; - auto c = avcodec_alloc_context3(*codec); + auto c = avcodec_alloc_context3(codec); if (!c) { cerr << "Could not alloc an encoding context" << endl; - return false; + return nullptr; } if (nthread > 0) { c->thread_count = nthread; } PStreamContex.enc = c; - switch ((*codec)->type) { + switch (codec->type) { case AVMediaType::AVMEDIA_TYPE_VIDEO: c->codec_id = codec_id; @@ -1178,7 +1180,7 @@ bool cmpc::CMpegEncoder::__add_stream(AVCodec** codec) { SCALE_FLAGS, nullptr, nullptr, nullptr); if (!PStreamContex.sws_ctx) { cerr << "Could not initialize the conversion context" << endl; - return false; + return nullptr; } } } @@ -1190,7 +1192,7 @@ bool cmpc::CMpegEncoder::__add_stream(AVCodec** codec) { SCALE_FLAGS, nullptr, nullptr, nullptr); if (!PswsCtx) { cerr << "Could not initialize the conversion context" << endl; - return false; + return nullptr; } } if (!RGBbuffer) { @@ -1206,7 +1208,7 @@ bool cmpc::CMpegEncoder::__add_stream(AVCodec** codec) { /* Some formats want stream headers to be separate. */ if (PFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - return true; + return codec; } /* video output */ @@ -1226,7 +1228,7 @@ cmpc::AVFrame* cmpc::CMpegEncoder::__alloc_picture(enum AVPixelFormat pix_fmt, i return picture; } -bool cmpc::CMpegEncoder::__open_video(AVCodec* codec, AVDictionary* opt_arg) { +bool cmpc::CMpegEncoder::__open_video(const AVCodec* codec, const AVDictionary* opt_arg) { int ret; auto c = PStreamContex.enc; AVDictionary* opt = nullptr; @@ -1809,7 +1811,7 @@ PyObject* cmpc::CMpegEncoder::getParameter() { } bool cmpc::CMpegEncoder::FFmpegSetup() { - AVCodec* video_codec = nullptr; + const AVCodec* video_codec; int ret; if (Ppacket) @@ -1839,13 +1841,17 @@ bool cmpc::CMpegEncoder::FFmpegSetup() { /* Add the audio and video streams using the default format codecs * and initialize the codecs. */ if (fmt->video_codec != AVCodecID::AV_CODEC_ID_NONE) { - if (!__add_stream(&video_codec)) { + video_codec = __add_stream(); + if (!video_codec) { FFmpegClose(); return false; } else __have_video = true; } + else { + video_codec = nullptr; + } /* Now that all the parameters are set, we can open the audio and * video codecs and allocate the necessary encode buffers. */ diff --git a/MpegCoder/MpegCoder.h b/MpegCoder/MpegCoder.h index 7e92a6e..2ddf98b 100644 --- a/MpegCoder/MpegCoder.h +++ b/MpegCoder/MpegCoder.h @@ -122,9 +122,9 @@ namespace cmpc { bool _LoadFrame_castFromPyFrameArray(AVFrame* frame, PyArrayObject* PyFrame); void __log_packet(); int __write_frame(); - bool __add_stream(AVCodec** codec); + const AVCodec* __add_stream(); AVFrame* __alloc_picture(enum AVPixelFormat pix_fmt, int width, int height); - bool __open_video(AVCodec* codec, AVDictionary* opt_arg); + bool __open_video(const AVCodec* codec, const AVDictionary* opt_arg); AVFrame* __get_video_frame(PyArrayObject* PyFrame); int __avcodec_encode_video2(AVCodecContext* enc_ctx, AVPacket* pkt, AVFrame* frame); int __avcodec_encode_video2_flush(AVCodecContext* enc_ctx, AVPacket* pkt); diff --git a/MpegCoder/MpegCoder.vcxproj b/MpegCoder/MpegCoder.vcxproj index 1e7d04e..8aeef01 100644 --- a/MpegCoder/MpegCoder.vcxproj +++ b/MpegCoder/MpegCoder.vcxproj @@ -29,26 +29,26 @@ DynamicLibrary true - v142 + v143 Unicode DynamicLibrary false - v142 + v143 true Unicode DynamicLibrary true - v142 + v143 Unicode DynamicLibrary false - v142 + v143 true Unicode @@ -77,8 +77,8 @@ true - C:\Users\yjin4\.conda\envs\py39\include;C:\Users\yjin4\.conda\envs\py39\lib\site-packages\numpy\core\include;..\include;$(IncludePath) - C:\Users\yjin4\.conda\envs\py39\libs;C:\Users\yjin4\.conda\envs\py39\lib\site-packages\numpy\core\lib;..\lib;$(LibraryPath) + C:\Users\cainm\.conda\envs\py310\include;C:\Users\cainm\.conda\envs\py310\lib\site-packages\numpy\core\include;..\include;$(IncludePath) + C:\Users\cainm\.conda\envs\py310\libs;C:\Users\cainm\.conda\envs\py310\lib\site-packages\numpy\core\lib;..\lib;$(LibraryPath) false @@ -87,8 +87,8 @@ false - C:\Users\yjin4\.conda\envs\py39\include;C:\Users\yjin4\.conda\envs\py39\lib\site-packages\numpy\core\include;..\include;$(IncludePath) - C:\Users\yjin4\.conda\envs\py39\libs;C:\Users\yjin4\.conda\envs\py39\lib\site-packages\numpy\core\lib;..\lib;$(LibraryPath) + C:\Users\cainm\.conda\envs\py310\include;C:\Users\cainm\.conda\envs\py310\lib\site-packages\numpy\core\include;..\include;$(IncludePath) + C:\Users\cainm\.conda\envs\py310\libs;C:\Users\cainm\.conda\envs\py310\lib\site-packages\numpy\core\lib;..\lib;$(LibraryPath) @@ -111,11 +111,12 @@ Disabled _DEBUG;MpegCoder_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true + true Windows true - avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;python39.lib;python3.lib;npymath.lib;%(AdditionalDependencies) + python310.lib;python3.lib;npymath.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) echo F | xcopy /y /i "$(OutDir)$(TargetName)$(TargetExt)" "$(OutDir)mpegCoder.pyd" @@ -148,13 +149,14 @@ true NDEBUG;MpegCoder_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true + true Windows true true true - avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;python39.lib;python3.lib;npymath.lib;%(AdditionalDependencies) + python310.lib;python3.lib;npymath.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) echo F | xcopy /y /i "$(OutDir)$(TargetName)$(TargetExt)" "$(OutDir)mpegCoder.pyd" diff --git a/MpegCoder/MpegPyd.h b/MpegCoder/MpegPyd.h index f869177..4aaa373 100644 --- a/MpegCoder/MpegPyd.h +++ b/MpegCoder/MpegPyd.h @@ -213,6 +213,9 @@ Yuchen's Mpeg Coder - Readme >>> d.clear() # Disconnect with the stream. For more instructions, you could tap help(mpegCoder). ================================================================================ +V3.2.0 update report: + 1. Upgrade FFMpeg to 5.0. + 2. Fix the const assignment bug caused by the codec configuration method. V3.1.0 update report: 1. Support str() type for all string arguments. 2. Support http, ftp, sftp streams for MpegServer. diff --git a/MpegCoder/MpegStreamer.cpp b/MpegCoder/MpegStreamer.cpp index 89d5599..5be484e 100644 --- a/MpegCoder/MpegStreamer.cpp +++ b/MpegCoder/MpegStreamer.cpp @@ -1202,43 +1202,45 @@ int cmpc::CMpegServer::__write_frame() { } /* Add an output stream. */ -bool cmpc::CMpegServer::__add_stream(AVCodec** codec) { +const cmpc::AVCodec* cmpc::CMpegServer::__add_stream() { /* find the encoder */ AVCodecID codec_id; auto srcwidth = widthSrc > 0 ? widthSrc : width; auto srcheight = heightSrc > 0 ? heightSrc : height; - *codec = avcodec_find_encoder_by_name(codecName.c_str()); - if (!(*codec)) { + auto const_codec = avcodec_find_encoder_by_name(codecName.c_str()); + const AVCodec* codec; + if (!(const_codec)) { codec_id = PFormatCtx->oformat->video_codec; cerr << "Could not find encoder " << codecName << ", use " << avcodec_get_name(codec_id) << " as an alternative." << endl; - *codec = avcodec_find_encoder(codec_id); + codec = avcodec_find_encoder(codec_id); } else { - codec_id = (*codec)->id; - PFormatCtx->oformat->video_codec = codec_id; + codec = const_codec; + codec_id = codec->id; } - if (!(*codec)) { + + if (!codec) { cerr << "Could not find encoder for '" << avcodec_get_name(codec_id) << "'" << endl; - return false; + return nullptr; } PStreamContex.st = avformat_new_stream(PFormatCtx, nullptr); if (!PStreamContex.st) { cerr << "Could not allocate stream" << endl; - return false; + return nullptr; } PStreamContex.st->id = PFormatCtx->nb_streams - 1; - auto c = avcodec_alloc_context3(*codec); + auto c = avcodec_alloc_context3(codec); if (!c) { cerr << "Could not alloc an encoding context" << endl; - return false; + return nullptr; } if (nthread > 0) { c->thread_count = nthread; } PStreamContex.enc = c; - switch ((*codec)->type) { + switch (codec->type) { case AVMediaType::AVMEDIA_TYPE_VIDEO: c->codec_id = codec_id; @@ -1288,7 +1290,7 @@ bool cmpc::CMpegServer::__add_stream(AVCodec** codec) { SCALE_FLAGS, nullptr, nullptr, nullptr); if (!PStreamContex.sws_ctx) { cerr << "Could not initialize the conversion context" << endl; - return false; + return nullptr; } } } @@ -1300,7 +1302,7 @@ bool cmpc::CMpegServer::__add_stream(AVCodec** codec) { SCALE_FLAGS, nullptr, nullptr, nullptr); if (!PswsCtx) { cerr << "Could not initialize the conversion context" << endl; - return false; + return nullptr; } } if (!RGBbuffer) { @@ -1316,7 +1318,7 @@ bool cmpc::CMpegServer::__add_stream(AVCodec** codec) { /* Some formats want stream headers to be separate. */ if (PFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - return true; + return codec; } /* video output */ @@ -1336,7 +1338,7 @@ cmpc::AVFrame* cmpc::CMpegServer::__alloc_picture(enum AVPixelFormat pix_fmt, in return picture; } -bool cmpc::CMpegServer::__open_video(AVCodec* codec, AVDictionary* opt_arg) { +bool cmpc::CMpegServer::__open_video(const AVCodec* codec, const AVDictionary* opt_arg) { int ret; auto c = PStreamContex.enc; AVDictionary* opt = nullptr; @@ -1988,7 +1990,7 @@ bool cmpc::CMpegServer::FFmpegSetup() { cerr << "Have not get necessary and correct configurations, so FFmpegSetup() should not be called." << endl; return false; } - AVCodec* video_codec = nullptr; + const AVCodec* video_codec; int ret; if (Ppacket) @@ -2035,13 +2037,17 @@ bool cmpc::CMpegServer::FFmpegSetup() { /* Add the audio and video streams using the default format codecs * and initialize the codecs. */ if (fmt->video_codec != AVCodecID::AV_CODEC_ID_NONE) { - if (!__add_stream(&video_codec)) { + video_codec = __add_stream(); + if (!video_codec) { FFmpegClose(); return false; } else __have_video = true; } + else { + video_codec = nullptr; + } /* Now that all the parameters are set, we can open the audio and * video codecs and allocate the necessary encode buffers. */ diff --git a/MpegCoder/MpegStreamer.h b/MpegCoder/MpegStreamer.h index 06ca04c..f809171 100644 --- a/MpegCoder/MpegStreamer.h +++ b/MpegCoder/MpegStreamer.h @@ -163,9 +163,9 @@ namespace cmpc { bool _LoadFrame_castFromPyFrameArray(AVFrame* frame, PyArrayObject* PyFrame); void __log_packet(); int __write_frame(); - bool __add_stream(AVCodec** codec); + const AVCodec* __add_stream(); AVFrame* __alloc_picture(enum AVPixelFormat pix_fmt, int width, int height); - bool __open_video(AVCodec* codec, AVDictionary* opt_arg); + bool __open_video(const AVCodec* codec, const AVDictionary* opt_arg); AVFrame* __get_video_frame(PyArrayObject* PyFrame); int __avcodec_encode_video2(AVCodecContext* enc_ctx, AVPacket* pkt, AVFrame* frame); int __avcodec_encode_video2_flush(AVCodecContext* enc_ctx, AVPacket* pkt); diff --git a/README.md b/README.md index 51ba3c6..7d4b1a0 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,11 @@ The following instructions are used for building the project on Windows with Vis 6. The `mpegCoder.pyd` should be used together with the FFMpeg shared libraries, including: ```shell - avcodec-58.dll - avformat-58.dll - avutil-56.dll - swresample-3.dll - swscale-5.dll + avcodec-59.dll + avformat-59.dll + avutil-57.dll + swresample-4.dll + swscale-6.dll ``` ## Update reports @@ -59,15 +59,15 @@ Has been moved to [:bookmark_tabs: CHANGELOG.md](./CHANGELOG.md) ## Version of currently used FFmpeg library -Current FFMpeg version is `4.4`. +Current FFMpeg version is `5.0`. | Dependency | Version | | :-------------: | :------------: | -| `libavcodec` | `58.134.100.0` | -| `libavformat` | `58.76.100.0` | -| `libavutil` | `56.70.100.0` | -| `libswresample` | `3.9.100.0` | -| `libswscale` | `5.9.100.0` | +| `libavcodec` | `59.18.100.0` | +| `libavformat` | `59.16.100.0` | +| `libavutil` | `57.17.100.0` | +| `libswresample` | `4.3.100.0` | +| `libswscale` | `6.4.100.0` | [git-linux]:https://github.com/cainmagi/FFmpeg-Encoder-Decoder-for-Python/tree/master-linux "master (Linux)" [exp1]:https://github.com/cainmagi/FFmpeg-Encoder-Decoder-for-Python/tree/example-client-check "check the client" diff --git a/webtools.py b/webtools.py index 2fedeef..13b351d 100644 --- a/webtools.py +++ b/webtools.py @@ -302,4 +302,4 @@ def download_tarball(user, repo, tag, asset, path='.', mode='auto', token=None, # token = get_token(token='') print('Get ffmpeg dependencies...') - download_tarball('cainmagi', 'FFmpeg-Encoder-Decoder-for-Python', 'deps-3.0.0', 'dep-win-ffmpeg_4_4.tar.xz', path='.', mode='auto', verbose=True, token='') + download_tarball('cainmagi', 'FFmpeg-Encoder-Decoder-for-Python', 'deps-3.2.0', 'dep-win-ffmpeg_5_0.tar.xz', path='.', mode='auto', verbose=True, token='')