@@ -18,20 +18,25 @@ import (
18
18
19
19
type Par struct {
20
20
ff.AVCodecParameters
21
+ opts []media.Metadata
21
22
timebase ff.AVRational
22
23
}
23
24
24
25
type jsonPar struct {
25
- Par ff.AVCodecParameters `json:"parameters"`
26
- Timebase ff.AVRational `json:"timebase"`
26
+ ff.AVCodecParameters
27
+ Timebase ff.AVRational `json:"timebase"`
28
+ Opts []media.Metadata `json:"options"`
27
29
}
28
30
29
31
///////////////////////////////////////////////////////////////////////////////
30
32
// LIFECYCLE
31
33
32
- func NewAudioPar (samplefmt string , channellayout string , samplerate int ) (* Par , error ) {
34
+ // Create new audio parameters with sample format, channel layout and sample rate
35
+ // plus any additional options which is used for creating a stream
36
+ func NewAudioPar (samplefmt string , channellayout string , samplerate int , opts ... media.Metadata ) (* Par , error ) {
33
37
par := new (Par )
34
38
par .SetCodecType (ff .AVMEDIA_TYPE_AUDIO )
39
+ par .opts = opts
35
40
36
41
// Sample Format
37
42
if samplefmt_ := ff .AVUtil_get_sample_fmt (samplefmt ); samplefmt_ == ff .AV_SAMPLE_FMT_NONE {
@@ -59,9 +64,12 @@ func NewAudioPar(samplefmt string, channellayout string, samplerate int) (*Par,
59
64
return par , nil
60
65
}
61
66
62
- func NewVideoPar (pixfmt string , size string , framerate float64 ) (* Par , error ) {
67
+ // Create new video parameters with pixel format, frame size, framerate
68
+ // plus any additional options which is used for creating a stream
69
+ func NewVideoPar (pixfmt string , size string , framerate float64 , opts ... media.Metadata ) (* Par , error ) {
63
70
par := new (Par )
64
71
par .SetCodecType (ff .AVMEDIA_TYPE_VIDEO )
72
+ par .opts = opts
65
73
66
74
// Pixel Format
67
75
if pixfmt_ := ff .AVUtil_get_pix_fmt (pixfmt ); pixfmt_ == ff .AV_PIX_FMT_NONE {
@@ -88,37 +96,22 @@ func NewVideoPar(pixfmt string, size string, framerate float64) (*Par, error) {
88
96
// Set default sample aspect ratio
89
97
par .SetSampleAspectRatio (ff .AVUtil_rational (1 , 1 ))
90
98
91
- // TODO: Set profile, codec and bitrate and any other parameters
92
-
93
- /* TODO
94
- c->gop_size = 12; // emit one intra frame every twelve frames at most
95
- c->pix_fmt = STREAM_PIX_FMT;
96
- if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
97
- // just for testing, we also add B-frames
98
- c->max_b_frames = 2;
99
- }
100
- if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
101
- // Needed to avoid using macroblocks in which some coeffs overflow.
102
- // This does not happen with normal video, it just happens here as
103
- // the motion of the chroma plane does not match the luma plane.
104
- c->mb_decision = 2;
105
- }
106
- */
107
-
108
99
// Return success
109
100
return par , nil
110
101
}
111
102
112
- func AudioPar (samplefmt string , channellayout string , samplerate int ) * Par {
113
- if par , err := NewAudioPar (samplefmt , channellayout , samplerate ); err != nil {
103
+ // Create audio parameters. If there is an error, then this function will panic
104
+ func AudioPar (samplefmt string , channellayout string , samplerate int , opts ... media.Metadata ) * Par {
105
+ if par , err := NewAudioPar (samplefmt , channellayout , samplerate , opts ... ); err != nil {
114
106
panic (err )
115
107
} else {
116
108
return par
117
109
}
118
110
}
119
111
120
- func VideoPar (pixfmt string , size string , framerate float64 ) * Par {
121
- if par , err := NewVideoPar (pixfmt , size , framerate ); err != nil {
112
+ // Create video parameters. If there is an error, then this function will panic
113
+ func VideoPar (pixfmt string , size string , framerate float64 , opts ... media.Metadata ) * Par {
114
+ if par , err := NewVideoPar (pixfmt , size , framerate , opts ... ); err != nil {
122
115
panic (err )
123
116
} else {
124
117
return par
@@ -130,8 +123,9 @@ func VideoPar(pixfmt string, size string, framerate float64) *Par {
130
123
131
124
func (ctx * Par ) MarshalJSON () ([]byte , error ) {
132
125
return json .Marshal (jsonPar {
133
- Par : ctx .AVCodecParameters ,
134
- Timebase : ctx .timebase ,
126
+ AVCodecParameters : ctx .AVCodecParameters ,
127
+ Timebase : ctx .timebase ,
128
+ Opts : ctx .opts ,
135
129
})
136
130
}
137
131
@@ -196,6 +190,19 @@ func (ctx *Par) CopyToCodecContext(codec *ff.AVCodecContext) error {
196
190
///////////////////////////////////////////////////////////////////////////////
197
191
// PRIVATE METHODS
198
192
193
+ // Return options as a dictionary, which needs to be freed after use
194
+ // by the caller method
195
+ func (ctx * Par ) newOpts () * ff.AVDictionary {
196
+ dict := ff .AVUtil_dict_alloc ()
197
+ for _ , opt := range ctx .opts {
198
+ if err := ff .AVUtil_dict_set (dict , opt .Key (), opt .Value (), ff .AV_DICT_APPEND ); err != nil {
199
+ ff .AVUtil_dict_free (dict )
200
+ return nil
201
+ }
202
+ }
203
+ return dict
204
+ }
205
+
199
206
func (ctx * Par ) copyAudioCodec (codec * ff.AVCodecContext ) error {
200
207
codec .SetSampleFormat (ctx .SampleFormat ())
201
208
codec .SetSampleRate (ctx .Samplerate ())
0 commit comments