-
Notifications
You must be signed in to change notification settings - Fork 0
/
ffmpeg.rkt
159 lines (153 loc) · 6.57 KB
/
ffmpeg.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#lang at-exp racket/gui
(require racket/generator
ffi/unsafe
ffi/unsafe/define
ffi/vector
ffi/cvector
data/gvector
racket/match
opengl
opengl/util
portaudio
video/private/ffmpeg
video/private/ffmpeg-pipeline
video/private/packetqueue
video/private/video-canvas)
(define out-width 1920)
(define out-height 1080)
(define (alloc-picture fmt w h)
(define frame (av-frame-alloc))
(set-av-frame-format/video! frame fmt)
(set-av-frame-width! frame w)
(set-av-frame-height! frame h)
(av-frame-set-color-range frame 'mpeg)
(av-frame-get-buffer frame 32)
frame)
;; Video
(define frame (av-frame-alloc))
(define frame-rgb (alloc-picture 'yuv420p out-width out-height))
;(define buff #f)
(define sws #f)
(define (encode-proc mode obj data queue-ctx)
(match obj
[(struct* codec-obj ([type type]
[stream stream]
[codec-context ctx]
[codec codec]
[id id]
[next-pts next-pts]))
(match* (type mode)
[('video 'init)
(set-avcodec-context-codec-id! ctx id)
(set-avcodec-context-bit-rate! ctx 400000)
(set-avcodec-context-width! ctx out-width)
(set-avcodec-context-height! ctx out-height)
(set-avcodec-context-time-base! ctx 1/25)
(set-avstream-time-base! stream 1/25)
(set-avcodec-context-gop-size! ctx 12)
(set-avcodec-context-pix-fmt! ctx 'yuv420p)
(set-avcodec-context-color-range! ctx 'mpeg)
(when (eq? id 'mpeg2video)
(set-avcodec-context-max-b-frames! ctx 2))
(when (eq? id 'mpeg1video)
(set-avcodec-context-mb-decision! ctx 2))
#|
(define num-bytes
(av-image-get-buffer-size 'yuv420p
(avcodec-context-width ctx)
(avcodec-context-height ctx)
32))
(define buff (av-malloc num-bytes _uint8))
(av-image-fill-arrays (av-frame-data frame-rgb)
(av-frame-linesize frame-rgb)
buff ;(array-ptr buff)
'yuv420p
(avcodec-context-width ctx)
(avcodec-context-height ctx)
1)
|#
(set! sws
(sws-getContext (avcodec-context-width queue-ctx)
(avcodec-context-height queue-ctx)
(avcodec-context-pix-fmt queue-ctx)
(avcodec-context-width ctx)
(avcodec-context-height ctx)
(avcodec-context-pix-fmt ctx)
'bicubic
#f #f #f))
]
[('audio 'init)
(set-avcodec-context-sample-fmt!
ctx (if (avcodec-sample-fmts codec)
(ptr-ref (avcodec-sample-fmts codec) _avsample-format)
'fltp))
(set-avcodec-context-bit-rate! ctx 64000)
(define supported-samplerates (avcodec-supported-samplerates codec))
(set-avcodec-context-sample-rate!
ctx
(if supported-samplerates
(let loop ([rate #f]
[offset 0])
(define new-rate (ptr-ref (avcodec-supported-samplerates codec)
_int
offset))
(cond [(= new-rate 44100) new-rate]
[(= new-rate 0) (or rate 44100)]
[else (loop (or rate new-rate) (add1 offset))]))
44100))
(define supported-layouts (avcodec-channel-layouts codec))
(set-avcodec-context-channel-layout!
ctx
(if supported-layouts
(let loop ([layout #f]
[offset 0])
(define new-layout (ptr-ref (avcodec-channel-layouts codec)
offset))
(cond [(set-member? new-layout 'stereo) 'stereo]
[(set-empty? new-layout) (or layout 'stereo)]
[else (loop (or layout new-layout) (add1 offset))]))
'stereo))
(set-avcodec-context-channels!
ctx (av-get-channel-layout-nb-channels (avcodec-context-channel-layout ctx)))
(set-avstream-time-base! stream (/ 1 (avcodec-context-sample-rate ctx)))]
[('video 'write)
(cond
[(eof-object? data) data]
[else
(avcodec-send-packet queue-ctx data)
(avcodec-receive-frame queue-ctx frame)
(av-frame-make-writable frame-rgb)
(sws-scale sws
(array-ptr (av-frame-data frame))
(array-ptr (av-frame-linesize frame))
0
(avcodec-context-height queue-ctx)
(array-ptr (av-frame-data frame-rgb))
(array-ptr (av-frame-linesize frame-rgb)))
(av-packet-unref data)
(set-av-frame-pts! frame-rgb next-pts)
(set-codec-obj-next-pts!
obj (add1 (codec-obj-next-pts obj)))
(avcodec-send-frame ctx frame-rgb)
(let loop ()
(with-handlers ([exn:ffmpeg:again? (λ (e) '())])
(cons (avcodec-receive-packet ctx) (loop))))])]
[(_ _)
data])]))
(link (λ () (file->stream-bundle "/Users/leif/demo2.mp4"))
(λ (in-bundle) (bundle-for-file "/Users/leif/test.mp4"
(mk-stream-bundle
#:locked? #f
#:streams
(for/list ([i (stream-bundle-streams in-bundle)])
(cond
[(eq? (codec-obj-type i) 'video)
(mk-codec-obj #:callback-data (codec-obj-callback-data i)
#:type 'video
#:id 'h264)]
[(eq? (codec-obj-type i) 'audio)
i
#;(mk-codec-obj #:callback-data (codec-obj-callback-data i)
#:type 'audio
#:id 'aac)])))))
#:out-callback encode-proc)