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