Skip to content

Commit 656f220

Browse files
committed
Updated frame to include images
1 parent f7b3046 commit 656f220

File tree

13 files changed

+599
-233
lines changed

13 files changed

+599
-233
lines changed

codec.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package media
2+
3+
import (
4+
"encoding/json"
5+
6+
// Packages
7+
ff "github.com/mutablelogic/go-media/sys/ffmpeg61"
8+
)
9+
10+
////////////////////////////////////////////////////////////////////////////////
11+
// TYPES
12+
13+
type codec struct {
14+
ctx *ff.AVCodec
15+
}
16+
17+
var _ Codec = (*codec)(nil)
18+
19+
////////////////////////////////////////////////////////////////////////////////
20+
// LIFECYCLE
21+
22+
func newCodec(ctx *ff.AVCodec) *codec {
23+
return &codec{ctx}
24+
}
25+
26+
////////////////////////////////////////////////////////////////////////////////
27+
// STRINGIFY
28+
29+
type jsonCodec struct {
30+
Name string `json:"name"`
31+
Description string `json:"description,omitempty"`
32+
Type string `json:"type"`
33+
}
34+
35+
func (codec *codec) MarshalJSON() ([]byte, error) {
36+
return json.Marshal(&jsonCodec{
37+
Name: codec.Name(),
38+
Description: codec.Description(),
39+
Type: codec.Type().String(),
40+
})
41+
}
42+
43+
////////////////////////////////////////////////////////////////////////////////
44+
// PUBLIC METHODS
45+
46+
func (codec *codec) Name() string {
47+
return codec.ctx.Name()
48+
}
49+
50+
// Return the codec description
51+
func (codec *codec) Description() string {
52+
return codec.ctx.LongName()
53+
}
54+
55+
// Return the codec type (AUDIO, VIDEO, SUBTITLE, DATA, INPUT, OUTPUT)
56+
func (codec *codec) Type() MediaType {
57+
t := NONE
58+
switch codec.ctx.Type() {
59+
case ff.AVMEDIA_TYPE_AUDIO:
60+
t = AUDIO
61+
case ff.AVMEDIA_TYPE_VIDEO:
62+
t = VIDEO
63+
case ff.AVMEDIA_TYPE_SUBTITLE:
64+
t = SUBTITLE
65+
default:
66+
t = DATA
67+
}
68+
if ff.AVCodec_is_encoder(codec.ctx) {
69+
t |= OUTPUT
70+
}
71+
if ff.AVCodec_is_decoder(codec.ctx) {
72+
t |= INPUT
73+
}
74+
return t
75+
}
76+
77+
// TODO: Supported sample formats, channel layouts, pixel formats, etc.

decoder.go

Lines changed: 36 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"io"
8+
"syscall"
89

910
// Packages
1011
ff "github.com/mutablelogic/go-media/sys/ffmpeg61"
@@ -161,122 +162,23 @@ func (d *decoder) close() error {
161162
// PUBLIC METHODS
162163

163164
func (d *demuxer) Demux(ctx context.Context, fn DecoderFunc) error {
164-
// If the decoder is nil then set it to default - which is to send the
165-
// packet to the appropriate decoder
166165
if fn == nil {
167-
fn = func(packet Packet) error {
168-
fmt.Println("TODO", packet)
169-
return nil
170-
}
171-
}
172-
173-
// Allocate a packet
174-
packet := ff.AVCodec_packet_alloc()
175-
if packet == nil {
176-
return errors.New("failed to allocate packet")
177-
}
178-
defer ff.AVCodec_packet_free(packet)
179-
180-
// Read packets
181-
FOR_LOOP:
182-
for {
183-
select {
184-
case <-ctx.Done():
185-
break FOR_LOOP
186-
default:
187-
if err := ff.AVFormat_read_frame(d.input, packet); errors.Is(err, io.EOF) {
188-
break FOR_LOOP
189-
} else if err != nil {
190-
return err
191-
}
192-
stream := packet.StreamIndex()
193-
if decoder := d.decoders[stream]; decoder != nil {
194-
if err := decoder.decode(fn, packet); errors.Is(err, io.EOF) {
195-
break FOR_LOOP
196-
} else if err != nil {
197-
return err
198-
}
199-
}
200-
// Unreference the packet
201-
ff.AVCodec_packet_unref(packet)
202-
}
166+
return errors.New("no decoder function provided")
203167
}
204-
205-
// Flush the decoders
206-
for _, decoder := range d.decoders {
207-
if err := decoder.decode(fn, nil); err != nil {
208-
return err
209-
}
210-
}
211-
212-
// Return the context error - will be cancelled, perhaps, or nil if the
213-
// demuxer finished successfully without cancellation
214-
return ctx.Err()
168+
return d.demux(ctx, fn, nil)
215169
}
216170

217-
func (d *demuxer) Decode(context.Context, FrameFunc) error {
218-
// TODO
219-
return errors.New("not implemented")
171+
func (d *demuxer) Decode(ctx context.Context, fn FrameFunc) error {
172+
if fn == nil {
173+
return errors.New("no decoder function provided")
174+
}
175+
return d.demux(ctx, nil, fn)
220176
}
221177

222178
////////////////////////////////////////////////////////////////////////////
223179
// PRIVATE METHODS
224180

225-
func (d *decoder) decode(fn DecoderFunc, packet *ff.AVPacket) error {
226-
// Send the packet to the user defined packet function or
227-
// to the default version
228-
return fn(newPacket(packet))
229-
}
230-
231-
/*
232-
// Get the codec
233-
stream.
234-
235-
// Find the decoder for the stream
236-
dec := ff.AVCodec_find_decoder(codec.ID())
237-
if dec == nil {
238-
return nil, fmt.Errorf("failed to find decoder for codec %q", codec.Name())
239-
}
240-
241-
// Allocate a codec context for the decoder
242-
dec_ctx := ff.AVCodec_alloc_context(dec)
243-
if dec_ctx == nil {
244-
return nil, fmt.Errorf("failed to allocate codec context for codec %q", codec.Name())
245-
}
246-
247-
// Create a frame for encoding - after resampling and resizing
248-
if frame := ff.AVUtil_frame_alloc(); frame == nil {
249-
return nil, errors.New("failed to allocate frame")
250-
} else {
251-
decoder.frame = frame
252-
}
253-
254-
// Return success
255-
return decoder, nil
256-
}
257-
258-
// Close the demuxer
259-
func (d *demuxer) close() error {
260-
261-
}
262-
263-
// Close the decoder
264-
func (d *decoder) close() error {
265-
266-
}
267-
268-
// Demultiplex streams from the reader
269-
func (d *demuxer) Demux(ctx context.Context, fn DecoderFunc) error {
270-
// If the decoder is nil then set it to default
271-
if fn == nil {
272-
fn = func(packet Packet) error {
273-
if packet == nil {
274-
return d.decodePacket(nil)
275-
}
276-
return d.decodePacket(packet.(*ff.AVPacket))
277-
}
278-
}
279-
181+
func (d *demuxer) demux(ctx context.Context, demuxfn DecoderFunc, framefn FrameFunc) error {
280182
// Allocate a packet
281183
packet := ff.AVCodec_packet_alloc()
282184
if packet == nil {
@@ -292,13 +194,13 @@ FOR_LOOP:
292194
break FOR_LOOP
293195
default:
294196
if err := ff.AVFormat_read_frame(d.input, packet); errors.Is(err, io.EOF) {
295-
break
197+
break FOR_LOOP
296198
} else if err != nil {
297199
return err
298200
}
299201
stream := packet.StreamIndex()
300202
if decoder := d.decoders[stream]; decoder != nil {
301-
if err := decoder.decode(fn, packet); errors.Is(err, io.EOF) {
203+
if err := decoder.decode(packet, demuxfn, framefn); errors.Is(err, io.EOF) {
302204
break FOR_LOOP
303205
} else if err != nil {
304206
return err
@@ -311,23 +213,23 @@ FOR_LOOP:
311213

312214
// Flush the decoders
313215
for _, decoder := range d.decoders {
314-
if err := decoder.decode(fn, nil); err != nil {
216+
if err := decoder.decode(nil, demuxfn, framefn); err != nil {
315217
return err
316218
}
317219
}
318220

319-
// Return success
320-
return nil
221+
// Return the context error - will be cancelled, perhaps, or nil if the
222+
// demuxer finished successfully without cancellation
223+
return ctx.Err()
321224
}
322225

323-
func (d *decoder) decode(fn DecoderFunc, packet *ff.AVPacket) error {
324-
// Send the packet to the user defined packet function or
325-
// to the default version
326-
return fn(packet)
327-
}
226+
func (d *decoder) decode(packet *ff.AVPacket, demuxfn DecoderFunc, framefn FrameFunc) error {
227+
if demuxfn != nil {
228+
// Send the packet to the user defined packet function
229+
return demuxfn(newPacket(packet))
230+
}
328231

329-
func (d *demuxer) decodePacket(packet *ff.AVPacket) error {
330-
// Submit the packet to the decoder. If nil then flush
232+
// Submit the packet to the decoder (nil packet will flush the decoder)
331233
if err := ff.AVCodec_send_packet(d.codec, packet); err != nil {
332234
return err
333235
}
@@ -341,62 +243,16 @@ func (d *demuxer) decodePacket(packet *ff.AVPacket) error {
341243
return err
342244
}
343245

344-
fmt.Println("TODO", d.frame)
345-
}
346-
return nil
347-
}
348-
349-
// Resample or resize the frame, then pass back
350-
/*
351-
if frame, err := d.re(d.frame); err != nil {
352-
return err
353-
} else if err := fn(frame); errors.Is(err, io.EOF) {
354-
// End early
355-
break
356-
} else if err != nil {
357-
return err
358-
}*/
359-
360-
// Flush
361-
/*
362-
if frame, err := d.re(nil); err != nil {
363-
return err
364-
} else if frame == nil {
365-
// NOOP
366-
} else if err := fn(frame); errors.Is(err, io.EOF) {
367-
// NOOP
368-
} else if err != nil {
369-
return err
370-
}
371-
*/
372-
373-
/*
374-
375-
// Return a function to decode packets from the streams into frames
376-
func (r *reader) Decode(fn FrameFunc) DecoderFunc {
377-
return func(codec Decoder, packet Packet) error {
378-
if packet != nil {
379-
// Submit the packet to the decoder
380-
if err := ff.AVCodec_send_packet(codec.(*decoder).codec, packet.(*ff.AVPacket)); err != nil {
381-
return err
382-
}
383-
} else {
384-
// Flush remaining frames
385-
if err := ff.AVCodec_send_packet(codec.(*decoder).codec, nil); err != nil {
386-
return err
387-
}
246+
// Pass the frame
247+
if err := framefn(newFrame(d.frame)); errors.Is(err, io.EOF) {
248+
// End early
249+
break
250+
} else if err != nil {
251+
return err
388252
}
389253

390-
// get all the available frames from the decoder
391-
for {
392-
if err := ff.AVCodec_receive_frame(codec.(*decoder).codec, r.frame); errors.Is(err, syscall.EAGAIN) || errors.Is(err, io.EOF) {
393-
// Finished decoding packet or EOF
394-
break
395-
} else if err != nil {
396-
return err
397-
}
398-
399-
// Resample or resize the frame, then pass back
254+
// Resample or resize the frame, then pass back
255+
/*
400256
if frame, err := codec.(*decoder).re(r.frame); err != nil {
401257
return err
402258
} else if err := fn(frame); errors.Is(err, io.EOF) {
@@ -405,9 +261,11 @@ func (r *reader) Decode(fn FrameFunc) DecoderFunc {
405261
} else if err != nil {
406262
return err
407263
}
408-
}
264+
*/
265+
}
409266

410-
// Flush
267+
// TODO: Flush
268+
/*
411269
if frame, err := codec.(*decoder).re(nil); err != nil {
412270
return err
413271
} else if frame == nil {
@@ -416,10 +274,8 @@ func (r *reader) Decode(fn FrameFunc) DecoderFunc {
416274
// NOOP
417275
} else if err != nil {
418276
return err
419-
}
277+
}*/
420278

421-
// Success
422-
return nil
423-
}
279+
// Return success
280+
return nil
424281
}
425-
*/

0 commit comments

Comments
 (0)