Package: aiscm
Version: 0.23.1-1
Followup-For: Bug #1004784
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu kinetic

Here is a more complete patch that deals with ffmpeg API changes. 
Unfortunately after applying this patch, the test suite hangs in
avcodec_send_packet(), so I've clearly gotten something wrong.  (At least
there's a good testsuite!)

-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
Ubuntu Developer                                   https://www.debian.org/
slanga...@ubuntu.com                                     vor...@debian.org
diff -Nru aiscm-0.23.1/debian/patches/0001-Use-codecpar-instead-of-codec.patch 
aiscm-0.23.1/debian/patches/0001-Use-codecpar-instead-of-codec.patch
--- aiscm-0.23.1/debian/patches/0001-Use-codecpar-instead-of-codec.patch        
1969-12-31 16:00:00.000000000 -0800
+++ aiscm-0.23.1/debian/patches/0001-Use-codecpar-instead-of-codec.patch        
2022-07-20 07:10:02.000000000 -0700
@@ -0,0 +1,191 @@
+From 6eb20d6c3079dd59d5e1caedf3afc170dc0e84d3 Mon Sep 17 00:00:00 2001
+From: "Jan Wedekind (Dr)" <j...@wedesoft.de>
+Date: Sun, 6 Feb 2022 10:55:57 +0000
+Subject: [PATCH] Use codecpar instead of codec
+
+---
+ aiscm/ffmpeg.c | 56 ++++++++++++++++++++++++++++----------------------
+ 1 file changed, 32 insertions(+), 24 deletions(-)
+
+diff --git a/aiscm/ffmpeg.c b/aiscm/ffmpeg.c
+index 982e03fa..e2064491 100644
+--- a/aiscm/ffmpeg.c
++++ b/aiscm/ffmpeg.c
+@@ -60,8 +60,8 @@ static scm_t_bits ffmpeg_tag;
+ 
+ struct ffmpeg_t {
+   AVFormatContext *fmt_ctx;
+-  AVCodecContext *video_codec_ctx;
+-  AVCodecContext *audio_codec_ctx;
++  struct AVCodecContext *video_codec_ctx;
++  struct AVCodecContext *audio_codec_ctx;
+   int video_stream_idx;
+   int audio_stream_idx;
+   long output_video_pts;
+@@ -94,14 +94,14 @@ static struct ffmpeg_t *get_self(SCM scm_self)
+   return get_self_no_check(scm_self);
+ }
+ 
+-static AVCodecContext *video_codec_ctx(struct ffmpeg_t *self)
++static struct AVCodecContext *video_codec_ctx(struct ffmpeg_t *self)
+ {
+   if (!self->video_codec_ctx)
+     scm_misc_error("video-codec-ctx", "File format does not have a video 
stream", SCM_EOL);
+   return self->video_codec_ctx;
+ }
+ 
+-static AVCodecContext *audio_codec_ctx(struct ffmpeg_t *self)
++static struct AVCodecContext *audio_codec_ctx(struct ffmpeg_t *self)
+ {
+   if (!self->audio_codec_ctx)
+     scm_misc_error("audio-codec-ctx", "File format does not have an audio 
stream", SCM_EOL);
+@@ -127,7 +127,7 @@ static char is_input_context(struct ffmpeg_t *self)
+   return self->fmt_ctx->iformat != NULL;
+ }
+ 
+-static void write_frame(struct ffmpeg_t *self, AVPacket *packet, 
AVCodecContext *codec, AVStream *stream, int stream_idx)
++static void write_frame(struct ffmpeg_t *self, AVPacket *packet, struct 
AVCodecContext *codec, AVStream *stream, int stream_idx)
+ {
+ #ifdef HAVE_AV_PACKET_RESCALE_TS
+   av_packet_rescale_ts(packet, codec->time_base, stream->time_base);
+@@ -144,7 +144,7 @@ static void write_frame(struct ffmpeg_t *self, AVPacket 
*packet, AVCodecContext
+ 
+ static int encode_video(struct ffmpeg_t *self, AVFrame *video_frame)
+ {
+-  AVCodecContext *codec = video_codec_ctx(self);
++  struct AVCodecContext *codec = video_codec_ctx(self);
+ 
+   // Initialise data packet
+   AVPacket pkt = { 0 };
+@@ -166,7 +166,7 @@ static int encode_video(struct ffmpeg_t *self, AVFrame 
*video_frame)
+ 
+ static int encode_audio(struct ffmpeg_t *self, AVFrame *audio_frame)
+ {
+-  AVCodecContext *codec = audio_codec_ctx(self);
++  struct AVCodecContext *codec = audio_codec_ctx(self);
+ 
+   // Initialise data packet
+   AVPacket pkt = { 0 };
+@@ -234,12 +234,12 @@ SCM ffmpeg_destroy(SCM scm_self)
+   };
+ 
+   if (self->audio_codec_ctx) {
+-    avcodec_close(self->audio_codec_ctx);
++    avcodec_free_context(&self->audio_codec_ctx);
+     self->audio_codec_ctx = NULL;
+   };
+ 
+   if (self->video_codec_ctx) {
+-    avcodec_close(self->video_codec_ctx);
++    avcodec_free_context(&self->video_codec_ctx);
+     self->video_codec_ctx = NULL;
+   };
+ 
+@@ -267,7 +267,7 @@ size_t free_ffmpeg(SCM scm_self)
+   return 0;
+ }
+ 
+-static AVCodecContext *open_codec(SCM scm_self, AVCodecContext *codec_ctx, 
AVCodec *codec,
++static struct AVCodecContext *open_codec(SCM scm_self, AVCodecContext 
*codec_ctx, AVCodec *codec,
+                                   const char *media_type, SCM scm_file_name)
+ {
+   int err = avcodec_open2(codec_ctx, codec, NULL);
+@@ -279,17 +279,25 @@ static AVCodecContext *open_codec(SCM scm_self, 
AVCodecContext *codec_ctx, AVCod
+   return codec_ctx;
+ }
+ 
+-static AVCodecContext *open_decoder(SCM scm_self, SCM scm_file_name,
++static struct AVCodecContext *open_decoder(SCM scm_self, SCM scm_file_name,
+                                     AVStream *stream, const char *media_type)
+ {
+-  AVCodecContext *dec_ctx = stream->codec;
+-  AVCodec *decoder = avcodec_find_decoder(dec_ctx->codec_id);
+-  if (!decoder) {
++  struct AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
++  if (!dec) {
+     ffmpeg_destroy(scm_self);
+-    scm_misc_error("open-codec", "Failed to find ~a codec for file '~a'",
++    scm_misc_error("open-codec", "Failed to find ~a decoder for file '~a'",
+                    scm_list_2(scm_from_locale_string(media_type), 
scm_file_name));
+   };
+-  return open_codec(scm_self, dec_ctx, decoder, media_type, scm_file_name);
++  struct AVCodecContext *dec_ctx = avcodec_alloc_context3(dec);
++  if (!dec_ctx) {
++    ffmpeg_destroy(scm_self);
++    scm_misc_error("open-codec", "Failed to allocate codec context for file 
'~a'",
++                   scm_list_1(scm_file_name));
++  };
++  avcodec_parameters_to_context(dec_ctx, stream->codecpar);
++  AVDictionary *opts = NULL;
++  avcodec_open2(dec_ctx, dec, &opts);
++  return dec_ctx;
+ }
+ 
+ static AVFrame *allocate_frame(SCM scm_self)
+@@ -387,11 +395,11 @@ static AVStream *open_output_stream(SCM scm_self, 
AVCodec *encoder, int *stream_
+   return retval;
+ }
+ 
+-static AVCodecContext *configure_output_video_codec(AVStream *video_stream, 
enum AVCodecID video_codec_id,
++static struct AVCodecContext *configure_output_video_codec(AVStream 
*video_stream, enum AVCodecID video_codec_id,
+     SCM scm_video_bit_rate, SCM scm_shape, SCM scm_frame_rate, SCM 
scm_aspect_ratio)
+ {
+   // Get codec context
+-  AVCodecContext *retval = video_stream->codec;
++  struct AVCodecContext *retval = video_stream->codec;
+ 
+   // Set codec id
+   retval->codec_id = video_codec_id;
+@@ -427,11 +435,11 @@ static AVCodecContext 
*configure_output_video_codec(AVStream *video_stream, enum
+   return retval;
+ }
+ 
+-static AVCodecContext *configure_output_audio_codec(SCM scm_self, AVStream 
*audio_stream, enum AVCodecID audio_codec_id,
++static struct AVCodecContext *configure_output_audio_codec(SCM scm_self, 
AVStream *audio_stream, enum AVCodecID audio_codec_id,
+     SCM scm_select_rate, SCM scm_channels, SCM scm_audio_bit_rate, SCM 
scm_select_format)
+ {
+   // Get codec context
+-  AVCodecContext *retval = audio_stream->codec;
++  struct AVCodecContext *retval = audio_stream->codec;
+   const AVCodec *codec = retval->codec;
+ 
+   // Select sample format
+@@ -471,7 +479,7 @@ static AVCodecContext *configure_output_audio_codec(SCM 
scm_self, AVStream *audi
+   return retval;
+ }
+ 
+-static AVFrame *allocate_output_video_frame(SCM scm_self, AVCodecContext 
*video_context)
++static AVFrame *allocate_output_video_frame(SCM scm_self, struct 
AVCodecContext *video_context)
+ {
+   AVFrame *retval = allocate_frame(scm_self);
+   int width = video_context->width;
+@@ -498,7 +506,7 @@ static AVFrame *allocate_output_video_frame(SCM scm_self, 
AVCodecContext *video_
+   return retval;
+ }
+ 
+-static AVFrame *allocate_output_audio_frame(SCM scm_self, AVCodecContext 
*audio_codec, enum AVSampleFormat sample_fmt)
++static AVFrame *allocate_output_audio_frame(SCM scm_self, struct 
AVCodecContext *audio_codec, enum AVSampleFormat sample_fmt)
+ {
+   AVFrame *retval = allocate_frame(scm_self);
+   retval->format = sample_fmt;
+@@ -683,7 +691,7 @@ SCM ffmpeg_have_audio(SCM scm_self)
+ 
+ SCM ffmpeg_shape(SCM scm_self)
+ {
+-  AVCodecContext *ctx = video_codec_ctx(get_self(scm_self));
++  struct AVCodecContext *ctx = video_codec_ctx(get_self(scm_self));
+   return scm_list_2(scm_from_int(ctx->height), scm_from_int(ctx->width));
+ }
+ 
+@@ -975,7 +983,7 @@ SCM ffmpeg_fetch_audio(SCM scm_self, SCM scm_data, SCM 
scm_bytes)
+ SCM ffmpeg_encode_audio(SCM scm_self)
+ {
+   struct ffmpeg_t *self = get_self(scm_self);
+-  AVCodecContext *codec = audio_codec_ctx(self);
++  struct AVCodecContext *codec = audio_codec_ctx(self);
+   AVFrame *audio_frame = self->audio_target_frame;
+   audio_frame->pts = av_rescale_q(self->samples_count, (AVRational){1, 
codec->sample_rate}, codec->time_base);
+   self->samples_count += audio_frame->nb_samples;
+-- 
+2.34.1
+
diff -Nru aiscm-0.23.1/debian/patches/ffmpeg-5.0.patch 
aiscm-0.23.1/debian/patches/ffmpeg-5.0.patch
--- aiscm-0.23.1/debian/patches/ffmpeg-5.0.patch        1969-12-31 
16:00:00.000000000 -0800
+++ aiscm-0.23.1/debian/patches/ffmpeg-5.0.patch        2022-07-20 
07:10:02.000000000 -0700
@@ -0,0 +1,245 @@
+Description: compatibility with FFMpeg 5.0
+ Fixes needed to accomodate ffmpeg 5.0 API changes.
+Author: Steve Langasek <steve.langa...@ubuntu.com>
+Bug-Debian: https://bugs.debian.org/1004784
+Last-Update: 2022-07-20
+Forwarded: no
+
+Index: aiscm-0.23.1/aiscm/ffmpeg.c
+===================================================================
+--- aiscm-0.23.1.orig/aiscm/ffmpeg.c
++++ aiscm-0.23.1/aiscm/ffmpeg.c
+@@ -16,6 +16,7 @@
+ //
+ #include <stdio.h>
+ #include <libguile.h>
++#include <libavcodec/avcodec.h>
+ #include <libavutil/imgutils.h>
+ #include <libavutil/opt.h>
+ #include <libavformat/avformat.h>
+@@ -151,17 +152,30 @@
+   av_init_packet(&pkt);
+ 
+   // Encode the video frame
+-  int got_packet;
+-  int err = avcodec_encode_video2(codec, &pkt, video_frame, &got_packet);
+-  if (err < 0)
+-    scm_misc_error("encode-video", "Error encoding video frame: ~a",
+-                   scm_list_1(get_error_text(err)));
++  int got_packet = 0;
++  int ret = avcodec_send_frame(codec, video_frame);
++  if (ret < 0)
++  {
++    scm_misc_error("encode-video", "Error sending a frame for encoding: ~a",
++                   scm_list_1(get_error_text(ret)));
++    return 0;
++  }
+ 
+-  // Write any new video packets
+-  if (got_packet)
+-    write_frame(self, &pkt, codec, video_stream(self), 
self->video_stream_idx);
++  while (ret >= 0) {
++    ret = avcodec_receive_packet(codec, &pkt);
++    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
++      return got_packet;
++    else if (ret < 0) {
++      scm_misc_error("encode-video", "Error encoding video frame: ~a",
++                     scm_list_1(get_error_text(ret)));
++      return got_packet;
++    } else {
++      // Write any new video packets
++      got_packet = 1;
++      write_frame(self, &pkt, codec, video_stream(self), 
self->video_stream_idx);
++    }
++  }
+ 
+-  return got_packet;
+ }
+ 
+ static int encode_audio(struct ffmpeg_t *self, AVFrame *audio_frame)
+@@ -173,17 +187,28 @@
+   av_init_packet(&pkt);
+ 
+   // Encode the audio frame
+-  int got_packet;
+-  int err = avcodec_encode_audio2(codec, &pkt, audio_frame, &got_packet);
++  int got_packet = 0;
++
++  int err = avcodec_send_frame(codec, audio_frame);
+   if (err < 0)
+-    scm_misc_error("encode-audio", "Error encoding audio frame: ~a",
++    scm_misc_error("encode-audio", "Error sending the frame to the encoder: 
~a",
+                    scm_list_1(get_error_text(err)));
+ 
+-  // Write any new audio packets
+-  if (got_packet)
+-    write_frame(self, &pkt, codec, audio_stream(self), 
self->audio_stream_idx);
++  while (1) {
++    err = avcodec_receive_packet(codec, &pkt);
++    if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
++      return got_packet;
++    else if (err < 0) {
++      scm_misc_error("encode-audio", "Error encoding audio frame: ~a",
++                     scm_list_1(get_error_text(err)));
++      return got_packet;
++    } else {
++      // Write any new audio packets
++      got_packet = 1;
++      write_frame(self, &pkt, codec, audio_stream(self), 
self->audio_stream_idx);
++    }
++  }
+ 
+-  return got_packet;
+ }
+ 
+ SCM ffmpeg_destroy(SCM scm_self)
+@@ -395,14 +420,26 @@
+   return retval;
+ }
+ 
+-static struct AVCodecContext *configure_output_video_codec(AVStream 
*video_stream, enum AVCodecID video_codec_id,
++static struct AVCodecContext *configure_output_video_codec(AVStream 
*video_stream, AVCodec *video_encoder,
+     SCM scm_video_bit_rate, SCM scm_shape, SCM scm_frame_rate, SCM 
scm_aspect_ratio)
+ {
++  int res;
+   // Get codec context
+-  struct AVCodecContext *retval = video_stream->codec;
++  struct AVCodecContext *retval = avcodec_alloc_context3(video_encoder);
++
++  if (!retval)
++    return retval;
++
++  res = avcodec_parameters_to_context(retval, video_stream->codecpar);
++  if (res < 0)
++  {
++    avcodec_free_context(&retval);
++    scm_misc_error("configure-output-video-codec", "Error initializing 
context: ~a",
++                   scm_list_1(av_err2str(res)));
++    return retval;
++  }
+ 
+-  // Set codec id
+-  retval->codec_id = video_codec_id;
++  // Set codec type
+   retval->codec_type = AVMEDIA_TYPE_VIDEO;
+ 
+   // Set encoder bit rate
+@@ -435,12 +472,27 @@
+   return retval;
+ }
+ 
+-static struct AVCodecContext *configure_output_audio_codec(SCM scm_self, 
AVStream *audio_stream, enum AVCodecID audio_codec_id,
++static struct AVCodecContext *configure_output_audio_codec(SCM scm_self, 
AVStream *audio_stream, AVCodec *audio_encoder,
+     SCM scm_select_rate, SCM scm_channels, SCM scm_audio_bit_rate, SCM 
scm_select_format)
+ {
++  int res;
+   // Get codec context
+-  struct AVCodecContext *retval = audio_stream->codec;
+-  const AVCodec *codec = retval->codec;
++  struct AVCodecContext *retval = avcodec_alloc_context3(audio_encoder);
++  const AVCodec *codec;
++
++  if (!retval)
++    return retval;
++
++  res = avcodec_parameters_to_context(retval, audio_stream->codecpar);
++  if (res < 0)
++  {
++    avcodec_free_context(&retval);
++    scm_misc_error("configure-output-audio-codec", "Error initializing 
context: ~a",
++                   scm_list_1(av_err2str(res)));
++    return retval;
++  }
++
++  codec = retval->codec;
+ 
+   // Select sample format
+   SCM scm_sample_formats = SCM_EOL;
+@@ -603,7 +655,7 @@
+ 
+     // Configure the output video codec
+     self->video_codec_ctx =
+-      configure_output_video_codec(video_stream, video_codec_id, 
scm_video_bit_rate, scm_shape, scm_frame_rate, scm_aspect_ratio);
++      configure_output_video_codec(video_stream, video_encoder, 
scm_video_bit_rate, scm_shape, scm_frame_rate, scm_aspect_ratio);
+ 
+     // Some formats want stream headers to be separate.
+     if (self->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
+@@ -631,7 +683,7 @@
+ 
+     // Configure the output audio codec
+     self->audio_codec_ctx =
+-      configure_output_audio_codec(retval, audio_stream, audio_codec_id,
++      configure_output_audio_codec(retval, audio_stream, audio_encoder,
+                                    scm_select_rate, scm_channels, 
scm_audio_bit_rate, scm_select_format);
+ 
+     // Some formats want stream headers to be separate.
+@@ -809,12 +861,24 @@
+ 
+ static SCM decode_audio(struct ffmpeg_t *self, AVPacket *pkt, AVFrame *frame)
+ {
+-  int got_frame;
+-  int len = avcodec_decode_audio4(self->audio_codec_ctx, frame, &got_frame, 
pkt);
+-  if (len < 0)
+-    scm_misc_error("ffmpeg-decode-audio/video", "Error decoding frame: ~a", 
scm_list_1(get_error_text(len)));
+-  consume_packet_data(pkt, FFMIN(pkt->size, len));
+-  return got_frame ? list_timestamped_audio(self, frame) : SCM_BOOL_F;
++  int ret;
++
++  ret = avcodec_send_packet(self->audio_codec_ctx, pkt);
++  if (ret < 0) {
++    scm_misc_error("ffmpeg-decode-audio/video", "Error submitting the packet 
to the decoder: ~a", scm_list_1(get_error_text(ret)));
++    return SCM_BOOL_F;
++  }
++
++  /* this is incorrect because in current ffmpeg a single packet can return
++   * multiple frames.  Correcting this is left as an exercise for the reader.
++   */
++  ret = avcodec_receive_frame(self->audio_codec_ctx, frame);
++  if (ret < 0)
++    scm_misc_error("ffmpeg-decode-audio/video", "Error decoding frame: ~a", 
scm_list_1(get_error_text(ret)));
++  else
++    consume_packet_data(pkt, FFMIN(pkt->size, ret));
++
++  return (ret > 0) ? list_timestamped_audio(self, frame) : SCM_BOOL_F;
+ }
+ 
+ static SCM list_video_frame_info(struct ffmpeg_t *self, AVFrame *frame)
+@@ -883,12 +947,24 @@
+ 
+ static SCM decode_video(struct ffmpeg_t *self, AVPacket *pkt, AVFrame *frame)
+ {
+-  int got_frame;
+-  int len = avcodec_decode_video2(self->video_codec_ctx, frame, &got_frame, 
pkt);
+-  if (len < 0)
+-    scm_misc_error("ffmpeg-decode-audio/video", "Error decoding frame: ~a", 
scm_list_1(get_error_text(len)));
+-  consume_packet_data(pkt, pkt->size);
+-  return got_frame ? list_timestamped_video(self, frame) : SCM_BOOL_F;
++  int ret;
++
++  ret = avcodec_send_packet(self->video_codec_ctx, pkt);
++  if (ret < 0) {
++    scm_misc_error("ffmpeg-decode-audio/video", "Error submitting the packet 
to the decoder: ~a", scm_list_1(get_error_text(ret)));
++    return SCM_BOOL_F;
++  }
++
++  /* this is incorrect because in current ffmpeg a single packet can return
++   * multiple frames.  Correcting this is left as an exercise for the reader.
++   */
++  ret = avcodec_receive_frame(self->video_codec_ctx, frame);
++  if (ret < 0)
++    scm_misc_error("ffmpeg-decode-audio/video", "Error decoding frame: ~a", 
scm_list_1(get_error_text(ret)));
++  else
++    consume_packet_data(pkt, pkt->size);
++
++  return (ret > 0) ? list_timestamped_video(self, frame) : SCM_BOOL_F;
+ }
+ 
+ static int packet_empty(struct ffmpeg_t *self)
+@@ -1002,7 +1078,6 @@
+ 
+ void init_ffmpeg(void)
+ {
+-  av_register_all();
+   avformat_network_init();
+   ffmpeg_tag = scm_make_smob_type("ffmpeg", sizeof(struct ffmpeg_t));
+   scm_set_smob_free(ffmpeg_tag, free_ffmpeg);
diff -Nru aiscm-0.23.1/debian/patches/series aiscm-0.23.1/debian/patches/series
--- aiscm-0.23.1/debian/patches/series  1969-12-31 16:00:00.000000000 -0800
+++ aiscm-0.23.1/debian/patches/series  2022-07-20 07:10:02.000000000 -0700
@@ -0,0 +1,2 @@
+0001-Use-codecpar-instead-of-codec.patch
+ffmpeg-5.0.patch

Reply via email to