Bug#1081485: Fix compilation of shotdetect against ffmpeg 7
package: shotdetect
Version: 1.0.86-6
The source code of shotdetect 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 shotdetect-1.0.86.orig/src/film.cpp shotdetect-1.0.86/src/film.cpp
--- shotdetect-1.0.86.orig/src/film.cpp 2024-09-11 12:04:16.621965453 -0400
+++ shotdetect-1.0.86/src/film.cpp 2024-09-11 18:18:09.827384029 -0400
@@ -18,6 +18,7 @@
#include "film.h"
#include "graph.h"
extern "C" {
+#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
#define DEBUG
@@ -143,10 +144,13 @@
/* Video metadata */
if (videoStream != -1)
{
- this->height = int (pFormatCtx->streams[videoStream]->codec->height);
- this->width = int (pFormatCtx->streams[videoStream]->codec->width);
+ this->height = int (pFormatCtx->streams[videoStream]->codecpar->height);
+ this->width = int (pFormatCtx->streams[videoStream]->codecpar->width);
this->fps = av_q2d (pFormatCtx->streams[videoStream]->avg_frame_rate);
- avcodec_string (buf, sizeof (buf), pFormatCtx->streams[videoStream]->codec, 0);
+ AVCodecContext *pCodecCtx_temp;
+ avcodec_parameters_to_context (pCodecCtx_temp, pFormatCtx->streams[videoStream]->codecpar);
+ avcodec_string (buf, sizeof (buf), pCodecCtx_temp, 0);
+ avcodec_free_context(&pCodecCtx_temp);
this->codec.video = buf;
}
else
@@ -162,7 +166,7 @@
{
avcodec_string (buf, sizeof (buf), pCodecCtxAudio, 0);
this->codec.audio = buf;
- this->nchannel = pCodecCtxAudio->channels;
+ this->nchannel = pCodecCtxAudio->ch_layout.nb_channels;
this->samplerate = pCodecCtxAudio->sample_rate;
}
else
@@ -210,7 +214,6 @@
/*
* Register all formats and codecs
*/
- av_register_all ();
if( ! ( pFormatCtx = avformat_alloc_context() )
|| (avformat_open_input (&pFormatCtx, input_path.c_str (), NULL, NULL) != 0) )
@@ -238,7 +241,7 @@
*/
for (int j = 0; j < pFormatCtx->nb_streams; j++)
{
- switch (pFormatCtx->streams[j]->codec->codec_type)
+ switch (pFormatCtx->streams[j]->codecpar->codec_type)
{
case AVMEDIA_TYPE_VIDEO:
videoStream = j;
@@ -266,8 +269,9 @@
init_xml (xml_audio);
}
- pCodecCtxAudio = pFormatCtx->streams[audioStream]->codec;
- pCodecAudio = avcodec_find_decoder (pCodecCtxAudio->codec_id);
+ avcodec_parameters_to_context (pCodecCtxAudio, pFormatCtx->streams[audioStream]->codecpar);
+ const AVCodec * local_codec_Audio = avcodec_find_decoder (pCodecCtxAudio->codec_id);
+ pCodecAudio = const_cast<AVCodec *>(local_codec_Audio);
if (pCodecAudio == NULL)
return -1; // Codec not found
@@ -281,8 +285,9 @@
*/
if (videoStream != -1)
{
- pCodecCtx = pFormatCtx->streams[videoStream]->codec;
- pCodec = avcodec_find_decoder (pCodecCtx->codec_id);
+ avcodec_parameters_to_context (pCodecCtx, pFormatCtx->streams[videoStream]->codecpar);
+ const AVCodec * local_codec = avcodec_find_decoder (pCodecCtx->codec_id);
+ pCodec = const_cast<AVCodec *>(local_codec);
if (pCodec == NULL)
return -1; // Codec not found
@@ -299,7 +304,7 @@
/*
* Determine required buffer size and allocate buffer
*/
- numBytes = avpicture_get_size (AV_PIX_FMT_RGB24, width, height);
+ numBytes = av_image_get_buffer_size (AV_PIX_FMT_RGB24, width, height, 1);
buffer = (uint8_t *) malloc (sizeof (uint8_t) * numBytes);
buffer2 = (uint8_t *) malloc (sizeof (uint8_t) * numBytes);
@@ -307,10 +312,11 @@
/*
* Assign appropriate parts of buffer to image planes in pFrameRGB
*/
- avpicture_fill ((AVPicture *) pFrameRGB, buffer, AV_PIX_FMT_RGB24, width, height);
-
- avpicture_fill ((AVPicture *) pFrameRGBprev, buffer2, AV_PIX_FMT_RGB24, width, height);
+ av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize,
+ buffer, AV_PIX_FMT_RGB24, width, height, 1);
+ av_image_fill_arrays(pFrameRGBprev->data, pFrameRGBprev->linesize,
+ buffer2, AV_PIX_FMT_RGB24, width, height, 1);
/*
* Mise en place du premier plan
@@ -335,15 +341,15 @@
{
if (packet.stream_index == videoStream)
{
- AVPacket avpkt;
- av_init_packet(&avpkt);
- avpkt.data = packet.data;
- avpkt.size = packet.size;
- //
+ AVPacket *avpkt = av_packet_alloc();
+ avpkt->data = packet.data;
+ avpkt->size = packet.size;
+ //
// HACK for CorePNG to decode as normal PNG by default
// same method used by ffmpeg
- avpkt.flags = AV_PKT_FLAG_KEY;
- avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &avpkt);
+ avpkt->flags = AV_PKT_FLAG_KEY;
+ avcodec_send_packet(pCodecCtx,avpkt);
+ avcodec_receive_frame(pCodecCtx,pFrame);
if (frameFinished)
{
@@ -404,7 +410,7 @@
* Free the packet that was allocated by av_read_frame
*/
if (packet.data != NULL)
- av_free_packet (&packet);
+ av_packet_unref (&packet);
}
if (videoStream != -1)
@@ -440,7 +446,7 @@
av_frame_free (&pFrameRGB);
av_frame_free (&pFrame);
av_frame_free (&pFrameRGBprev);
- avcodec_close (pCodecCtx);
+ avcodec_free_context(&pCodecCtx);
}
/*
* Close the codec
@@ -449,7 +455,7 @@
{
/* Close the XML file */
if (audio_set) close_xml ();
- avcodec_close (pCodecCtxAudio);
+ avcodec_free_context(&pCodecCtxAudio);
}
/*
@@ -496,14 +502,13 @@
ptr = packet.data;
len = packet.size;
- AVPacket avpkt;
- av_init_packet(&avpkt);
+ AVPacket *avpkt = av_packet_alloc();
while (len > 0)
{
- avpkt.data = ptr;
- avpkt.size = len;
- len1 = avcodec_decode_audio4 (pCodecCtxAudio, frame, &got_output, &avpkt);
-
+ avpkt->data = ptr;
+ avpkt->size = len;
+ avcodec_send_packet (pCodecCtxAudio,avpkt);
+ len1 = avcodec_receive_frame (pCodecCtxAudio, frame);
if (len1 < 0)
{
@@ -524,12 +529,12 @@
if (av_sample_fmt_is_planar(pCodecCtxAudio->sample_fmt)) {
left = (int16_t*)frame->data[0];
- right = (pCodecCtxAudio->channels > 1) ? (int16_t*)frame->data[1] : left;
+ right = (pCodecCtxAudio->ch_layout.nb_channels > 1) ? (int16_t*)frame->data[1] : left;
block_align = 1;
} else {
left = (int16_t*)frame->data[0];
- right = (pCodecCtxAudio->channels > 1) ? left + 1 : left;
- block_align = pCodecCtxAudio->channels;
+ right = (pCodecCtxAudio->ch_layout.nb_channels > 1) ? left + 1 : left;
+ block_align = pCodecCtxAudio->ch_layout.nb_channels;
}
samples += frame->nb_samples;
@@ -594,3 +599,4 @@
this->shot_set = false;
}
+
Reply to: