Skip to content

Commit 8509004

Browse files
committed
Updates to remove framerate
1 parent 8879890 commit 8509004

File tree

10 files changed

+43
-14
lines changed

10 files changed

+43
-14
lines changed

pkg/ffmpeg/encoder.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func NewEncoder(ctx *ff.AVFormatContext, stream int, par *Par) (*Encoder, error)
7676
ff.AVCodec_free_context(encoder.ctx)
7777
return nil, ErrInternalAppError.With("could not allocate stream")
7878
} else {
79+
// Set stream identifier and timebase from parameters
7980
streamctx.SetId(stream)
8081
encoder.stream = streamctx
8182
}
@@ -95,6 +96,8 @@ func NewEncoder(ctx *ff.AVFormatContext, stream int, par *Par) (*Encoder, error)
9596
if err := ff.AVCodec_parameters_from_context(encoder.stream.CodecPar(), encoder.ctx); err != nil {
9697
ff.AVCodec_free_context(encoder.ctx)
9798
return nil, err
99+
} else {
100+
encoder.stream.SetTimeBase(par.timebase)
98101
}
99102

100103
// Create a packet
@@ -164,6 +167,7 @@ func (e *Encoder) Encode(frame *Frame, fn EncoderPacketFn) error {
164167
// Return the codec parameters
165168
func (e *Encoder) Par() *Par {
166169
par := new(Par)
170+
par.timebase = e.stream.TimeBase()
167171
if err := ff.AVCodec_parameters_from_context(&par.AVCodecParameters, e.ctx); err != nil {
168172
return nil
169173
} else {

pkg/ffmpeg/frame.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func NewFrame(par *Par) (*Frame, error) {
5353
frame.SetWidth(par.Width())
5454
frame.SetHeight(par.Height())
5555
frame.SetSampleAspectRatio(par.SampleAspectRatio())
56-
frame.SetTimeBase(par.timebase)
56+
frame.SetTimeBase(par.timebase) // Also sets framerate
5757
default:
5858
ff.AVUtil_frame_free(frame)
5959
return nil, errors.New("invalid codec type")

pkg/ffmpeg/opts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ffmpeg
22

33
import (
44
// Package imports
5+
56
ffmpeg "github.com/mutablelogic/go-media/sys/ffmpeg61"
67

78
// Namespace imports

pkg/ffmpeg/par.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ type Par struct {
2121
timebase ff.AVRational
2222
}
2323

24+
type jsonPar struct {
25+
Par ff.AVCodecParameters `json:"parameters"`
26+
Timebase ff.AVRational `json:"timebase"`
27+
Framerate float64 `json:"framerate,omitempty"`
28+
}
29+
2430
///////////////////////////////////////////////////////////////////////////////
2531
// LIFECYCLE
2632

@@ -76,13 +82,15 @@ func NewVideoPar(pixfmt string, size string, framerate float64) (*Par, error) {
7682
// Frame rate
7783
if framerate < 0 {
7884
return nil, ErrBadParameter.Withf("negative framerate %v", framerate)
79-
} else {
85+
} else if framerate > 0 {
8086
par.timebase = ff.AVUtil_rational_invert(ff.AVUtil_rational_d2q(framerate, 1<<24))
8187
}
8288

8389
// Set default sample aspect ratio
8490
par.SetSampleAspectRatio(ff.AVUtil_rational(1, 1))
8591

92+
// TODO: Set profile, codec and bitrate and any other parameters
93+
8694
/* TODO
8795
c->gop_size = 12; // emit one intra frame every twelve frames at most
8896
c->pix_fmt = STREAM_PIX_FMT;
@@ -122,12 +130,20 @@ func VideoPar(pixfmt string, size string, framerate float64) *Par {
122130
// STRINGIFY
123131

124132
func (ctx *Par) MarshalJSON() ([]byte, error) {
125-
return json.Marshal(ctx.AVCodecParameters)
133+
return json.Marshal(jsonPar{
134+
Par: ctx.AVCodecParameters,
135+
Timebase: ctx.timebase,
136+
Framerate: ctx.FrameRate(),
137+
})
126138
}
127139

128140
func (ctx *Par) String() string {
129-
data, _ := json.MarshalIndent(ctx, "", " ")
130-
return string(data)
141+
data, err := json.MarshalIndent(ctx, "", " ")
142+
if err != nil {
143+
return err.Error()
144+
} else {
145+
return string(data)
146+
}
131147
}
132148

133149
///////////////////////////////////////////////////////////////////////////////
@@ -153,8 +169,10 @@ func (ctx *Par) WidthHeight() string {
153169
}
154170

155171
func (ctx *Par) FrameRate() float64 {
156-
framerate := ff.AVUtil_rational_invert(ctx.timebase)
157-
return ff.AVUtil_rational_q2d(framerate)
172+
if ctx.timebase.Num() == 0 || ctx.timebase.Den() == 0 {
173+
return 0
174+
}
175+
return ff.AVUtil_rational_q2d(ff.AVUtil_rational_invert(ctx.timebase))
158176
}
159177

160178
func (ctx *Par) ValidateFromCodec(codec *ff.AVCodec) error {
@@ -183,6 +201,7 @@ func (ctx *Par) CopyToCodecContext(codec *ff.AVCodecContext) error {
183201
func (ctx *Par) copyAudioCodec(codec *ff.AVCodecContext) error {
184202
codec.SetSampleFormat(ctx.SampleFormat())
185203
codec.SetSampleRate(ctx.Samplerate())
204+
codec.SetTimeBase(ff.AVUtil_rational(1, ctx.Samplerate()))
186205
if err := codec.SetChannelLayout(ctx.ChannelLayout()); err != nil {
187206
return err
188207
}

pkg/ffmpeg/reader.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ func (r *Reader) mapStreams(fn DecoderMapFunc) (decoderMap, error) {
346346
// Get decoder parameters and map to a decoder
347347
par, err := fn(stream_index, &Par{
348348
AVCodecParameters: *stream.CodecPar(),
349+
timebase: stream.TimeBase(),
349350
})
350351
if err != nil {
351352
result = errors.Join(result, err)

pkg/ffmpeg/writer_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,17 @@ func Test_writer_003(t *testing.T) {
137137
frame := video.Frame()
138138
if frame.Ts() >= duration {
139139
return nil, io.EOF
140-
} else {
141-
t.Log("Frame", stream, "=>", frame.Ts())
142-
return frame, nil
143140
}
141+
if !assert.NotEqual(ffmpeg.TS_UNDEFINED, frame.Ts()) {
142+
t.FailNow()
143+
}
144+
t.Log("Frame", stream, "=>", frame.Ts())
145+
return frame, nil
144146
}, func(packet *ffmpeg.Packet) error {
145147
if packet != nil {
148+
if !assert.NotEqual(ffmpeg.TS_UNDEFINED, packet.Ts()) {
149+
t.FailNow()
150+
}
146151
t.Log("Packet", packet.Ts())
147152
}
148153
return writer.Write(packet)

pkg/generator/yuv420p.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ func NewYUV420P(par *ffmpeg.Par) (*yuv420p, error) {
3333
} else if par.PixelFormat() != ff.AV_PIX_FMT_YUV420P {
3434
return nil, errors.New("invalid pixel format, only yuv420p is supported")
3535
}
36-
framerate := par.FrameRate()
37-
if framerate <= 0 {
36+
if framerate := par.FrameRate(); framerate <= 0 {
3837
return nil, errors.New("invalid framerate")
3938
}
4039

sys/ffmpeg61/avcodec.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ func (ctx *AVCodecContext) MarshalJSON() ([]byte, error) {
186186
Height: int(ctx.height),
187187
SampleAspectRatio: AVRational(ctx.sample_aspect_ratio),
188188
Framerate: AVRational(ctx.framerate),
189+
TimeBase: (AVRational)(ctx.time_base),
189190
})
190191
case C.AVMEDIA_TYPE_AUDIO:
191192
return json.Marshal(jsonAVCodecContext{

sys/ffmpeg61/avcodec_parameters.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ type jsonAVCodecParameterVideo struct {
3030
Width int `json:"width"`
3131
Height int `json:"height"`
3232
SampleAspectRatio AVRational `json:"sample_aspect_ratio,omitempty"`
33-
Framerate AVRational `json:"framerate,omitempty"`
3433
}
3534

3635
type jsonAVCodecParameters struct {

sys/ffmpeg61/avformat_avio_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func Test_avio_001(t *testing.T) {
5555
if n == AVERROR_EOF {
5656
break
5757
}
58-
fmt.Println("N=", n, string(buf[:n]))
58+
t.Log("N=", n, string(buf[:n]))
5959
}
6060

6161
// Free the context

0 commit comments

Comments
 (0)