package: zoneminder Version: 1.36.33+dfsg1-1 The source code of zoneminder is incompatible with the current version of FFmpeg 7, leading to a crash when trying to compile against it. The attached patch fixes the issues, allowing successful compilation.
I am using Ubuntu 24.04 and Debian Unstable.
diff -Nru zoneminder-1.36.33+dfsg1.orig/src/zm_camera.h zoneminder-1.36.33+dfsg1/src/zm_camera.h --- zoneminder-1.36.33+dfsg1.orig/src/zm_camera.h 2024-09-10 20:26:34.096617372 -0400 +++ zoneminder-1.36.33+dfsg1/src/zm_camera.h 2024-09-10 20:36:28.867120617 -0400 @@ -108,9 +108,9 @@ } int getChannels() { #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - return mAudioStream ? mAudioStream->codecpar->channels : -1; + return mAudioStream ? mAudioStream->codecpar->ch_layout.nb_channels : -1; #else - return mAudioStream ? mAudioStream->codec->channels : -1; + return mAudioStream ? mAudioStream->codec->ch_layout.nb_channels : -1; #endif } diff -Nru zoneminder-1.36.33+dfsg1.orig/src/zm_ffmpeg.cpp zoneminder-1.36.33+dfsg1/src/zm_ffmpeg.cpp --- zoneminder-1.36.33+dfsg1.orig/src/zm_ffmpeg.cpp 2024-09-10 20:26:34.096617372 -0400 +++ zoneminder-1.36.33+dfsg1/src/zm_ffmpeg.cpp 2024-09-10 20:47:38.354826253 -0400 @@ -334,8 +334,8 @@ if (tbn) zm_log_fps(1 / av_q2d(st->time_base), "stream tb numerator"); } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { - Debug(1, "profile %d channels %d sample_rate %d", - codec->profile, codec->channels, codec->sample_rate); + Debug(1, "profile %d ch_layout.nb_channels %d sample_rate %d", + codec->profile, codec->ch_layout.nb_channels, codec->sample_rate); } if (st->disposition & AV_DISPOSITION_DEFAULT) diff -Nru zoneminder-1.36.33+dfsg1.orig/src/zm_ffmpeg.h zoneminder-1.36.33+dfsg1/src/zm_ffmpeg.h --- zoneminder-1.36.33+dfsg1.orig/src/zm_ffmpeg.h 2024-09-10 20:26:34.096617372 -0400 +++ zoneminder-1.36.33+dfsg1/src/zm_ffmpeg.h 2024-09-10 20:49:00.780033524 -0400 @@ -314,7 +314,7 @@ av_get_sample_fmt_name((AVSampleFormat)frame->format), \ frame->sample_rate, \ frame->nb_samples, \ - frame->channel_layout, \ + frame->ch_layout, \ frame->pts \ ); diff -Nru zoneminder-1.36.33+dfsg1.orig/src/zm_ffmpeg_input.cpp zoneminder-1.36.33+dfsg1/src/zm_ffmpeg_input.cpp --- zoneminder-1.36.33+dfsg1.orig/src/zm_ffmpeg_input.cpp 2024-09-10 20:26:34.096617372 -0400 +++ zoneminder-1.36.33+dfsg1/src/zm_ffmpeg_input.cpp 2024-09-10 20:53:11.704662456 -0400 @@ -300,7 +300,7 @@ last_seek_request = seek_target; // Normally it is likely just the next packet. Need a heuristic for seeking, something like duration * keyframe interval - if (frame->pts + 10*frame->pkt_duration < seek_target) { + if (frame->pts + 10*frame->duration < seek_target) { Debug(1, "Jumping ahead"); if (( ret = av_seek_frame(input_format_context, stream_id, seek_target, AVSEEK_FLAG_FRAME @@ -313,7 +313,7 @@ } // Seeking seems to typically seek to a keyframe, so then we have to decode until we get the frame we want. if (frame->pts <= seek_target) { - while (frame && (frame->pts + frame->pkt_duration < seek_target)) { + while (frame && (frame->pts + frame->duration < seek_target)) { if (is_video_stream(input_format_context->streams[stream_id])) { zm_dump_video_frame(frame, "pts <= seek_target"); } else { diff -Nru zoneminder-1.36.33+dfsg1.orig/src/zm_mpeg.cpp zoneminder-1.36.33+dfsg1/src/zm_mpeg.cpp --- zoneminder-1.36.33+dfsg1.orig/src/zm_mpeg.cpp 2024-09-10 20:26:34.098617377 -0400 +++ zoneminder-1.36.33+dfsg1/src/zm_mpeg.cpp 2024-09-10 20:56:15.979127047 -0400 @@ -629,7 +629,7 @@ pkt->size = buffer_size; got_packet = 1; } else { - opicture_ptr->pts = codec_context->frame_number; + opicture_ptr->pts = codec_context->frame_num; opicture_ptr->quality = codec_context->global_quality; #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) diff -Nru zoneminder-1.36.33+dfsg1.orig/src/zm_videostore.cpp zoneminder-1.36.33+dfsg1/src/zm_videostore.cpp --- zoneminder-1.36.33+dfsg1.orig/src/zm_videostore.cpp 2024-09-10 20:26:34.100617382 -0400 +++ zoneminder-1.36.33+dfsg1/src/zm_videostore.cpp 2024-09-11 11:37:47.051160173 -0400 @@ -470,9 +470,9 @@ audio_out_ctx->codec_tag = 0; #endif - if (audio_out_ctx->channels > 1) { + if (audio_out_ctx->ch_layout.nb_channels > 1) { Warning("Audio isn't mono, changing it."); - audio_out_ctx->channels = 1; + audio_out_ctx->ch_layout.nb_channels = 1; } else { Debug(3, "Audio is mono"); } @@ -803,26 +803,30 @@ Debug(2, "Got something other than AAC (%s)", audio_in_codec->name); // Some formats (i.e. WAV) do not produce the proper channel layout - if (audio_in_ctx->channel_layout == 0) { + if (av_channel_layout_check(&audio_in_ctx->ch_layout)) { + //if (audio_in_ctx->ch_layout == 0) { Debug(2, "Setting input channel layout to mono"); // Perhaps we should not be modifying the audio_in_ctx.... - audio_in_ctx->channel_layout = av_get_channel_layout("mono"); + //audio_in_ctx->ch_layout = av_get_channel_layout("mono"); + av_channel_layout_default(&audio_in_ctx->ch_layout, 0); } /* put sample parameters */ audio_out_ctx->bit_rate = audio_in_ctx->bit_rate <= 32768 ? audio_in_ctx->bit_rate : 32768; audio_out_ctx->sample_rate = audio_in_ctx->sample_rate; audio_out_ctx->sample_fmt = audio_in_ctx->sample_fmt; - audio_out_ctx->channels = audio_in_ctx->channels; - audio_out_ctx->channel_layout = audio_in_ctx->channel_layout; + audio_out_ctx->ch_layout.nb_channels = audio_in_ctx->ch_layout.nb_channels; + audio_out_ctx->ch_layout = audio_in_ctx->ch_layout; audio_out_ctx->sample_fmt = audio_in_ctx->sample_fmt; -#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100) - if (!audio_out_ctx->channel_layout) { +#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 61, 100) + if (!av_channel_layout_check(&audio_out_ctx->ch_layout)) { + //if (!audio_out_ctx->ch_layout) { Debug(3, "Correcting channel layout from (%" PRIi64 ") to (%" PRIi64 ")", - audio_out_ctx->channel_layout, - av_get_default_channel_layout(audio_out_ctx->channels) + audio_out_ctx->ch_layout, + av_channel_layout_from_string(&audio_out_ctx->ch_layout,std::to_string(audio_out_ctx->ch_layout.nb_channels).c_str()) + //av_get_default_channel_layout(audio_out_ctx->ch_layout.nb_channels) ); - audio_out_ctx->channel_layout = av_get_default_channel_layout(audio_out_ctx->channels); + av_channel_layout_default(&audio_out_ctx->ch_layout, audio_out_ctx->ch_layout.nb_channels); } #endif if (audio_out_codec->supported_samplerates) { @@ -892,27 +896,27 @@ Debug(1, "Audio in bit_rate (%" AV_PACKET_DURATION_FMT ") sample_rate(%d) channels(%d) fmt(%d) layout(%" PRIi64 ") frame_size(%d)", audio_in_ctx->bit_rate, audio_in_ctx->sample_rate, - audio_in_ctx->channels, audio_in_ctx->sample_fmt, - audio_in_ctx->channel_layout, audio_in_ctx->frame_size); + audio_in_ctx->ch_layout.nb_channels, audio_in_ctx->sample_fmt, + audio_in_ctx->ch_layout, audio_in_ctx->frame_size); Debug(1, "Audio out context bit_rate (%" AV_PACKET_DURATION_FMT ") sample_rate(%d) channels(%d) fmt(%d) layout(% " PRIi64 ") frame_size(%d)", audio_out_ctx->bit_rate, audio_out_ctx->sample_rate, - audio_out_ctx->channels, audio_out_ctx->sample_fmt, - audio_out_ctx->channel_layout, audio_out_ctx->frame_size); + audio_out_ctx->ch_layout.nb_channels, audio_out_ctx->sample_fmt, + audio_out_ctx->ch_layout, audio_out_ctx->frame_size); #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) Debug(1, "Audio out stream bit_rate (%" PRIi64 ") sample_rate(%d) channels(%d) fmt(%d) layout(%" PRIi64 ") frame_size(%d)", audio_out_stream->codecpar->bit_rate, audio_out_stream->codecpar->sample_rate, - audio_out_stream->codecpar->channels, audio_out_stream->codecpar->format, - audio_out_stream->codecpar->channel_layout, audio_out_stream->codecpar->frame_size); + audio_out_stream->codecpar->ch_layout.nb_channels, audio_out_stream->codecpar->format, + audio_out_stream->codecpar->ch_layout, audio_out_stream->codecpar->frame_size); #else Debug(1, "Audio out bit_rate (%d) sample_rate(%d) channels(%d) fmt(%d) " "layout(%" PRIi64 ") frame_size(%d)", audio_out_stream->codec->bit_rate, audio_out_stream->codec->sample_rate, - audio_out_stream->codec->channels, audio_out_stream->codec->sample_fmt, - audio_out_stream->codec->channel_layout, audio_out_stream->codec->frame_size); + audio_out_stream->codec->ch_layout.nb_channels, audio_out_stream->codec->sample_fmt, + audio_out_stream->codec->ch_layout, audio_out_stream->codec->frame_size); #endif /** Create a new frame to store the audio samples. */ @@ -933,20 +937,19 @@ if (!(fifo = av_audio_fifo_alloc( audio_out_ctx->sample_fmt, - audio_out_ctx->channels, 1))) { + audio_out_ctx->ch_layout.nb_channels, 1))) { Error("Could not allocate FIFO"); return false; } #if defined(HAVE_LIBSWRESAMPLE) - resample_ctx = swr_alloc_set_opts(nullptr, - audio_out_ctx->channel_layout, - audio_out_ctx->sample_fmt, - audio_out_ctx->sample_rate, - audio_in_ctx->channel_layout, - audio_in_ctx->sample_fmt, - audio_in_ctx->sample_rate, - 0, nullptr); - if (!resample_ctx) { + if ((ret = swr_alloc_set_opts2(&resample_ctx, + &audio_out_ctx->ch_layout, + audio_out_ctx->sample_fmt, + audio_out_ctx->sample_rate, + &audio_in_ctx->ch_layout, + audio_in_ctx->sample_fmt, + audio_in_ctx->sample_rate, + 0, nullptr)) < 0) { Error("Could not allocate resample context"); av_frame_free(&in_frame); av_frame_free(&out_frame); @@ -973,7 +976,7 @@ } av_opt_set_int(resample_ctx, "in_channel_layout", - audio_in_ctx->channel_layout, 0); + audio_in_ctx->ch_layout, 0); av_opt_set_int(resample_ctx, "in_sample_fmt", audio_in_ctx->sample_fmt, 0); av_opt_set_int(resample_ctx, "in_sample_rate", @@ -981,13 +984,13 @@ av_opt_set_int(resample_ctx, "in_channels", audio_in_ctx->channels, 0); av_opt_set_int(resample_ctx, "out_channel_layout", - audio_in_ctx->channel_layout, 0); + audio_in_ctx->ch_layout, 0); av_opt_set_int(resample_ctx, "out_sample_fmt", audio_out_ctx->sample_fmt, 0); av_opt_set_int(resample_ctx, "out_sample_rate", audio_out_ctx->sample_rate, 0); av_opt_set_int(resample_ctx, "out_channels", - audio_out_ctx->channels, 0); + audio_out_ctx->ch_layout.nb_channels, 0); if ((ret = avresample_open(resample_ctx)) < 0) { Error("Could not open resample ctx"); @@ -1001,15 +1004,15 @@ out_frame->nb_samples = audio_out_ctx->frame_size; out_frame->format = audio_out_ctx->sample_fmt; #if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100) - out_frame->channels = audio_out_ctx->channels; + out_frame->ch_layout.nb_channels = audio_out_ctx->ch_layout.nb_channels; #endif - out_frame->channel_layout = audio_out_ctx->channel_layout; + out_frame->ch_layout = audio_out_ctx->ch_layout; out_frame->sample_rate = audio_out_ctx->sample_rate; // The codec gives us the frame size, in samples, we calculate the size of the // samples buffer in bytes unsigned int audioSampleBuffer_size = av_samples_get_buffer_size( - nullptr, audio_out_ctx->channels, + nullptr, audio_out_ctx->ch_layout.nb_channels, audio_out_ctx->frame_size, audio_out_ctx->sample_fmt, 0); converted_in_samples = reinterpret_cast<uint8_t *>(av_malloc(audioSampleBuffer_size)); @@ -1023,7 +1026,7 @@ // Setup the data pointers in the AVFrame if (avcodec_fill_audio_frame( - out_frame, audio_out_ctx->channels, + out_frame, audio_out_ctx->ch_layout.nb_channels, audio_out_ctx->sample_fmt, (const uint8_t *)converted_in_samples, audioSampleBuffer_size, 0) < 0) { @@ -1183,7 +1186,7 @@ //zm_packet->out_frame->pict_type = AV_PICTURE_TYPE_NONE; //zm_packet->out_frame->key_frame = zm_packet->keyframe; #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - frame->pkt_duration = 0; + frame->duration = 0; #endif int64_t in_pts = zm_packet->timestamp.tv_sec * (uint64_t)1000000 + zm_packet->timestamp.tv_usec; @@ -1235,14 +1238,14 @@ int64_t duration = 0; if (zm_packet->in_frame) { - if (zm_packet->in_frame->pkt_duration) { + if (zm_packet->in_frame->duration) { duration = av_rescale_q( - zm_packet->in_frame->pkt_duration, + zm_packet->in_frame->duration, video_in_stream->time_base, video_out_stream->time_base); - Debug(1, "duration from ipkt: pts(%" PRId64 ") = pkt_duration(%" PRId64 ") => (%" PRId64 ") (%d/%d) (%d/%d)", + Debug(1, "duration from ipkt: pts(%" PRId64 ") = duration(%" PRId64 ") => (%" PRId64 ") (%d/%d) (%d/%d)", zm_packet->in_frame->pts, - zm_packet->in_frame->pkt_duration, + zm_packet->in_frame->duration, duration, video_in_stream->time_base.num, video_in_stream->time_base.den, @@ -1261,8 +1264,8 @@ duration ); if (duration <= 0) { - duration = zm_packet->in_frame->pkt_duration ? - zm_packet->in_frame->pkt_duration : + duration = zm_packet->in_frame->duration ? + zm_packet->in_frame->duration : av_rescale_q(1, video_in_stream->time_base, video_out_stream->time_base); } } // end if in_frmae->pkt_duration