diff --git a/ffmpeg-definitions.rkt b/ffmpeg-definitions.rkt index 493652f..3807bea 100644 --- a/ffmpeg-definitions.rkt +++ b/ffmpeg-definitions.rkt @@ -48,6 +48,89 @@ (define (AVERROR e) (* -1 e)) +;;;; Load libraries and get major library versions. + +(define libavutil (get-lib (case (system-type 'os) + [(windows) '("avutil-60")] + [else '("avutil" "libavutil")]) '(#f))) + + +(define libswresample (get-lib (case (system-type 'os) + [(windows) '("swresample-6")] + [else '("swresample" "libswresample")]) '(#f))) + +(define libavcodec (get-lib (case (system-type 'os) + [(windows) '("avcodec-62")] + [else '("avcodec" "libavcodec")]) '(#f))) + +(define libavformat (get-lib (case (system-type 'os) + [(windows) '("avformat-62")] + [else '("avformat" "libavformat")]) '(#f))) + + +(define-ffi-definer def-avutil libavutil #:default-make-fail make-not-available) +(define-ffi-definer def-swresample libswresample #:default-make-fail make-not-available) +(define-ffi-definer def-avcodec libavcodec #:default-make-fail make-not-available) +(define-ffi-definer def-avformat libavformat #:default-make-fail make-not-available) + +(def-avutil avutil_version (_fun -> _uint)) +(def-avcodec avcodec_version (_fun -> _uint)) +(def-avformat avformat_version (_fun -> _uint)) +(def-swresample swresample_version (_fun -> _uint)) + +(define avutil-version-major (quotient (avutil_version) 65536)) +(define avcodec-version-major (quotient (avcodec_version) 65536)) +(define avformat-version-major (quotient (avformat_version) 65536)) +(define swresample-version-major (quotient (swresample_version) 65536)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Version check +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define (ffmpeg-version lib) + (let ((v (λ (v) (list (quotient v 65536) (remainder (quotient v 256) 256) (remainder v 256))))) + (cond ((eq? lib 'avutil) (v (avutil_version))) + ((eq? lib 'avcodec) (v (avcodec_version))) + ((eq? lib 'avformat) (v (avformat_version))) + ((or (eq? lib 'swr) + (eq? lib 'swresample)) (v (swresample_version))) + (else (error (format "Unknown library '~a" lib))) + ) + ) + ) + +(define (ffmpeg-version-string lib) + (apply format (cons "~a.~a.~a" (ffmpeg-version lib)))) + +;; Support ffmpeg 6, 7 and 8 + +(define-syntax check-support + (syntax-rules () + ((_ lib version-hash) + (let ((from (car (hash-ref version-hash lib))) + (until (cadr (hash-ref version-hash lib)))) + (let ((major-version (car (ffmpeg-version lib)))) + (cond + ((or (< major-version from) (> major-version until)) + (error + (format "Unsupported major version of ffmpeg library ~a: ~a (~a).\nSupported range: ~a - ~a" + 'lib major-version (ffmpeg-version-string lib) from until))) + (else + (info-sound "Supported ffmpeg library ~a - version ~a between ~a and ~a" + lib (ffmpeg-version-string lib) from until) + ) + ) + ) + ) + ) + ) + ) + +(check-support 'avutil valid-ffmpeg-versions) +(check-support 'avcodec valid-ffmpeg-versions) +(check-support 'avformat valid-ffmpeg-versions) +(check-support 'swresample valid-ffmpeg-versions) + ;;;; Constants (define-cstruct _AVRational @@ -103,29 +186,83 @@ ; codec_id : int / AVCodecID ; ch_layout : AVChannelLayout ; sample_rate : int +; libavcodec stuff. (def-cstruct _AVCodecParameters (codec_type codec_id format ch_layout sample_rate) - (make-offsets (codec_type _AVMediaType) - (codec_id _AVCodecID) + (if (= avcodec-version-major 60) + ;; ffmpeg 6 definition is different and probably backward compatible with ffmpeg 5 + ;; This is with old channel layout in compiled, which is the case on linux. + ;; Probably always, because of back compatibility with ffmpeg 5.0 probably. + (make-offsets + (codec_type _AVMediaType) + (codec_id _AVCodecID) - ;; codec_tag, extradata, extradata_size, - ;; coded_side_data, nb_coded_side_data - _int32 _pointer _int _pointer _int + _uint32 ;; codec_tag + _pointer ;; extradata + _int ;; extradata_size - ;; AVCodecParameters.format - ;; audio: enum AVSampleFormat - (format _AVSampleFormat) + (format _AVSampleFormat) - _int64 ; bit_rate - (6 _int) - (2 _AVRational) - (7 _int) + _int64 ;; bit_rate - (ch_layout _AVChannelLayout) - (sample_rate _int)) + (6 _int) ;; bits_per_coded_sample, bits_per_raw_sample, + ;; profile, level, width, height + + _AVRational ;; sample_aspect_ratio + + (6 _int) ;; field_order, color_range, color_primaries, + ;; color_trc, color_space, chroma_location + + _int ;; video_delay + + ;; Alleen als FF_API_OLD_CHANNEL_LAYOUT actief is. + _uint64 ;; channel_layout + _int ;; channels + + (sample_rate _int) + + (5 _int) ;; block_align, frame_size, + ;; initial_padding, trailing_padding, seek_preroll + + (ch_layout _AVChannelLayout) + + ;; framerate, coded_side_data, nb_coded_side_data komen hierna, + ;; maar die heb je niet nodig. + ) + ;;;;;;; ffmpeg 7 and 8. (major versions 61 and 62). + (make-offsets (codec_type _AVMediaType) + (codec_id _AVCodecID) + + _int32 ;; codec_tag + _pointer ;; extradata + _int ;; extradata_size + + _pointer ;; coded_side_data + _int ;; nb_coded_side_data + + ;; AVCodecParameters.format + ;; audio: enum AVSampleFormat + (format _AVSampleFormat) + + _int64 ;; bit_rate + + (6 _int) ;; bits_per_coded_sample, bits_per_raw_sample, + ;; profile, level, width, height, + + (2 _AVRational) ;; sample_aspect_ratio, ramerate + + (7 _int) ;; field_order, color_range, + ;; color_primaries, color_trc, + ;; color_space, chroma_location, + ;; video_delay + + (ch_layout _AVChannelLayout) ;; ch_layout + (sample_rate _int)) ;; sample_rate + ) ) + (define (avcodec-pars-codec_id s) (AVCodecParameters-codec_id s)) @@ -197,29 +334,61 @@ (def-cstruct _AVFrame (data nb_samples sample_rate best_effort_timestamp) - (make-offsets - (data _pointer) - (7 _pointer) ; data - (8 _int) ; linesize - _pointer ; extended-data - (2 _int) ; width, height - (nb_samples _int) ; nb_samples - (2 _int) ; format / enum Picturetype - _AVRational ; sample_aspect_ratio; - (2 _int64) ; pts / pkt_dts - _AVRational ; time_base - _int ; quality - _pointer ; opaque - _int ; repeat_pict - (sample_rate _int); sample_rate - (8 _pointer) ; AVBufferRef *buf[AV_NUM_DATA_POINTERS]; - _pointer ; AVBufferRef **extended_buf; - _int ; int nb_extended_buf; - _pointer ; AVFrameSideData **side_data; - _int ; nb_side_data; - (6 _int) ; flags / color_range / color_primaries / color_trc / colorspace / chroma_location - (best_effort_timestamp _int64) ; best_effort_timestamp - )) + (if (= avutil-version-major 58) + ;;; avutil 58 (ffmpeg 6.x) + (make-offsets + (data _pointer) + (7 _pointer) ; data + (8 _int) ; linesize + _pointer ; extended-data + (2 _int) ; width, height + (nb_samples _int) ; nb_samples + (3 _int) ; format / key_frame / enum Picturetype ;;; deprecated FRAME_KEY + _AVRational ; sample_aspect_ratio; + (2 _int64) ; pts / pkt_dts + _AVRational ; time_base + (2 _int) ; coded_picture_number / display_picture_number ;; PICTURE_NUMBER + _int ; quality + _pointer ; opaque + _int ; repeat_pict + (2 _int) ; interlaced_frame / top_field_first ;; INTERLACED_FRAME + _int64 ; reordered_opaque ;; REORDERED_OPAQUE + (sample_rate _int); sample_rate + _int64 ; channel_layout ;; OLD_CHANNEL_LAYOUT + (8 _pointer) ; AVBufferRef *buf[AV_NUM_DATA_POINTERS]; + _pointer ; AVBufferRef **extended_buf; + _int ; int nb_extended_buf; + _pointer ; AVFrameSideData **side_data; + _int ; nb_side_data; + (6 _int) ; flags / color_range / color_primaries / color_trc / colorspace / chroma_location + (best_effort_timestamp _int64) ; best_effort_timestamp + ) + ;;; ffmpeg 7, 8 - avutil 59 and 60. + (make-offsets + (data _pointer) + (7 _pointer) ; data + (8 _int) ; linesize + _pointer ; extended-data + (2 _int) ; width, height + (nb_samples _int) ; nb_samples + (2 _int) ; format / enum Picturetype + _AVRational ; sample_aspect_ratio; + (2 _int64) ; pts / pkt_dts + _AVRational ; time_base + _int ; quality + _pointer ; opaque + _int ; repeat_pict + (sample_rate _int); sample_rate + (8 _pointer) ; AVBufferRef *buf[AV_NUM_DATA_POINTERS]; + _pointer ; AVBufferRef **extended_buf; + _int ; int nb_extended_buf; + _pointer ; AVFrameSideData **side_data; + _int ; nb_side_data; + (6 _int) ; flags / color_range / color_primaries / color_trc / colorspace / chroma_location + (best_effort_timestamp _int64) ; best_effort_timestamp + ) + ) + ) (define (avframe-data frame) ;; swr_convert wil const uint8_t **. @@ -254,35 +423,7 @@ (define (avpacket-stream-index pkt) (AVPacket-stream_index pkt)) -;;;; Needed functions for audio decoder - -(define libavutil (get-lib (case (system-type 'os) - [(windows) '("avutil-60")] - [else '("avutil" "libavutil")]) '(#f))) - - -(define libswresample (get-lib (case (system-type 'os) - [(windows) '("swresample-6")] - [else '("swresample" "libswresample")]) '(#f))) - -(define libavcodec (get-lib (case (system-type 'os) - [(windows) '("avcodec-62")] - [else '("avcodec" "libavcodec")]) '(#f))) - -(define libavformat (get-lib (case (system-type 'os) - [(windows) '("avformat-62")] - [else '("avformat" "libavformat")]) '(#f))) - - -(define-ffi-definer def-avutil libavutil #:default-make-fail make-not-available) -(define-ffi-definer def-swresample libswresample #:default-make-fail make-not-available) -(define-ffi-definer def-avcodec libavcodec #:default-make-fail make-not-available) -(define-ffi-definer def-avformat libavformat #:default-make-fail make-not-available) - -(def-avutil avutil_version (_fun -> _uint)) -(def-avcodec avcodec_version (_fun -> _uint)) -(def-avformat avformat_version (_fun -> _uint)) -(def-swresample swresample_version (_fun -> _uint)) +;;;;; Now import the needed functions (def-avcodec avcodec_free_context/raw (_fun (_ptr io _AVCodecContext) -> (p : _AVCodecContext) @@ -457,60 +598,6 @@ (def-swresample swr_close (_fun _SwrContext -> _void)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Version check -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(define avutil-version-major (quotient (avutil_version) 65536)) -(define avcodec-version-major (quotient (avcodec_version) 65536)) -(define avformat-version-major (quotient (avformat_version) 65536)) -(define swresample-version-major (quotient (swresample_version) 65536)) - -(define (ffmpeg-version lib) - (let ((v (λ (v) (list (quotient v 65536) (remainder (quotient v 256) 256) (remainder v 256))))) - (cond ((eq? lib 'avutil) (v (avutil_version))) - ((eq? lib 'avcodec) (v (avcodec_version))) - ((eq? lib 'avformat) (v (avformat_version))) - ((or (eq? lib 'swr) - (eq? lib 'swresample)) (v (swresample_version))) - (else (error (format "Unknown library '~a" lib))) - ) - ) - ) - -(define (ffmpeg-version-string lib) - (apply format (cons "~a.~a.~a" (ffmpeg-version lib)))) - -;; Support ffmpeg 6, 7 and 8 - -(define-syntax check-support - (syntax-rules () - ((_ lib version-hash) - (let ((from (car (hash-ref version-hash lib))) - (until (cadr (hash-ref version-hash lib)))) - (let ((major-version (car (ffmpeg-version lib)))) - (cond - ((or (< major-version from) (> major-version until)) - (error - (format "Unsupported major version of ffmpeg library ~a: ~a (~a).\nSupported range: ~a - ~a" - 'lib major-version (ffmpeg-version-string lib) from until))) - (else - (info-sound "Supported ffmpeg library ~a - version ~a between ~a and ~a" - lib (ffmpeg-version-string lib) from until) - ) - ) - ) - ) - ) - ) - ) - -(check-support 'avutil valid-ffmpeg-versions) -(check-support 'avcodec valid-ffmpeg-versions) -(check-support 'avformat valid-ffmpeg-versions) -(check-support 'swresample valid-ffmpeg-versions) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/libao-async-ffi-racket.rkt b/libao-async-ffi-racket.rkt index 88400ca..39fdf0d 100644 --- a/libao-async-ffi-racket.rkt +++ b/libao-async-ffi-racket.rkt @@ -756,9 +756,9 @@ (let ((ao-size buf-size) (ao-mem au-buf)) - (let ((m (convert-req-bits-to-dev-bits h mem info))) + (let ((m (convert-req-bits-to-dev-bits h au-buf info))) (when (eq? (cadr m) #t) - (reuse-buf h mem) + (reuse-buf h au-buf) (set! ao-mem (car m)) (set! ao-size (mem-size ao-mem))))