sylware / nyanmp (public) (License: AGPLv3) (since 2020-02-12) (hash sha1)
intended to become a collection of media players for gnu/linux based on ffmpeg, alsa, vulkan, x11, wayland, etc.
List of commits:
Subject Hash Author Date (UTC)
npa: tons of love 68a79110ca4a6f5bdb41ed90e421b6f46c1c1877 Sylvain BERTRAND 2020-11-06 15:20:13
npv: spurious unsigned 5b4e039ffd921438a37112f0b4108480366f4d6d Sylvain BERTRAND 2020-11-06 04:31:18
npv: backward discontinuity handling 0fc81a53996993992dd86a96a26afd2aab0ac366 Sylvain BERTRAND 2020-09-25 16:14:26
npv: more monotonic, more pts discontinuity 1ab37ad2a24ca8f9fbf6d51eac8f996bd2eefacf Sylvain BERTRAND 2020-09-25 01:34:41
npv: workaround a mesa bug (which leads to linux state corruption) 780e5bec0b90a9e931778cf68fec62a7c5241c13 Sylvain BERTRAND 2020-09-23 15:57:25
npv: fix filter time base handling, prepare discontinuity support 2b7347be805d17a2b6f06e276e897c51431b9c6c Sylvain BERTRAND 2020-09-22 17:38:46
npv: correct coarse sync of vulkan image acquisition a9b52940ff2d567dc6c26b28d86eab54f5876819 Sylvain BERTRAND 2020-09-20 22:00:32
npv: fix channel layout handling and a tad more 88f74f181a567d108874a936fe3d306d34cfefb7 Sylvain BERTRAND 2020-09-19 23:12:04
npv: dynamic audio filter configuration d8a0ff688ddb2abcde22c01a2ae52ea74e9f0f2f Sylvain BERTRAND 2020-09-19 20:54:04
npv:protection against tantrum of media audio 78589150b7c6f1f3cae49b4b4bc8b572c6d8e6b7 Sylvain BERTRAND 2020-09-18 15:26:17
npv/npa:finish to workaround null channel layout 314788563e01d7ffb364a1775ba68619ee3f6c5c Sylvain BERTRAND 2020-09-15 22:50:57
npv: handle empty channel layout 5b5794fc4d5300b671b684a2f41196f66bd1fc4a Sylvain BERTRAND 2020-09-15 22:11:07
npv: tidy mutex locking 1962092d9675f76604414086200e88f6c857346f Sylvain BERTRAND 2020-09-15 00:51:12
npv: less incorrect reprogramming of blits b319e79f4f1b79670f6eef754142cc65c891ad4b Sylvain BERTRAND 2020-09-12 15:14:27
npv:fix osd restoration 8c64f703eca6b8c54b4cb5c95231dd02aa394135 Sylvain BERTRAND 2020-08-29 20:36:12
npv:osd:solo compilation modulo a few warnings 7805bd8f34f913b1535cc81c5be2a3132bd7e0e5 Sylvain BERTRAND 2020-08-29 14:51:35
npv: cleanup and color component fix 44f294e1de96c7974740f1187ebdbe12204884ae Sylvain BERTRAND 2020-08-28 23:48:18
npv:osd:timer, will add more if pertinent 6d34403c2c49bfa6ccf8e7a72e35a69e6f0527c5 Sylvain BERTRAND 2020-08-28 22:47:18
npv/npa: document properly snd_pcm_drain behavior 510ca39ee6a9ac9fcd646484793b7556eaa5972f Sylvain BERTRAND 2020-08-26 17:36:29
npv:remove locale layout dependent key binds f69bbbe529045b4243ece8957c838cb1465352da Sylvain BERTRAND 2020-08-24 21:27:08
Commit 68a79110ca4a6f5bdb41ed90e421b6f46c1c1877 - npa: tons of love
Author: Sylvain BERTRAND
Author date (UTC): 2020-11-06 15:20
Committer name: Sylvain BERTRAND
Committer date (UTC): 2020-11-06 15:20
Parent(s): 5b4e039ffd921438a37112f0b4108480366f4d6d
Signing key:
Tree: 06c5ad8bf51b4bc5a520ed5a791a3f52fe52e87d
File Lines added Lines deleted
npa/TODO 1 7
npa/npa.c 741 419
File npa/TODO changed (mode: 100644) (index 70b2a25..c57e505)
1 1 not ordered: not ordered:
2 - port npv proper usage of filter time base
3 - port npv dynamic audio reconfiguration
4 - port npv initial ffmpeg audio parameter override code
5 - we were lied to: presentation/decoding timestamps from a demuxer can be
6 discontinuous without any warning.
7 - support dynamic re-configuration based on decoder output?
8 (the plumbing should be roughly in place for that)
2 - make the circular buffer size dynamic in order to increase buffering
File npa/npa.c changed (mode: 100644) (index 177f23b..141a136)
18 18 * cfg : ConFiGuration * cfg : ConFiGuration
19 19 * ctx : ConTeX * ctx : ConTeX
20 20 * dec : DECoder/DECoded * dec : DECoder/DECoded
21 * desc : DESCription
21 22 * dev : DEVice * dev : DEVice
22 23 * e : End (usually a pointer on the byte past the last valid byte) * e : End (usually a pointer on the byte past the last valid byte)
23 24 * eof : End Of File * eof : End Of File
 
26 27 * evt(s) : EVenT(S) * evt(s) : EVenT(S)
27 28 * err : ERRor * err : ERRor
28 29 * fd : File Descriptor * fd : File Descriptor
30 * ff : FFmpeg
29 31 * filt : FILTer * filt : FILTer
30 32 * fmt : ForMaT * fmt : ForMaT
31 33 * fr(s) : FRame(S) * fr(s) : FRame(S)
 
38 40 * nr : NumbeR * nr : NumbeR
39 41 * out : OUTput * out : OUTput
40 42 * pkt(s) : PacKeT(S) * pkt(s) : PacKeT(S)
43 * pts : Presentation TimeStamp
41 44 * rd : ReaD * rd : ReaD
42 45 * ref(s) : REFerence(S) * ref(s) : REFerence(S)
43 46 * s : Start * s : Start
 
59 62 * and/or similar cleanup: we have a virtual machine with a garbage collector, * and/or similar cleanup: we have a virtual machine with a garbage collector,
60 63 * it is linux. * it is linux.
61 64 * *
62 * we do presume we won't play more than 8 chans and ffmpeg chans layout will
65 * we do presume we won't play more than 8 chans and ff chans layout will
63 66 * fit alsa chans map * fit alsa chans map
64 67 * *
65 68 * XXX: we don't know how the alsa silence machinery works, then we use brutal * XXX: we don't know how the alsa silence machinery works, then we use brutal
 
88 91 #include <sys/epoll.h> #include <sys/epoll.h>
89 92 #include <sys/signalfd.h> #include <sys/signalfd.h>
90 93 #include <sys/timerfd.h> #include <sys/timerfd.h>
91 /* ffmpeg */
94 /* ff */
92 95 #include <libavformat/avformat.h> #include <libavformat/avformat.h>
93 96 #include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
94 97 #include <libavfilter/avfilter.h> #include <libavfilter/avfilter.h>
 
97 100 #include <libavutil/opt.h> #include <libavutil/opt.h>
98 101 /* alsa */ /* alsa */
99 102 #include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
103 /*============================================================================*/
104 /* namespaces -- START */
100 105 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
101 /* fix C */
106 /* fix C -- START */
102 107 #define u8 uint8_t #define u8 uint8_t
103 108 #define U8_MAX 255 #define U8_MAX 255
104 109 #define u32 uint32_t #define u32 uint32_t
 
110 115 #else #else
111 116 #error "unable to find the right atomic for a 8 bits byte, be sure to have __STDC_WANT_IEC_60559_BFP_EXT__ defined" #error "unable to find the right atomic for a 8 bits byte, be sure to have __STDC_WANT_IEC_60559_BFP_EXT__ defined"
112 117 #endif #endif
118 /* fix C -- END */
113 119 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
114
120 /* ff namespace -- START*/
121 #define AV_FR_FMT_NONE AV_SAMPLE_FMT_NONE
122 #define av_bufsink_get_frs av_buffersink_get_frame
123 #define av_bufsrc_add_frs_flags av_buffersrc_add_frame_flags
124 #define AV_BUFSRC_FLAG_KEEP_REF AV_BUFFERSRC_FLAG_KEEP_REF
125 #define AV_BUFSRC_FLAG_PUSH AV_BUFFERSRC_FLAG_PUSH
126 #define av_codec AVCodec
127 #define av_codec_ctx AVCodecContext
128 #define av_dump_fmt av_dump_format
129 #define av_duration_estimation_method AVDurationEstimationMethod
130 #define av_filt AVFilter
131 #define av_filt_ctx AVFilterContext
132 #define av_filt_get_by_name avfilter_get_by_name
133 #define av_filt_graph AVFilterGraph
134 #define av_filt_graph_alloc avfilter_graph_alloc
135 #define av_filt_graph_alloc_filt avfilter_graph_alloc_filter
136 #define av_filt_graph_cfg avfilter_graph_config
137 #define av_filt_graph_dump avfilter_graph_dump
138 #define av_filt_graph_free avfilter_graph_free
139 #define av_filt_graph_send_cmd avfilter_graph_send_command
140 #define av_filt_init_str avfilter_init_str
141 #define av_filt_link avfilter_link
142 #define av_find_best_st av_find_best_stream
143 #define av_flush_bufs avcodec_flush_buffers
144 #define av_fmt_ctx AVFormatContext
145 #define AV_FMT_DURATION_FROM_BITRATE AVFMT_DURATION_FROM_BITRATE
146 #define AV_FMT_DURATION_FROM_PTS AVFMT_DURATION_FROM_PTS
147 #define AV_FMT_DURATION_FROM_ST AVFMT_DURATION_FROM_STREAM
148 #define av_fmt_find_st_info avformat_find_stream_info
149 #define av_fmt_flush avformat_flush
150 #define av_fmt_open_input avformat_open_input
151 #define av_fr_fmt_is_planar av_sample_fmt_is_planar
152 #define AV_FR_FMT_DBL AV_SAMPLE_FMT_DBL
153 #define AV_FR_FMT_DBLP AV_SAMPLE_FMT_DBLP
154 #define AV_FR_FMT_FLT AV_SAMPLE_FMT_FLT
155 #define AV_FR_FMT_FLTP AV_SAMPLE_FMT_FLTP
156 #define AV_FR_FMT_S16 AV_SAMPLE_FMT_S16
157 #define AV_FR_FMT_S16P AV_SAMPLE_FMT_S16P
158 #define AV_FR_FMT_S32 AV_SAMPLE_FMT_S32
159 #define AV_FR_FMT_S32P AV_SAMPLE_FMT_S32P
160 #define AV_FR_FMT_U8P AV_SAMPLE_FMT_U8P
161 #define AV_FR_FMT_U8 AV_SAMPLE_FMT_U8
162 #define av_frs_alloc av_frame_alloc
163 #define av_frs_set_silence av_samples_set_silence
164 #define av_frs_unref av_frame_unref
165 #define av_get_chan_layout_str av_get_channel_layout_string
166 #define av_get_default_chans_layout av_get_default_channel_layout
167 #define av_get_fr_fmt_name av_get_sample_fmt_name
168 #define av_get_fr_fmt_str av_get_sample_fmt_string
169 #define av_io_flush avio_flush
170 #define AV_MEDIA_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
171 #define av_pkt AVPacket
172 #define av_pkt_unref av_packet_unref
173 #define av_read_pkt av_read_frame
174 #define av_rational AVRational
175 #define av_seek_pkt av_seek_frame
176 #define av_receive_frs avcodec_receive_frame
177 #define av_fr_fmt AVSampleFormat
178 #define av_frs AVFrame
179 #define av_sd_pkt avcodec_send_packet
180 #define av_st AVStream
181 #define chans_layout channel_layout
182 #define chans_n channels
183 #define fmt format
184 #define fr_fmt sample_fmt
185 #define fr_rate sample_rate
186 #define frs_n nb_samples
187 #define st_idx stream_index
188 #define sts streams
189 #define tb time_base
190 /* ff namespace -- END */
191 /*----------------------------------------------------------------------------*/
192 /* alsa namespace -- START */
193 #define snd_pcm_fmt_desc snd_pcm_format_description
194 #define snd_pcm_fmt_set_silence snd_pcm_format_set_silence
195 #define SND_PCM_FMT_FLT SND_PCM_FORMAT_FLOAT
196 #define SND_PCM_FMT_S16 SND_PCM_FORMAT_S16
197 #define SND_PCM_FMT_S24 SND_PCM_FORMAT_S24
198 #define SND_PCM_FMT_S32 SND_PCM_FORMAT_S32
199 #define SND_PCM_FMT_S8 SND_PCM_FORMAT_S8
200 #define snd_pcm_fmt_t snd_pcm_format_t
201 #define SND_PCM_FMT_U16 SND_PCM_FORMAT_U16
202 #define SND_PCM_FMT_U24 SND_PCM_FORMAT_U24
203 #define SND_PCM_FMT_U32 SND_PCM_FORMAT_U32
204 #define SND_PCM_FMT_U8 SND_PCM_FORMAT_U8
205 #define snd_pcm_frs_to_bytes snd_pcm_frames_to_bytes
206 #define snd_pcm_hw_params_get_buf_size snd_pcm_hw_params_get_buffer_size
207 #define snd_pcm_hw_params_get_chans snd_pcm_hw_params_get_channels
208 #define snd_pcm_hw_params_get_chans_max snd_pcm_hw_params_get_channels_max
209 #define snd_pcm_hw_params_get_chans_min snd_pcm_hw_params_get_channels_min
210 #define snd_pcm_hw_params_get_fmt snd_pcm_hw_params_get_format
211 #define snd_pcm_hw_params_set_buf_size_near snd_pcm_hw_params_set_buffer_size_near
212 #define snd_pcm_hw_params_set_chans snd_pcm_hw_params_set_channels
213 #define snd_pcm_hw_params_set_fmt snd_pcm_hw_params_set_format
214 #define snd_pcm_hw_params_test_chans snd_pcm_hw_params_test_channels
215 #define snd_pcm_hw_params_test_fmt snd_pcm_hw_params_test_format
216 #define snd_pcm_sfrs_t snd_pcm_sframes_t
217 #define SND_PCM_ST_PLAYBACK SND_PCM_STREAM_PLAYBACK
218 #define snd_pcm_ufrs_t snd_pcm_uframes_t
219 /* alsa namespace -- END */
220 /* namespaces -- END */
221 /*============================================================================*/
115 222 #define ARRAY_N(x) (sizeof(x) / sizeof((x)[0])) #define ARRAY_N(x) (sizeof(x) / sizeof((x)[0]))
116
117 #define POUT(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
118 #define PERR(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
119 #define WARNING(fmt, ...) fprintf(stderr, "WARNING:" fmt, ##__VA_ARGS__)
120 #define FATAL(fmt, ...) ({perr("FATAL:" fmt, ##__VA_ARGS__);stdin_flags_restore();stdin_tty_cfg_restore();exit(1);})
121 #define EXIT(fmt, ...) ({pout("EXITING:" fmt, ##__VA_ARGS__);stdin_flags_restore();stdin_tty_cfg_restore();exit(0);})
122 223 #define STR_SZ 255 /* sz and idx fit in 1 byte */ #define STR_SZ 255 /* sz and idx fit in 1 byte */
123 224 /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
124 225 static u8 *current_url; static u8 *current_url;
 
... ... static int current_st_idx;
127 228 static struct { static struct {
128 229 struct { struct {
129 230 int64_t duration; int64_t duration;
130 enum AVDurationEstimationMethod m;
231 enum av_duration_estimation_method m;
131 232 } fmt; } fmt;
132 233 struct { struct {
133 AVRational tb;
234 av_rational tb;
134 235 int id; int id;
135 236 int64_t duration; int64_t duration;
136 237 } st; } st;
 
... ... static struct {
140 241 static int ep_fd; static int ep_fd;
141 242 static int sig_fd; static int sig_fd;
142 243 /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
143 /* linux alsa */
244 /* alsa */
144 245 static snd_pcm_t *pcm_g; static snd_pcm_t *pcm_g;
145 246 static snd_output_t *pcm_pout; static snd_output_t *pcm_pout;
146 247 static snd_output_t *pcm_perr; static snd_output_t *pcm_perr;
 
... ... static snd_output_t *pcm_perr;
148 249 static struct pollfd pcm_pollfds[PCM_POLLFDS_N_MAX]; static struct pollfd pcm_pollfds[PCM_POLLFDS_N_MAX];
149 250 static u8 pcm_pollfds_n; static u8 pcm_pollfds_n;
150 251 /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
151 /* ffmpeg dec */
152 /*
153 * XXX: a ffmpeg fr is not 1 audio fr but a collection of frs.
154 * ffmpeg dec fr "nb_samples" is actually the number of audio frs
155 * av_read_frame is actually av_read_pkt, like av_seek*
156 * we personally did not like the resulting confusion.
157 * we purposely "fix" the namespace even if some others won't like it.
158 */
159 #define AVFrames AVFrame
160 #define frames_n nb_samples
161 #define av_frames_alloc av_frame_alloc
162 #define av_read_pkt av_read_frame
163 #define av_seek_pkt av_seek_frame
164 #define avcodec_receive_frames avcodec_receive_frame
165 #define AVFrameFormat AVSampleFormat
166 #define av_frames_set_silence av_samples_set_silence
167 #define av_get_frame_fmt_name av_get_sample_fmt_name
168 #define av_get_frame_fmt_string av_get_sample_fmt_string
169 #define frame_rate sample_rate
170 #define av_frame_fmt_is_planar av_sample_fmt_is_planar
171 #define frame_fmt sample_fmt
172 #define av_frames_unref av_frame_unref
173 static AVPacket *rd_thd_pkt;
174 static AVFormatContext *fmt_ctx;
252 /* ff dec */
253 static av_pkt *rd_thd_pkt;
254 static av_fmt_ctx *fmt_ctx;
175 255 static pthread_mutex_t fmt_ctx_mutex; static pthread_mutex_t fmt_ctx_mutex;
176 static AVCodec *dec;
177 static AVCodecContext *dec_ctx;
256 static av_codec *dec;
257 static av_codec_ctx *dec_ctx;
178 258 /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
179 /* ffmpeg filter graph */
180 static AVFilterGraph *filter_graph;
181 static AVFilterContext *abufsrc_ctx;
182 static const AVFilter *abufsrc_filt;
183 static AVFilterContext *vol_ctx;
184 static const AVFilter *vol_filt;
259 /* ff filt graph */
260 static av_filt_graph *filt_graph;
261 static av_filt_ctx *abufsrc_ctx;
262 static const av_filt *abufsrc_filt;
263 static struct { /* used to detected reconfiguration */
264 int chans_n;
265 uint64_t chans_layout;
266 int rate;
267 enum av_fr_fmt fmt;
268 } abufsrc_key;
269 static av_filt_ctx *vol_ctx;
270 static const av_filt *vol_filt;
185 271 static u8 double_zero_l10n_str[sizeof("xxx.xx")]; static u8 double_zero_l10n_str[sizeof("xxx.xx")];
186 static AVFilterContext *afmt_ctx;
187 static const AVFilter *afmt_filt;
188 static AVFilterContext *abufsink_ctx;
189 static const AVFilter *abufsink_filt;
272 static av_filt_ctx *afmt_ctx;
273 static const av_filt *afmt_filt;
274 static av_filt_ctx *abufsink_ctx;
275 static const av_filt *abufsink_filt;
190 276 /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
191 277 /* a formally proven concurrently accessed lockless cb */ /* a formally proven concurrently accessed lockless cb */
192 278 struct { struct {
193 279 atomic_u8 reset; atomic_u8 reset;
280 atomic_u8 hold;
194 281
195 282 atomic_int st_idx; atomic_int st_idx;
196 AVPacket *pkts[U8_MAX + 1];
283 av_pkt *pkts[U8_MAX + 1];
197 284 atomic_u8 rd; atomic_u8 rd;
198 285 atomic_u8 sd; atomic_u8 sd;
199 286 } cb; } cb;
200 287 /* running state */ /* running state */
201 288 struct { struct {
202 AVFrames *av;
289 av_frs *av;
290 bool pushed_in_filt_graph;
203 291 int64_t most_recent_ts; /* a very "coarse-grained" clock */ int64_t most_recent_ts; /* a very "coarse-grained" clock */
204 292 } dec_frs; } dec_frs;
205 293 struct { struct {
206 AVFrames *av;
207 bool no_more_dec_frs;
294 av_frs *av;
208 295 float vol; float vol;
209 296 bool muted; bool muted;
210 snd_pcm_uframes_t pcm_written_ufrs_n;
297 snd_pcm_ufrs_t pcm_written_ufrs_n;
211 298 } filt_frs; } filt_frs;
212 299 /* we will inject silence frs while paused */ /* we will inject silence frs while paused */
213 300 bool paused; bool paused;
 
... ... static void fmt_ctx_unlock(void)
348 435 if (r != 0) if (r != 0)
349 436 fatal("unable to unlock the format context\n"); fatal("unable to unlock the format context\n");
350 437 } }
351 static u8 *duration_estimate_to_str(enum AVDurationEstimationMethod m)
438 static u8 *duration_estimate_to_str(enum av_duration_estimation_method m)
352 439 { {
353 440 switch (m) { switch (m) {
354 case AVFMT_DURATION_FROM_PTS:
441 case AV_FMT_DURATION_FROM_PTS:
355 442 return "from PTS(Presentation TimeStamp)"; return "from PTS(Presentation TimeStamp)";
356 case AVFMT_DURATION_FROM_STREAM:
443 case AV_FMT_DURATION_FROM_ST:
357 444 return "from stream"; return "from stream";
358 case AVFMT_DURATION_FROM_BITRATE:
445 case AV_FMT_DURATION_FROM_BITRATE:
359 446 return "from bitrate"; return "from bitrate";
360 447 default: default:
361 448 return "unkwown"; return "unkwown";
362 449 } }
363 450 } }
364 451 /* meh... */ /* meh... */
365 static u8 *ts_to_str(int64_t ts, AVRational tb, int64_t *remaining)
452 static u8 *ts_to_str(int64_t ts, av_rational tb, int64_t *remaining)
366 453 { {
367 454 static u8 str[sizeof("~S00:00:00.000 remains S9223372036854775807 time base units")]; static u8 str[sizeof("~S00:00:00.000 remains S9223372036854775807 time base units")];
368 455 bool is_neg; bool is_neg;
 
... ... static u8 *ts_to_str(int64_t ts, AVRational tb, int64_t *remaining)
370 457 int64_t mins_n; int64_t mins_n;
371 458 int64_t secs_n; int64_t secs_n;
372 459 int64_t msecs_n; int64_t msecs_n;
373 int64_t one_hour; /* in ffmpeg time_base units */
374 int64_t one_min; /* in ffmpeg time_base units */
375 int64_t one_sec; /* in ffmpeg time_base units */
376 int64_t one_msec; /* in ffmpeg time_base units */
460 int64_t one_hour; /* in ff tb units */
461 int64_t one_min; /* in ff tb units */
462 int64_t one_sec; /* in ff tb units */
463 int64_t one_msec; /* in ff tb units */
377 464
378 465 if (ts < 0) { if (ts < 0) {
379 466 ts = -ts; ts = -ts;
 
... ... static void cmd_info(void)
436 523 snprintf(duration_str, sizeof(duration_str), "%"PRId64, cmd_info_data.fmt.duration); snprintf(duration_str, sizeof(duration_str), "%"PRId64, cmd_info_data.fmt.duration);
437 524 ts_str = ts_to_str(cmd_info_data.fmt.duration, AV_TIME_BASE_Q, ts_str = ts_to_str(cmd_info_data.fmt.duration, AV_TIME_BASE_Q,
438 525 &remaining); &remaining);
439 pout("duration=");RED;POUT("%s", ts_str);RESTORE;
526 pout("duration=");RED;pout("%s", ts_str);RESTORE;
440 527 if (remaining != 0) if (remaining != 0)
441 528 pout(" remaining %"PRId64" av_time_base units\n", remaining); pout(" remaining %"PRId64" av_time_base units\n", remaining);
442 529 else else
 
... ... static void cmd_info(void)
449 536 } else { } else {
450 537 snprintf(duration_str, sizeof(duration_str), "%"PRId64, cmd_info_data.st.duration); snprintf(duration_str, sizeof(duration_str), "%"PRId64, cmd_info_data.st.duration);
451 538 ts_str = ts_to_str(cmd_info_data.st.duration, cmd_info_data.st.tb, &remaining); ts_str = ts_to_str(cmd_info_data.st.duration, cmd_info_data.st.tb, &remaining);
452 pout(";duration=");RED;POUT("%s\n", ts_str);RESTORE;
539 pout(";duration=");RED;pout("%s\n", ts_str);RESTORE;
453 540 if (remaining != 0) if (remaining != 0)
454 541 pout(" remaining %"PRId64" stream time base units\n", remaining); pout(" remaining %"PRId64" stream time base units\n", remaining);
455 542 else else
 
... ... static void do_reset(void)
499 586 u8 i; u8 i;
500 587
501 588 fmt_ctx_lock(); fmt_ctx_lock();
502 avformat_flush(fmt_ctx);
503 avio_flush(fmt_ctx->pb);
589 av_fmt_flush(fmt_ctx);
590 av_io_flush(fmt_ctx->pb);
504 591 fmt_ctx_unlock(); fmt_ctx_unlock();
505 592 i = 0; i = 0;
506 593 loop { loop {
507 av_packet_unref(cb.pkts[i]);
594 av_pkt_unref(cb.pkts[i]);
508 595 if (i == U8_MAX) if (i == U8_MAX)
509 596 break; break;
510 597 ++i; ++i;
 
... ... static void do_reset(void)
515 602 } }
516 603 #undef RESET_DONE #undef RESET_DONE
517 604 #define DO_RESET 1 #define DO_RESET 1
605 #define HOLD 1
518 606 static void rd_loop(void) { loop /* infinite loop */ static void rd_loop(void) { loop /* infinite loop */
519 607 { {
520 608 int r; int r;
 
... ... static void rd_loop(void) { loop /* infinite loop */
523 611 u8 sd; u8 sd;
524 612 u8 reset; u8 reset;
525 613 int st_idx; int st_idx;
614 u8 hold;
526 615 /* /*
527 616 * XXX: we actually perform reset on this thd, with a little lockfree * XXX: we actually perform reset on this thd, with a little lockfree
528 617 * protocol and reasonable wait loops * protocol and reasonable wait loops
 
... ... static void rd_loop(void) { loop /* infinite loop */
531 620 if (reset == DO_RESET) if (reset == DO_RESET)
532 621 do_reset(); do_reset();
533 622 /*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
623 hold = atomic_load(&cb.hold);
624 if (hold == HOLD) {
625 wait(1000000); /* 1ms */
626 continue;
627 }
628 /*--------------------------------------------------------------------*/
534 629 rd = atomic_load(&cb.rd); rd = atomic_load(&cb.rd);
535 630 sd = atomic_load(&cb.sd); sd = atomic_load(&cb.sd);
536 631 next_rd = rd + 1; next_rd = rd + 1;
 
... ... static void rd_loop(void) { loop /* infinite loop */
554 649 fatal("ffmpeg:error while demuxing coded/compressed data into packets\n"); fatal("ffmpeg:error while demuxing coded/compressed data into packets\n");
555 650 else { /* r == 0 */ else { /* r == 0 */
556 651 st_idx = atomic_load(&cb.st_idx); st_idx = atomic_load(&cb.st_idx);
557 if (rd_thd_pkt->stream_index != st_idx) { /* sd_idx can be -1 */
558 av_packet_unref(rd_thd_pkt);
652 if (rd_thd_pkt->st_idx != st_idx) { /* sd_idx can be -1 */
653 av_pkt_unref(rd_thd_pkt);
559 654 continue; continue;
560 655 } }
561 656 av_packet_move_ref(cb.pkts[rd], rd_thd_pkt); av_packet_move_ref(cb.pkts[rd], rd_thd_pkt);
 
... ... static void rd_loop(void) { loop /* infinite loop */
563 658 atomic_store(&cb.rd, next_rd); atomic_store(&cb.rd, next_rd);
564 659 }} }}
565 660 #undef DO_RESET #undef DO_RESET
661 #undef HOLD
566 662 static void *rd_thd_entry(void *arg) static void *rd_thd_entry(void *arg)
567 663 { {
568 664 int r; int r;
 
... ... static uint64_t pcm_chmaps2ff_chans_layout(snd_pcm_t *pcm,
646 742 pout("alsa:your pcm device support channel maps, but fine granularity wiring strategy is not implemented\n"); pout("alsa:your pcm device support channel maps, but fine granularity wiring strategy is not implemented\n");
647 743 free(pcm_chmap); free(pcm_chmap);
648 744 } }
649 ff_chans_layout = av_get_default_channel_layout((int)pcm_chans_n);
650 av_get_channel_layout_string(chans_layout_str, sizeof(chans_layout_str),
745 ff_chans_layout = av_get_default_chans_layout((int)pcm_chans_n);
746 av_get_chan_layout_str(chans_layout_str, sizeof(chans_layout_str),
651 747 (int)pcm_chans_n, ff_chans_layout); (int)pcm_chans_n, ff_chans_layout);
652 748 if (print_info) if (print_info)
653 749 pout("alsa channel map wired to ffmpeg channel layout:\"%s\" (%u pcm channels)\n", chans_layout_str, pcm_chans_n); pout("alsa channel map wired to ffmpeg channel layout:\"%s\" (%u pcm channels)\n", chans_layout_str, pcm_chans_n);
654 750 return ff_chans_layout; return ff_chans_layout;
655 751 } }
656 752 /* fatal if the wiring cannot be done */ /* fatal if the wiring cannot be done */
657 static void pcm_layout2ff_fmt_strict(snd_pcm_format_t alsa_fmt,
658 snd_pcm_access_t alsa_access, enum AVSampleFormat *ff_fmt,
659 bool print_info)
753 static void pcm_layout2ff_fmt_strict(snd_pcm_fmt_t alsa_fmt,
754 snd_pcm_access_t alsa_access, enum av_fr_fmt *ff_fmt, bool print_info)
660 755 { {
661 756 /* /*
662 757 * ff fmt byte order is always native. * ff fmt byte order is always native.
663 758 * here we handle little endian only * here we handle little endian only
664 759 */ */
665 760 switch (alsa_fmt) { switch (alsa_fmt) {
666 case SND_PCM_FORMAT_FLOAT:
761 case SND_PCM_FMT_FLT:
667 762 if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED)
668 *ff_fmt = AV_SAMPLE_FMT_FLT;
763 *ff_fmt = AV_FR_FMT_FLT;
669 764 else else
670 *ff_fmt = AV_SAMPLE_FMT_FLTP;
765 *ff_fmt = AV_FR_FMT_FLTP;
671 766 break; break;
672 case SND_PCM_FORMAT_S32:
767 case SND_PCM_FMT_S32:
673 768 if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED)
674 *ff_fmt = AV_SAMPLE_FMT_S32;
769 *ff_fmt = AV_FR_FMT_S32;
675 770 else else
676 *ff_fmt = AV_SAMPLE_FMT_S32P;
771 *ff_fmt = AV_FR_FMT_S32P;
677 772 break; break;
678 case SND_PCM_FORMAT_S16:
773 case SND_PCM_FMT_S16:
679 774 if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED)
680 *ff_fmt = AV_SAMPLE_FMT_S16;
775 *ff_fmt = AV_FR_FMT_S16;
681 776 else else
682 *ff_fmt = AV_SAMPLE_FMT_S16P;
777 *ff_fmt = AV_FR_FMT_S16P;
683 778 break; break;
684 case SND_PCM_FORMAT_U8:
779 case SND_PCM_FMT_U8:
685 780 if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED)
686 *ff_fmt = AV_SAMPLE_FMT_U8;
781 *ff_fmt = AV_FR_FMT_U8;
687 782 else else
688 *ff_fmt = AV_SAMPLE_FMT_U8P;
783 *ff_fmt = AV_FR_FMT_U8P;
689 784 break; break;
690 785 default: default:
691 fatal("unable to wire strictly alsa layout \"%s\"/\"%s\" to a ffmpeg format\n", snd_pcm_format_description(alsa_fmt), snd_pcm_access_name(alsa_access));
786 fatal("unable to wire strictly alsa layout \"%s\"/\"%s\" to a ffmpeg format\n", snd_pcm_fmt_desc(alsa_fmt), snd_pcm_access_name(alsa_access));
692 787 } }
693 788 if (print_info) { if (print_info) {
694 789 u8 ff_fmt_str[STR_SZ]; u8 ff_fmt_str[STR_SZ];
695 790
696 av_get_sample_fmt_string(ff_fmt_str, sizeof(ff_fmt_str),
697 *ff_fmt);
698 pout("alsa pcm layout \"%s\"/\"%s\" wired strictly to ffmpeg format \"%sbits\"\n", snd_pcm_format_description(alsa_fmt), snd_pcm_access_name(alsa_access), ff_fmt_str);
791 av_get_fr_fmt_str(ff_fmt_str, sizeof(ff_fmt_str), *ff_fmt);
792 pout("alsa pcm layout \"%s\"/\"%s\" wired strictly to ffmpeg format \"%sbits\"\n", snd_pcm_fmt_desc(alsa_fmt), snd_pcm_access_name(alsa_access), ff_fmt_str);
699 793 } }
700 794 } }
701 static void pcm2ff(snd_pcm_t *pcm, enum AVSampleFormat *ff_fmt,
795 static void pcm2ff(snd_pcm_t *pcm, enum av_fr_fmt *ff_fmt,
702 796 int *ff_rate, int *ff_chans_n, uint64_t *ff_chans_layout, int *ff_rate, int *ff_chans_n, uint64_t *ff_chans_layout,
703 797 bool print_info) bool print_info)
704 798 { {
705 799 int r; int r;
706 800 snd_pcm_hw_params_t *hw_params; snd_pcm_hw_params_t *hw_params;
707 801 snd_pcm_access_t pcm_access; snd_pcm_access_t pcm_access;
708 snd_pcm_format_t pcm_fmt;
802 snd_pcm_fmt_t pcm_fmt;
709 803 unsigned int pcm_rate; unsigned int pcm_rate;
710 804 unsigned int pcm_chans_n; unsigned int pcm_chans_n;
711 805
 
... ... static void pcm2ff(snd_pcm_t *pcm, enum AVSampleFormat *ff_fmt,
718 812 r = snd_pcm_hw_params_get_access(hw_params, &pcm_access); r = snd_pcm_hw_params_get_access(hw_params, &pcm_access);
719 813 if (r < 0) if (r < 0)
720 814 fatal("alsa:unable to get the pcm access for ffmpeg filter wiring\n"); fatal("alsa:unable to get the pcm access for ffmpeg filter wiring\n");
721 r = snd_pcm_hw_params_get_format(hw_params, &pcm_fmt);
815 r = snd_pcm_hw_params_get_fmt(hw_params, &pcm_fmt);
722 816 if (r < 0) if (r < 0)
723 817 fatal("alsa:unable to get the pcm format for ffmpeg filter wiring\n"); fatal("alsa:unable to get the pcm format for ffmpeg filter wiring\n");
724 818 /*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
725 819 pcm_layout2ff_fmt_strict(pcm_fmt, pcm_access, ff_fmt, print_info); pcm_layout2ff_fmt_strict(pcm_fmt, pcm_access, ff_fmt, print_info);
726 820 /*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
727 821 r = snd_pcm_hw_params_get_rate(hw_params, &pcm_rate, r = snd_pcm_hw_params_get_rate(hw_params, &pcm_rate,
728 SND_PCM_STREAM_PLAYBACK);
822 SND_PCM_ST_PLAYBACK);
729 823 if (r < 0) if (r < 0)
730 824 fatal("alsa:unable to get the pcm rate for ffmpeg filter wiring\n"); fatal("alsa:unable to get the pcm rate for ffmpeg filter wiring\n");
731 825 *ff_rate = (int)pcm_rate; *ff_rate = (int)pcm_rate;
732 r = snd_pcm_hw_params_get_channels(hw_params, &pcm_chans_n);
826 r = snd_pcm_hw_params_get_chans(hw_params, &pcm_chans_n);
733 827 if (r < 0) if (r < 0)
734 828 fatal("alsa:unable to get the pcm count of channels for ffmpeg filter wiring\n"); fatal("alsa:unable to get the pcm count of channels for ffmpeg filter wiring\n");
735 829 *ff_chans_n = (int)pcm_chans_n; *ff_chans_n = (int)pcm_chans_n;
 
... ... static void pcm2ff(snd_pcm_t *pcm, enum AVSampleFormat *ff_fmt,
739 833 /*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
740 834 snd_pcm_hw_params_free(hw_params); snd_pcm_hw_params_free(hw_params);
741 835 } }
742 static void abufsrc_cfg(enum AVFrameFormat fmt, int rate, int chans_n,
836 /* XXX: we don't program the tb of the filter since it should not be used */
837 static void abufsrc_cfg(enum av_fr_fmt fmt, int rate, int chans_n,
743 838 uint64_t chans_layout, bool print_info) uint64_t chans_layout, bool print_info)
744 839 { {
745 840 int r; int r;
746 AVRational tb;
747 841 u8 chans_layout_str[STR_SZ]; /* should be overkill */ u8 chans_layout_str[STR_SZ]; /* should be overkill */
748 842
749 abufsrc_filt = avfilter_get_by_name("abuffer");
843 abufsrc_filt = av_filt_get_by_name("abuffer");
750 844 if (abufsrc_filt == 0) if (abufsrc_filt == 0)
751 845 fatal("audio buffer source:could not find the filter\n"); fatal("audio buffer source:could not find the filter\n");
752 abufsrc_ctx = avfilter_graph_alloc_filter(filter_graph, abufsrc_filt,
846 abufsrc_ctx = av_filt_graph_alloc_filt(filt_graph, abufsrc_filt,
753 847 "src_abuf"); "src_abuf");
754 848 if (abufsrc_ctx == 0) if (abufsrc_ctx == 0)
755 849 fatal("audio buffer source context:could not allocate the instance in the filter graph\n"); fatal("audio buffer source context:could not allocate the instance in the filter graph\n");
756 r = av_opt_set(abufsrc_ctx, "sample_fmt", av_get_frame_fmt_name(fmt),
850 r = av_opt_set(abufsrc_ctx, "sample_fmt", av_get_fr_fmt_name(fmt),
757 851 AV_OPT_SEARCH_CHILDREN); AV_OPT_SEARCH_CHILDREN);
758 852 if (r < 0) if (r < 0)
759 853 fatal("audio buffer source context:unable to set the decoder frame format option\n"); fatal("audio buffer source context:unable to set the decoder frame format option\n");
 
... ... static void abufsrc_cfg(enum AVFrameFormat fmt, int rate, int chans_n,
761 855 AV_OPT_SEARCH_CHILDREN); AV_OPT_SEARCH_CHILDREN);
762 856 if (r < 0) if (r < 0)
763 857 fatal("audio buffer source context:unable to set the decoder rate option\n"); fatal("audio buffer source context:unable to set the decoder rate option\n");
764 av_get_channel_layout_string(chans_layout_str, sizeof(chans_layout_str),
858 av_get_chan_layout_str(chans_layout_str, sizeof(chans_layout_str),
765 859 chans_n, chans_layout); chans_n, chans_layout);
766 860 if (print_info) if (print_info)
767 861 pout("audio buffer source context:using channels layout \"%s\" (%d pcm channels)\n", chans_layout_str, chans_n); pout("audio buffer source context:using channels layout \"%s\" (%d pcm channels)\n", chans_layout_str, chans_n);
 
... ... static void abufsrc_cfg(enum AVFrameFormat fmt, int rate, int chans_n,
769 863 AV_OPT_SEARCH_CHILDREN); AV_OPT_SEARCH_CHILDREN);
770 864 if (r < 0) if (r < 0)
771 865 fatal("audio buffer source context:unable to set the decoder channel layout option\n"); fatal("audio buffer source context:unable to set the decoder channel layout option\n");
772 r = avfilter_init_str(abufsrc_ctx, 0);
866 r = av_filt_init_str(abufsrc_ctx, 0);
773 867 if (r < 0) if (r < 0)
774 868 fatal("audio buffer source context:unable to initialize\n"); fatal("audio buffer source context:unable to initialize\n");
775 869 } }
 
... ... static void vol_cfg(bool muted, double vol)
779 873 u8 vol_l10n_str[sizeof("xxx.xx")]; /* should be overkill */ u8 vol_l10n_str[sizeof("xxx.xx")]; /* should be overkill */
780 874 int r; int r;
781 875
782 vol_filt = avfilter_get_by_name("volume");
876 vol_filt = av_filt_get_by_name("volume");
783 877 if (vol_filt == 0) if (vol_filt == 0)
784 878 fatal("volume:could not find the filter\n"); fatal("volume:could not find the filter\n");
785 vol_ctx = avfilter_graph_alloc_filter(filter_graph, vol_filt, "vol");
879 vol_ctx = av_filt_graph_alloc_filt(filt_graph, vol_filt, "vol");
786 880 if (vol_ctx == 0) if (vol_ctx == 0)
787 881 fatal("volume context:could not allocate the instance in the filter graph\n"); fatal("volume context:could not allocate the instance in the filter graph\n");
788 882 if (muted) if (muted)
 
... ... static void vol_cfg(bool muted, double vol)
794 888 r = av_opt_set(vol_ctx, "volume", vol_l10n_str, AV_OPT_SEARCH_CHILDREN); r = av_opt_set(vol_ctx, "volume", vol_l10n_str, AV_OPT_SEARCH_CHILDREN);
795 889 if (r < 0) if (r < 0)
796 890 fatal("volume context:unable to set the volume option\n"); fatal("volume context:unable to set the volume option\n");
797 r = avfilter_init_str(vol_ctx, 0);
891 r = av_filt_init_str(vol_ctx, 0);
798 892 if (r < 0) if (r < 0)
799 893 fatal("volume buffer context:unable to initialize\n"); fatal("volume buffer context:unable to initialize\n");
800 894 } }
801 static void afmt_cfg(enum AVFrameFormat fmt, int rate, int chans_n,
895 static void afmt_cfg(enum av_fr_fmt fmt, int rate, int chans_n,
802 896 uint64_t chans_layout, bool print_info) uint64_t chans_layout, bool print_info)
803 897 { {
804 898 int r; int r;
805 899 u8 rate_str[sizeof("dddddd")]; u8 rate_str[sizeof("dddddd")];
806 900 u8 chans_layout_str[STR_SZ]; /* should be overkill */ u8 chans_layout_str[STR_SZ]; /* should be overkill */
807 901
808 afmt_filt = avfilter_get_by_name("aformat");
902 afmt_filt = av_filt_get_by_name("aformat");
809 903 if (afmt_filt == 0) if (afmt_filt == 0)
810 904 fatal("audio format:could not find the filter"); fatal("audio format:could not find the filter");
811 afmt_ctx = avfilter_graph_alloc_filter(filter_graph, afmt_filt, "afmt");
905 afmt_ctx = av_filt_graph_alloc_filt(filt_graph, afmt_filt, "afmt");
812 906 if (afmt_ctx == 0) if (afmt_ctx == 0)
813 907 fatal("audio format:could not allocate the instance in the filter graph\n"); fatal("audio format:could not allocate the instance in the filter graph\n");
814 r = av_opt_set(afmt_ctx, "sample_fmts", av_get_frame_fmt_name(fmt),
908 r = av_opt_set(afmt_ctx, "sample_fmts", av_get_fr_fmt_name(fmt),
815 909 AV_OPT_SEARCH_CHILDREN); AV_OPT_SEARCH_CHILDREN);
816 910 if (r < 0) if (r < 0)
817 911 fatal("audio format context:could to set the pcm sample format\n"); fatal("audio format context:could to set the pcm sample format\n");
 
... ... static void afmt_cfg(enum AVFrameFormat fmt, int rate, int chans_n,
820 914 AV_OPT_SEARCH_CHILDREN); AV_OPT_SEARCH_CHILDREN);
821 915 if (r < 0) if (r < 0)
822 916 fatal("audio format context:could not set the pcm rate\n"); fatal("audio format context:could not set the pcm rate\n");
823 av_get_channel_layout_string(chans_layout_str, sizeof(chans_layout_str),
917 av_get_chan_layout_str(chans_layout_str, sizeof(chans_layout_str),
824 918 chans_n, chans_layout); chans_n, chans_layout);
825 919 r = av_opt_set(afmt_ctx, "channel_layouts", chans_layout_str, r = av_opt_set(afmt_ctx, "channel_layouts", chans_layout_str,
826 920 AV_OPT_SEARCH_CHILDREN); AV_OPT_SEARCH_CHILDREN);
 
... ... static void afmt_cfg(enum AVFrameFormat fmt, int rate, int chans_n,
828 922 fatal("audio format context:could not set the layout of channels\n"); fatal("audio format context:could not set the layout of channels\n");
829 923 if (print_info) if (print_info)
830 924 pout("audio format context:channel layout is \"%s\"\n", chans_layout_str); pout("audio format context:channel layout is \"%s\"\n", chans_layout_str);
831 r = avfilter_init_str(afmt_ctx, 0);
925 r = av_filt_init_str(afmt_ctx, 0);
832 926 if (r < 0) if (r < 0)
833 927 fatal("audio format context:unable to initialize\n"); fatal("audio format context:unable to initialize\n");
834 928 } }
 
... ... static void abufsink_cfg(void)
836 930 { {
837 931 int r; int r;
838 932
839 abufsink_filt = avfilter_get_by_name("abuffersink");
933 abufsink_filt = av_filt_get_by_name("abuffersink");
840 934 if (abufsink_filt == 0) if (abufsink_filt == 0)
841 935 fatal("audio buffer sink:could not find the filter\n"); fatal("audio buffer sink:could not find the filter\n");
842 abufsink_ctx = avfilter_graph_alloc_filter(filter_graph, abufsink_filt,
936 abufsink_ctx = av_filt_graph_alloc_filt(filt_graph, abufsink_filt,
843 937 "sink_abuf"); "sink_abuf");
844 938 if (abufsink_ctx == 0) if (abufsink_ctx == 0)
845 939 fatal("audio buffer sink context:could not allocate the instance in the filter graph\n"); fatal("audio buffer sink context:could not allocate the instance in the filter graph\n");
846 r = avfilter_init_str(abufsink_ctx, 0);
940 r = av_filt_init_str(abufsink_ctx, 0);
847 941 if (r < 0) if (r < 0)
848 942 fatal("audio buffer sink context:unable to initialize\n"); fatal("audio buffer sink context:unable to initialize\n");
849 943 } }
 
... ... static void dec_ctx_cfg(AVCodecParameters *params)
868 962 if (r < 0) if (r < 0)
869 963 fatal("ffmpeg:unable to open the decoder context\n"); fatal("ffmpeg:unable to open the decoder context\n");
870 964 } }
871 static void filter_graph_cfg(
872 enum AVSampleFormat src_fmt, int src_rate, int src_chans_n,
965 static void filt_graph_cfg(
966 enum av_fr_fmt src_fmt, int src_rate, int src_chans_n,
873 967 uint64_t src_chans_layout, uint64_t src_chans_layout,
874 968 bool muted, double vol, bool muted, double vol,
875 enum AVSampleFormat dst_fmt, int dst_rate, int dst_chans_n,
969 enum av_fr_fmt dst_fmt, int dst_rate, int dst_chans_n,
876 970 uint64_t dst_chans_layout, bool print_info) uint64_t dst_chans_layout, bool print_info)
877 971 { {
878 972 int r; int r;
879 973 char *dump_str; char *dump_str;
880 974
881 avfilter_graph_free(&filter_graph);
975 av_filt_graph_free(&filt_graph);
882 976
883 filter_graph = avfilter_graph_alloc();
884 if (filter_graph == 0)
977 filt_graph = av_filt_graph_alloc();
978 if (filt_graph == 0)
885 979 fatal("unable to create filter graph\n"); fatal("unable to create filter graph\n");
886 980 abufsrc_cfg(src_fmt, src_rate, src_chans_n, src_chans_layout, abufsrc_cfg(src_fmt, src_rate, src_chans_n, src_chans_layout,
887 981 print_info); print_info);
982 /*--------------------------------------------------------------------*/
983 abufsrc_key.chans_n = src_chans_n;
984 abufsrc_key.chans_layout = src_chans_layout;
985 abufsrc_key.rate = src_rate;
986 abufsrc_key.fmt = src_fmt;
987 /*--------------------------------------------------------------------*/
888 988 vol_cfg(muted, vol); vol_cfg(muted, vol);
889 989 afmt_cfg(dst_fmt, dst_rate, dst_chans_n, dst_chans_layout, print_info); afmt_cfg(dst_fmt, dst_rate, dst_chans_n, dst_chans_layout, print_info);
890 990 abufsink_cfg(); abufsink_cfg();
891 r = avfilter_link(abufsrc_ctx, 0, vol_ctx, 0);
991 r = av_filt_link(abufsrc_ctx, 0, vol_ctx, 0);
892 992 if (r < 0) if (r < 0)
893 993 fatal("unable to connect the audio buffer source filter to the volume filter\n"); fatal("unable to connect the audio buffer source filter to the volume filter\n");
894 r = avfilter_link(vol_ctx, 0, afmt_ctx, 0);
994 r = av_filt_link(vol_ctx, 0, afmt_ctx, 0);
895 995 if (r < 0) if (r < 0)
896 996 fatal("unable to connect the volume filter to the audio format filter\n"); fatal("unable to connect the volume filter to the audio format filter\n");
897 r = avfilter_link(afmt_ctx, 0, abufsink_ctx, 0);
997 r = av_filt_link(afmt_ctx, 0, abufsink_ctx, 0);
898 998 if (r < 0) if (r < 0)
899 999 fatal("unable to connect the audio format filter to the audio buffer sink filter\n"); fatal("unable to connect the audio format filter to the audio buffer sink filter\n");
900 r = avfilter_graph_config(filter_graph, 0);
1000 r = av_filt_graph_cfg(filt_graph, 0);
901 1001 if (r < 0) if (r < 0)
902 1002 fatal("unable to configure the filter graph\n"); fatal("unable to configure the filter graph\n");
903 1003 /*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
904 1004 if (!print_info) if (!print_info)
905 1005 return; return;
906 dump_str = avfilter_graph_dump(filter_graph, 0);
1006 dump_str = av_filt_graph_dump(filt_graph, 0);
907 1007 if (dump_str == 0) { if (dump_str == 0) {
908 1008 warning("unable to get a filter graph description\n"); warning("unable to get a filter graph description\n");
909 1009 return; return;
 
... ... static void filter_graph_cfg(
916 1016 #define DONT_PRINT_INFO false #define DONT_PRINT_INFO false
917 1017 static void filt_flush(void) static void filt_flush(void)
918 1018 { {
919 enum AVSampleFormat dst_fmt;
1019 enum av_fr_fmt dst_fmt;
920 1020 int dst_rate; int dst_rate;
921 1021 int dst_chans_n; int dst_chans_n;
922 1022 uint64_t src_chans_layout; uint64_t src_chans_layout;
923 1023 uint64_t dst_chans_layout; uint64_t dst_chans_layout;
924 1024
925 av_frames_unref(filt_frs.av);
1025 av_frs_unref(filt_frs.av);
926 1026 filt_frs.pcm_written_ufrs_n = 0; filt_frs.pcm_written_ufrs_n = 0;
927 1027
928 1028 pcm2ff(pcm_g, &dst_fmt, &dst_rate, &dst_chans_n, &dst_chans_layout, pcm2ff(pcm_g, &dst_fmt, &dst_rate, &dst_chans_n, &dst_chans_layout,
929 1029 DONT_PRINT_INFO); DONT_PRINT_INFO);
930 1030 /* the audio dec ctx may not have a valid chans layout */ /* the audio dec ctx may not have a valid chans layout */
931 if (dec_ctx->channel_layout == 0) {
932 src_chans_layout = av_get_default_channel_layout(
933 dec_ctx->channels);
1031 if (dec_ctx->chans_layout == 0) {
1032 src_chans_layout = av_get_default_chans_layout(dec_ctx->chans_n);
934 1033 } else } else
935 src_chans_layout = dec_ctx->channel_layout;
936 filter_graph_cfg(
937 dec_ctx->sample_fmt, dec_ctx->sample_rate,
938 dec_ctx->channels, src_chans_layout,
1034 src_chans_layout = dec_ctx->chans_layout;
1035 filt_graph_cfg(
1036 dec_ctx->fr_fmt, dec_ctx->fr_rate,
1037 dec_ctx->chans_n, src_chans_layout,
939 1038 filt_frs.muted, filt_frs.vol, filt_frs.muted, filt_frs.vol,
940 1039 dst_fmt, dst_rate, dst_chans_n, dst_chans_layout, dst_fmt, dst_rate, dst_chans_n, dst_chans_layout,
941 1040 DONT_PRINT_INFO); DONT_PRINT_INFO);
 
... ... static void dec_fill(void) { loop
1297 1396 /* at start, we must read pkt before we can send one */ /* at start, we must read pkt before we can send one */
1298 1397 if (rd == sd) if (rd == sd)
1299 1398 break; break;
1300 r = avcodec_send_packet(dec_ctx, cb.pkts[sd]);
1399 r = av_sd_pkt(dec_ctx, cb.pkts[sd]);
1301 1400 /* dec is full and the pkt was rejected, or the decoder is in EOF */ /* dec is full and the pkt was rejected, or the decoder is in EOF */
1302 1401 if (r == AVERROR(EAGAIN) || r == AVERROR_EOF) if (r == AVERROR(EAGAIN) || r == AVERROR_EOF)
1303 1402 break; break;
1304 1403 else if (r != 0) else if (r != 0)
1305 1404 fatal("ffmpeg:error while sending the packet to the decoder\n"); fatal("ffmpeg:error while sending the packet to the decoder\n");
1306 1405 /* r == 0 */ /* r == 0 */
1307 av_packet_unref(cb.pkts[sd]);
1406 av_pkt_unref(cb.pkts[sd]);
1308 1407 next_sd = sd + 1; next_sd = sd + 1;
1309 1408 atomic_store(&cb.sd, next_sd); atomic_store(&cb.sd, next_sd);
1310 1409 }} }}
1311 /*
1312 * return true if we have 1 dec_frs.av, false if no more dec_frs.av
1313 * will come
1314 */
1315 static bool dec_frs_get(void) { loop
1410 static void dec_frs_get(void) { loop
1316 1411 { {
1317 1412 int r; int r;
1318 1413
1319 1414 dec_fill(); dec_fill();
1320 1415
1321 1416 /* will unref the dec_frs.av bufs for us */ /* will unref the dec_frs.av bufs for us */
1322 r = avcodec_receive_frames(dec_ctx, dec_frs.av);
1417 r = av_receive_frs(dec_ctx, dec_frs.av);
1323 1418 if (r == AVERROR(EAGAIN)) if (r == AVERROR(EAGAIN))
1324 1419 continue; continue;
1325 1420 else if (r == 0) { else if (r == 0) {
 
... ... static bool dec_frs_get(void) { loop
1329 1424 dec_frs.most_recent_ts = dec_frs.av->pkt_dts; dec_frs.most_recent_ts = dec_frs.av->pkt_dts;
1330 1425 else else
1331 1426 dec_frs.most_recent_ts = dec_frs.av->pkt_dts; dec_frs.most_recent_ts = dec_frs.av->pkt_dts;
1332 return true; /* "return" the current dec_frs.av */
1427 dec_frs.pushed_in_filt_graph = false;
1428 return; /* "return" the current dec_frs.av */
1333 1429 } else if (r == AVERROR_EOF) { } else if (r == AVERROR_EOF) {
1334 1430 pout("ffmpeg:last decoder frames reached (receiving)\n"); pout("ffmpeg:last decoder frames reached (receiving)\n");
1335 return false;
1431 loop { /* spinning */
1432 snd_pcm_state_t state;
1433
1434 r = snd_pcm_drain(pcm_g);
1435 if (r == 0)
1436 break;
1437 if (r == -EAGAIN)
1438 continue;
1439 /*
1440 * the pcm state can change asynchronously.
1441 * _old_ behavior:
1442 * if the draining was successful, the pcm
1443 * should be in SETUP state, and in this
1444 * state, snd_pcm_drain will fail
1445 * _new and fixed__ behavior:
1446 * this won't happen because calling
1447 * snd_pcm_drain while in the SETUP state
1448 * won't return an error anymore
1449 */
1450 state = snd_pcm_state(pcm_g);
1451 if (state == SND_PCM_STATE_SETUP)
1452 break;
1453 }
1454 /**********************************************/
1455 exit_ok("finished playing\n");
1456 /**********************************************/
1336 1457 } }
1337 1458 fatal("ffmpeg:error while receiving frames from the decoder\n"); fatal("ffmpeg:error while receiving frames from the decoder\n");
1338 1459 }} }}
1339 static bool filt_frs_get(void) { loop
1460 static bool is_recfg_required(av_frs *frs)
1461 {
1462 if ( frs->chans_n != abufsrc_key.chans_n
1463 || frs->chans_layout != abufsrc_key.chans_layout
1464 || frs->fr_rate != abufsrc_key.rate
1465 || frs->fmt != abufsrc_key.fmt)
1466 return true;
1467 return false;
1468 }
1469 #define AGAIN 0
1470 #define PUSHED 1
1471 #define FILT_RECFG_REQUIRED 2
1472 static u8 filt_graph_push_dec_frs(int *new_chans_n, uint64_t *new_chans_layout,
1473 int *new_fr_rate, enum av_fr_fmt *new_fmt)
1340 1474 { {
1341 1475 int r; int r;
1342 1476
1343 if (!filt_frs.no_more_dec_frs) {
1344 if(!dec_frs_get()) {
1345 filt_frs.no_more_dec_frs = true;
1346
1347 r = av_buffersrc_add_frame_flags(abufsrc_ctx,
1348 0 , AV_BUFFERSRC_FLAG_PUSH
1349 | AV_BUFFERSRC_FLAG_KEEP_REF);
1350 if (r < 0)
1351 fatal("ffmpeg:unable to notify the end of data to the filter source audio buffer context\n");
1352 } else {
1353 /*
1354 * the dec_frs bufs will be unref in
1355 * avcodec_receive_frames
1356 */
1357 r = av_buffersrc_add_frame_flags(abufsrc_ctx,
1358 dec_frs.av, AV_BUFFERSRC_FLAG_PUSH
1359 | AV_BUFFERSRC_FLAG_KEEP_REF);
1360 if (r < 0)
1361 fatal("ffmpeg:unable to submit the decoder frames to the filter source audio buffer context\n");
1362 }
1477 if (dec_frs.pushed_in_filt_graph)
1478 dec_frs_get();
1479 if (dec_frs.av->chans_layout == 0) /* choose one for the filt */
1480 dec_frs.av->chans_layout = av_get_default_chans_layout(
1481 dec_frs.av->chans_n);
1482 if (is_recfg_required(dec_frs.av)) {
1483 *new_chans_n = dec_frs.av->chans_n;
1484 *new_chans_layout = dec_frs.av->chans_layout;
1485 *new_fr_rate = dec_frs.av->fr_rate;
1486 *new_fmt = dec_frs.av->fmt;
1487 return FILT_RECFG_REQUIRED;
1363 1488 } }
1364 /*
1365 * the last dec_frs should switch the filter in draining mode,
1366 * and filt_frs.av won't matter.
1367 */
1368 r = av_buffersink_get_frame(abufsink_ctx, filt_frs.av);
1369 if (r == AVERROR(EAGAIN)) {
1370 /*
1371 * won't happen if no more dec frs are available thanks
1372 * to eof propagation along the processing graph, in theory
1373 */
1374 continue;
1375 } else if (r >= 0) {
1489 /* the dec_frs.av bufs will be unref in av_receive_frs */
1490 r = av_bufsrc_add_frs_flags(abufsrc_ctx, dec_frs.av,
1491 AV_BUFSRC_FLAG_KEEP_REF);
1492 if (r >= 0) {
1493 dec_frs.pushed_in_filt_graph = true;
1494 return PUSHED;
1495 } else if (r == AVERROR(EAGAIN))
1496 return AGAIN;
1497 fatal("ffmpeg:unable to submit a decoder set of frames to the filter source audio buffer context\n");
1498 }
1499 #undef AGAIN
1500 #undef PUSHED
1501 #undef FILT_RECFG_REQUIRED
1502 static void filt_frs_get(void)
1503 {
1504 int r;
1505
1506 r = av_bufsink_get_frs(abufsink_ctx, filt_frs.av);
1507 if (r >= 0) {
1376 1508 filt_frs.pcm_written_ufrs_n = 0; filt_frs.pcm_written_ufrs_n = 0;
1377 return true;
1378 } else if (r == AVERROR_EOF) {
1379 pout("ffmpeg:last filter frs reached (getting)\n");
1380 return false;
1509 return;
1381 1510 } }
1382 fatal("ffmpeg:error while getting frs from the filter\n");
1383 }}
1511 fatal("ffmpeg:error while getting frames from the filter\n");
1512 }
1513 #define FILT_RECFG_REQUIRED 2
1514 #define EOF_FILT 2
1515 #define DRAINING 3
1516 #define HAVE_FILT_SET 1
1517 #define PRINT_INFO true
1518 /* synchronous filtering */
1519 static void dec_frs_filter(void)
1520 {
1521 loop {
1522 u8 r;
1523 int new_chans_n;
1524 uint64_t new_chans_layout;
1525 int new_fr_rate;
1526 enum av_fr_fmt new_fmt;
1527 int dst_chans_n;
1528 uint64_t dst_chans_layout;
1529 int dst_rate;
1530 enum av_fr_fmt dst_fmt;
1531
1532 r = filt_graph_push_dec_frs(&new_chans_n, &new_chans_layout,
1533 &new_fr_rate, &new_fmt);
1534 if (r != FILT_RECFG_REQUIRED) {
1535 /* PUSHED | AGAIN */
1536 break;
1537 }
1538 /* FILT_RECFG_REQUIRED */
1539 pcm2ff(pcm_g, &dst_fmt, &dst_rate, &dst_chans_n,
1540 &dst_chans_layout, PRINT_INFO);
1541 filt_graph_cfg(
1542 new_fmt, new_fr_rate, new_chans_n, new_chans_layout,
1543 filt_frs.muted, filt_frs.vol,
1544 dst_fmt, dst_rate, dst_chans_n, dst_chans_layout,
1545 PRINT_INFO);
1546 }
1547 filt_frs_get();
1548 }
1549 #undef FILT_RECFG_REQUIRED
1550 #undef EOF_FILT
1551 #undef DRAINING
1552 #undef HAVE_FILT_SET
1553 #undef PRINT_INFO
1384 1554 #define NO 0 #define NO 0
1385 1555 static void chans_buf_init(u8 **chans_buf, int start_fr_idx) static void chans_buf_init(u8 **chans_buf, int start_fr_idx)
1386 1556 { {
1387 1557 int is_planar_fmt; int is_planar_fmt;
1388 1558 int sample_bytes_n; int sample_bytes_n;
1389 1559
1390 sample_bytes_n = av_get_bytes_per_sample(filt_frs.av->format);
1560 sample_bytes_n = av_get_bytes_per_sample(filt_frs.av->fmt);
1391 1561
1392 is_planar_fmt = av_frame_fmt_is_planar(filt_frs.av->format);
1562 is_planar_fmt = av_fr_fmt_is_planar(filt_frs.av->fmt);
1393 1563 if (is_planar_fmt == NO) { /* or is pcm interleaved */ if (is_planar_fmt == NO) { /* or is pcm interleaved */
1394 1564 int fr_bytes_n; int fr_bytes_n;
1395 1565
1396 fr_bytes_n = sample_bytes_n * filt_frs.av->channels;
1566 fr_bytes_n = sample_bytes_n * filt_frs.av->chans_n;
1397 1567 chans_buf[0] = (u8*)filt_frs.av->data[0] + start_fr_idx chans_buf[0] = (u8*)filt_frs.av->data[0] + start_fr_idx
1398 1568 * fr_bytes_n; * fr_bytes_n;
1399 } else { /* ffmpeg planar or pcm noninterleaved */
1569 } else { /* ff planar or pcm noninterleaved */
1400 1570 int p; int p;
1401 1571
1402 1572 p = 0; p = 0;
1403 1573 loop { loop {
1404 if (p == filt_frs.av->channels)
1574 if (p == filt_frs.av->chans_n)
1405 1575 break; break;
1406 1576 chans_buf[p] = (u8*)filt_frs.av->data[p] chans_buf[p] = (u8*)filt_frs.av->data[p]
1407 1577 + start_fr_idx * sample_bytes_n; + start_fr_idx * sample_bytes_n;
 
... ... static void chans_buf_inc(u8 **chans_buf, int frs_inc)
1416 1586 int is_planar_fmt; int is_planar_fmt;
1417 1587 int sample_bytes_n; int sample_bytes_n;
1418 1588
1419 sample_bytes_n = av_get_bytes_per_sample(filt_frs.av->format);
1589 sample_bytes_n = av_get_bytes_per_sample(filt_frs.av->fmt);
1420 1590
1421 is_planar_fmt = av_frame_fmt_is_planar(filt_frs.av->format);
1591 is_planar_fmt = av_fr_fmt_is_planar(filt_frs.av->fmt);
1422 1592 if (is_planar_fmt == NO) { /* or is pcm interleaved */ if (is_planar_fmt == NO) { /* or is pcm interleaved */
1423 1593 int fr_bytes_n; int fr_bytes_n;
1424 1594
1425 fr_bytes_n = sample_bytes_n * filt_frs.av->channels;
1595 fr_bytes_n = sample_bytes_n * filt_frs.av->chans_n;
1426 1596 chans_buf[0] += frs_inc * fr_bytes_n; chans_buf[0] += frs_inc * fr_bytes_n;
1427 } else { /* ffmpeg planar or pcm noninterleaved */
1597 } else { /* ff planar or pcm noninterleaved */
1428 1598 u8 p; u8 p;
1429 1599
1430 1600 p = 0; p = 0;
1431 1601 loop { loop {
1432 if (p == filt_frs.av->channels)
1602 if (p == filt_frs.av->chans_n)
1433 1603 break; break;
1434 1604 chans_buf[p] += frs_inc * sample_bytes_n; chans_buf[p] += frs_inc * sample_bytes_n;
1435 1605 ++p; ++p;
 
... ... static void chans_buf_inc(u8 **chans_buf, int frs_inc)
1438 1608 } }
1439 1609 #undef NO #undef NO
1440 1610 #define NO 0 #define NO 0
1441 static void pcm_silence_frs_write(snd_pcm_uframes_t ufrs_n)
1611 static void pcm_silence_frs_write(snd_pcm_ufrs_t ufrs_n)
1442 1612 { {
1443 1613 int is_planar_fmt; int is_planar_fmt;
1444 1614
1445 1615 if (ufrs_n == 0) if (ufrs_n == 0)
1446 1616 return; return;
1447 1617
1448 is_planar_fmt = av_frame_fmt_is_planar(filt_frs.av->format);
1618 is_planar_fmt = av_fr_fmt_is_planar(filt_frs.av->fmt);
1449 1619 if (is_planar_fmt == NO) if (is_planar_fmt == NO)
1450 1620 (void)snd_pcm_writei(pcm_g, silence_bufs[0], ufrs_n); (void)snd_pcm_writei(pcm_g, silence_bufs[0], ufrs_n);
1451 1621 else else
 
... ... static void pcm_silence_frs_write(snd_pcm_uframes_t ufrs_n)
1453 1623 } }
1454 1624 #undef NO #undef NO
1455 1625 #define NO 0 #define NO 0
1456 static void pcm_filt_frs_write(snd_pcm_uframes_t ufrs_n) { loop
1626 static void pcm_filt_frs_write(snd_pcm_ufrs_t ufrs_n) { loop
1457 1627 { {
1458 1628 u8 chan_buf; u8 chan_buf;
1459 1629 u8 *chans_buf[AV_NUM_DATA_POINTERS]; u8 *chans_buf[AV_NUM_DATA_POINTERS];
1460 snd_pcm_sframes_t r0;
1461 snd_pcm_uframes_t ufrs_to_write_n;
1462 snd_pcm_uframes_t filt_frs_remaining_ufrs_n; /* for clarity */
1630 snd_pcm_sfrs_t r0;
1631 snd_pcm_ufrs_t ufrs_to_write_n;
1632 snd_pcm_ufrs_t filt_frs_remaining_ufrs_n; /* for clarity */
1463 1633
1464 1634 if (ufrs_n == 0) if (ufrs_n == 0)
1465 1635 return; return;
1466
1636 if (filt_frs.pcm_written_ufrs_n == (snd_pcm_ufrs_t)filt_frs.av->frs_n) {
1637 av_frs_unref(filt_frs.av);
1638 dec_frs_filter(); /* synchronous filtering */
1639 }
1467 1640 /* create the chan buf pointers */ /* create the chan buf pointers */
1468 1641 chans_buf_init(chans_buf, (int)filt_frs.pcm_written_ufrs_n); chans_buf_init(chans_buf, (int)filt_frs.pcm_written_ufrs_n);
1469
1470 filt_frs_remaining_ufrs_n = (snd_pcm_uframes_t)filt_frs.av->frames_n
1642 filt_frs_remaining_ufrs_n = (snd_pcm_ufrs_t)filt_frs.av->frs_n
1471 1643 - filt_frs.pcm_written_ufrs_n; - filt_frs.pcm_written_ufrs_n;
1472 1644 if (filt_frs_remaining_ufrs_n > ufrs_n) if (filt_frs_remaining_ufrs_n > ufrs_n)
1473 1645 ufrs_to_write_n = ufrs_n; ufrs_to_write_n = ufrs_n;
 
... ... static void pcm_filt_frs_write(snd_pcm_uframes_t ufrs_n) { loop
1476 1648
1477 1649 loop { loop {
1478 1650 int is_planar_fmt; int is_planar_fmt;
1479 snd_pcm_uframes_t written_ufrs_n;
1651 snd_pcm_ufrs_t written_ufrs_n;
1480 1652
1481 is_planar_fmt = av_frame_fmt_is_planar(filt_frs.av->format);
1653 is_planar_fmt = av_fr_fmt_is_planar(filt_frs.av->fmt);
1482 1654 if (is_planar_fmt == NO) if (is_planar_fmt == NO)
1483 1655 r0 = snd_pcm_writei(pcm_g, chans_buf[0], r0 = snd_pcm_writei(pcm_g, chans_buf[0],
1484 1656 ufrs_to_write_n); ufrs_to_write_n);
 
... ... static void pcm_filt_frs_write(snd_pcm_uframes_t ufrs_n) { loop
1502 1674 fatal("alsa:fatal/unhandled error while writing the frames\n"); fatal("alsa:fatal/unhandled error while writing the frames\n");
1503 1675 } }
1504 1676 /* r0 >= 0 */ /* r0 >= 0 */
1505 written_ufrs_n = (snd_pcm_uframes_t)r0;
1677 written_ufrs_n = (snd_pcm_ufrs_t)r0;
1506 1678 filt_frs.pcm_written_ufrs_n += written_ufrs_n; filt_frs.pcm_written_ufrs_n += written_ufrs_n;
1507 1679 ufrs_n -= written_ufrs_n; ufrs_n -= written_ufrs_n;
1508 1680 ufrs_to_write_n -= written_ufrs_n; ufrs_to_write_n -= written_ufrs_n;
1509
1510 1681 chans_buf_inc(chans_buf, (int)written_ufrs_n); chans_buf_inc(chans_buf, (int)written_ufrs_n);
1511
1512 1682 if (ufrs_to_write_n == 0) if (ufrs_to_write_n == 0)
1513 1683 break; break;
1514 1684 } }
1515 if (filt_frs.pcm_written_ufrs_n
1516 == (snd_pcm_uframes_t)filt_frs.av->frames_n) {
1517 av_frame_unref(filt_frs.av);
1518
1519 if (!filt_frs_get()) { /* no more filt frs ? */
1520 loop { /* spinning */
1521 int r1;
1522 snd_pcm_state_t state;
1523
1524 r1 = snd_pcm_drain(pcm_g);
1525 if (r1 == 0)
1526 break;
1527 if (r1 == -EAGAIN)
1528 continue;
1529 /*
1530 * the pcm state can change asynchronously.
1531 * _old_ behavior:
1532 * if the draining was successful, the pcm
1533 * should be in SETUP state, and in this
1534 * state, snd_pcm_drain will fail
1535 * _new and fixed__ behavior:
1536 * this won't happen because calling
1537 * snd_pcm_drain while in the SETUP state
1538 * won't return an error anymore
1539 */
1540 state = snd_pcm_state(pcm_g);
1541 if (state == SND_PCM_STATE_SETUP)
1542 break;
1543 }
1544 /**********************************************/
1545 exit_ok("finished playing\n");
1546 /**********************************************/
1547 }
1548 }
1549 1685 }} }}
1550 1686 #undef NO #undef NO
1551 1687 static void evt_pcm_write(void) static void evt_pcm_write(void)
1552 1688 { {
1553 snd_pcm_sframes_t r0;
1689 snd_pcm_sfrs_t r0;
1554 1690 /* try only 2 times */ /* try only 2 times */
1555 1691 r0 = snd_pcm_avail(pcm_g); r0 = snd_pcm_avail(pcm_g);
1556 1692 if (r0 < 0) { if (r0 < 0) {
 
... ... static void evt_pcm_write(void)
1571 1707 } }
1572 1708
1573 1709 if (paused) if (paused)
1574 pcm_silence_frs_write((snd_pcm_uframes_t)r0);
1710 pcm_silence_frs_write((snd_pcm_ufrs_t)r0);
1575 1711 else else
1576 pcm_filt_frs_write((snd_pcm_uframes_t)r0);
1712 pcm_filt_frs_write((snd_pcm_ufrs_t)r0);
1577 1713 } }
1578 1714 #define EPOLL_EVTS_N 8 /* why not */ #define EPOLL_EVTS_N 8 /* why not */
1579 1715 static void evts_loop(void) static void evts_loop(void)
 
... ... static void silence_bufs_cfg(snd_pcm_t *pcm, bool print_info)
1628 1764 { {
1629 1765 int r; int r;
1630 1766 snd_pcm_hw_params_t *hw_params; snd_pcm_hw_params_t *hw_params;
1631 snd_pcm_uframes_t buf_ufrs_n;
1632 snd_pcm_format_t fmt;
1767 snd_pcm_ufrs_t buf_ufrs_n;
1768 snd_pcm_fmt_t fmt;
1633 1769 snd_pcm_access_t access; snd_pcm_access_t access;
1634 1770 unsigned int chans_n; unsigned int chans_n;
1635 1771 u8 c; u8 c;
 
... ... static void silence_bufs_cfg(snd_pcm_t *pcm, bool print_info)
1640 1776 r = snd_pcm_hw_params_current(pcm, hw_params); r = snd_pcm_hw_params_current(pcm, hw_params);
1641 1777 if (r != 0) if (r != 0)
1642 1778 fatal("silence:alsa:unable to get the pcm hardware parameters\n"); fatal("silence:alsa:unable to get the pcm hardware parameters\n");
1643 r = snd_pcm_hw_params_get_buffer_size(hw_params, &buf_ufrs_n);
1779 r = snd_pcm_hw_params_get_buf_size(hw_params, &buf_ufrs_n);
1644 1780 if (r < 0) if (r < 0)
1645 fatal("silence:alsa:unable to get the number of frames in the pcm buffer\n");
1646 r = snd_pcm_hw_params_get_format(hw_params, &fmt);
1781 fatal("silence:alsa:unable to get the number of frs in the pcm buffer\n");
1782 r = snd_pcm_hw_params_get_fmt(hw_params, &fmt);
1647 1783 if (r < 0) if (r < 0)
1648 1784 fatal("silence:alsa:unable to get the pcm format\n"); fatal("silence:alsa:unable to get the pcm format\n");
1649 1785 r = snd_pcm_hw_params_get_access(hw_params, &access); r = snd_pcm_hw_params_get_access(hw_params, &access);
1650 1786 if (r < 0) if (r < 0)
1651 1787 fatal("silence:alsa:unable to get the pcm access mode\n"); fatal("silence:alsa:unable to get the pcm access mode\n");
1652 r = snd_pcm_hw_params_get_channels(hw_params, &chans_n);
1788 r = snd_pcm_hw_params_get_chans(hw_params, &chans_n);
1653 1789 if (r < 0) if (r < 0)
1654 1790 fatal("silence:alsa:unable to get the pcm number of channels\n"); fatal("silence:alsa:unable to get the pcm number of channels\n");
1655 1791 /* wipe silence bufs first */ /* wipe silence bufs first */
 
... ... static void silence_bufs_cfg(snd_pcm_t *pcm, bool print_info)
1667 1803 || access == SND_PCM_ACCESS_MMAP_INTERLEAVED) { || access == SND_PCM_ACCESS_MMAP_INTERLEAVED) {
1668 1804 ssize_t buf_bytes_n; ssize_t buf_bytes_n;
1669 1805
1670 buf_bytes_n = snd_pcm_frames_to_bytes(pcm,
1671 (snd_pcm_sframes_t)buf_ufrs_n);
1806 buf_bytes_n = snd_pcm_frs_to_bytes(pcm,
1807 (snd_pcm_sfrs_t)buf_ufrs_n);
1672 1808 if (buf_bytes_n <= 0) if (buf_bytes_n <= 0)
1673 1809 fatal("silence:alsa:interleaved:unable to get the pcm number of bytes of all buffer frames\n"); fatal("silence:alsa:interleaved:unable to get the pcm number of bytes of all buffer frames\n");
1674 1810 silence_bufs[0] = malloc((size_t)buf_bytes_n); silence_bufs[0] = malloc((size_t)buf_bytes_n);
 
... ... static void silence_bufs_cfg(snd_pcm_t *pcm, bool print_info)
1676 1812 fatal("silence:interleaved:unable to allocate the silence buffer of %d bytes\n", (int)buf_bytes_n); fatal("silence:interleaved:unable to allocate the silence buffer of %d bytes\n", (int)buf_bytes_n);
1677 1813 if (print_info) if (print_info)
1678 1814 pout("silence:interleaved:buffer of %d bytes is allocated\n", (int)buf_bytes_n); pout("silence:interleaved:buffer of %d bytes is allocated\n", (int)buf_bytes_n);
1679 r = snd_pcm_format_set_silence(fmt, silence_bufs[0],
1815 r = snd_pcm_fmt_set_silence(fmt, silence_bufs[0],
1680 1816 (unsigned int)buf_ufrs_n); (unsigned int)buf_ufrs_n);
1681 1817 if (r < 0) if (r < 0)
1682 1818 fatal("silence:interleaved:unable to fill with silence the buffer\n"); fatal("silence:interleaved:unable to fill with silence the buffer\n");
 
... ... static void silence_bufs_cfg(snd_pcm_t *pcm, bool print_info)
1697 1833 silence_bufs[c] = malloc((size_t)buf_bytes_n); silence_bufs[c] = malloc((size_t)buf_bytes_n);
1698 1834 if (silence_bufs[c] == 0) if (silence_bufs[c] == 0)
1699 1835 fatal("silence:non interleaved:unable to allocate silence buffer %u of %d bytes\n", c, (int)buf_bytes_n); fatal("silence:non interleaved:unable to allocate silence buffer %u of %d bytes\n", c, (int)buf_bytes_n);
1700 r = snd_pcm_format_set_silence(fmt, silence_bufs[c],
1836 r = snd_pcm_fmt_set_silence(fmt, silence_bufs[c],
1701 1837 (unsigned int)buf_samples_n); (unsigned int)buf_samples_n);
1702 1838 if (r < 0) if (r < 0)
1703 1839 fatal("silence:non interleaved:unable to fill with silence the buffer\n"); fatal("silence:non interleaved:unable to fill with silence the buffer\n");
 
... ... static void silence_bufs_cfg(snd_pcm_t *pcm, bool print_info)
1711 1847 fatal("silence:the pcm access type is not supported\n"); fatal("silence:the pcm access type is not supported\n");
1712 1848 snd_pcm_hw_params_free(hw_params); snd_pcm_hw_params_free(hw_params);
1713 1849 } }
1714 static void ffmpeg_log_stdout(void *a, int b, const char *fmt, va_list ap)
1850 static void ff_log_stdout(void *a, int b, const char *fmt, va_list ap)
1715 1851 { {
1716 1852 vprintf(fmt, ap); vprintf(fmt, ap);
1717 1853 } }
1854 struct ff_supported_fr_fmt_t {
1855 u8 *str;
1856 enum av_fr_fmt fmt;
1857 };
1858 /* this is the intersection of ff audio fr fmt and alsa pcm fmt */
1859 static struct ff_supported_fr_fmt_t ff_supported_fr_fmts[] = {
1860 {"u8", AV_FR_FMT_U8},
1861 {"u8planar", AV_FR_FMT_U8P},
1862 {"s16", AV_FR_FMT_S16},
1863 {"s16planar", AV_FR_FMT_S16P},
1864 {"s32", AV_FR_FMT_S32},
1865 {"s32planar", AV_FR_FMT_S32P},
1866 {"float32", AV_FR_FMT_FLT},
1867 {"float32planar", AV_FR_FMT_FLTP},
1868 {"float64", AV_FR_FMT_DBL},
1869 {"float64planar", AV_FR_FMT_DBLP},
1870 {0,0}
1871 };
1718 1872 static void usage(void) static void usage(void)
1719 1873 { {
1874 struct ff_supported_fr_fmt_t *fmt;
1875
1720 1876 pout("\ pout("\
1721 npa [-p alsa pcm] [-v volume(0..100)] [-h] url\n");
1877 npa [-p alsa pcm] [-v volume(0..100)]\n\
1878 [-fc override initial ffmpeg count of channels used to approximate the alsa\n\
1879 pcm configuration]\n\
1880 [-fr override initial ffmpeg rate(hz) used to approximate the alsa pcm\n\
1881 configuration]\n\
1882 [-ff override initial ffmpeg audio frame format used to approximate the alsa\n\
1883 pcm configuration, see below for a list]\n\
1884 [-h]\n\
1885 url\n\
1886 \n\
1887 the ffmpeg audio frame formats which intersect alsa pcm audio formats are:\n");
1888
1889 fmt = ff_supported_fr_fmts;
1890 loop {
1891 if (fmt->str == 0)
1892 break;
1893 pout("\t%s\n", fmt->str);
1894 ++fmt;
1895 }
1722 1896 } }
1723 1897 static void opts_parse(int argc, u8 **args, u8 **url, u8 **pcm_str, static void opts_parse(int argc, u8 **args, u8 **url, u8 **pcm_str,
1724 double *initial_vol)
1898 double *initial_vol, int *override_initial_ff_chans_n,
1899 int *override_initial_ff_rate,
1900 enum av_fr_fmt *override_initial_ff_fr_fmt)
1725 1901 { {
1726 1902 int i; int i;
1727 1903 int url_idx; int url_idx;
 
... ... static void opts_parse(int argc, u8 **args, u8 **url, u8 **pcm_str,
1748 1924 *initial_vol = (double)vol_ul / 100.0; *initial_vol = (double)vol_ul / 100.0;
1749 1925 pout("-v:using initial volume %f\n", *initial_vol); pout("-v:using initial volume %f\n", *initial_vol);
1750 1926 i += 2; i += 2;
1927 /*------------------------------------------------------------*/
1928 /* ff initial override for alsa pcm cfg -- start */
1929 } else if (strcmp("-fr", args[i]) == 0) {
1930 if ((i + 1) == argc) {
1931 perr("-fr:override initial ffmpeg rate(hz) is missing\n");
1932 usage();
1933 exit(1);
1934 }
1935 *override_initial_ff_rate = (int)strtol(args[i + 1], 0,
1936 10);
1937 pout("-fr:override initial ffmpeg audio rate to %dHz used for alsa pcm configuration\n", *override_initial_ff_rate);
1938 i += 2;
1939 } else if (strcmp("-fc", args[i]) == 0) {
1940 if ((i + 1) == argc) {
1941 perr("-fc:override initial ffmpeg channel count is missing\n");
1942 usage();
1943 exit(1);
1944 }
1945 *override_initial_ff_chans_n = (int)strtol(args[i + 1],
1946 0, 10);
1947 pout("-fc:override initial ffmpeg count of channels to %d used for alsa pcm configuration\n", *override_initial_ff_chans_n);
1948 i += 2;
1949 } else if (strcmp("-ff", args[i]) == 0) {
1950 struct ff_supported_fr_fmt_t *fmt;
1951
1952 if ((i + 1) == argc) {
1953 perr("-fc:override initial ffmpeg audio frame format is missing\n");
1954 usage();
1955 exit(1);
1956 }
1957 fmt = ff_supported_fr_fmts;
1958 loop {
1959 if (fmt->str == 0) {
1960 perr("-ff:unknown ffmpeg audio frame format\n");
1961 usage();
1962 exit(1);
1963 }
1964 if (strcmp(fmt->str, args[i + 1]) == 0) {
1965 *override_initial_ff_fr_fmt = fmt->fmt;
1966 break;
1967 }
1968 ++fmt;
1969 }
1970 pout("-ff:override initial ffmpeg audio frame format is %s\n", av_get_fr_fmt_name(*override_initial_ff_fr_fmt));
1971 i += 2;
1972 /* ff initial override for alsa pcm cfg -- end */
1973 /*------------------------------------------------------------*/
1751 1974 } else if (strcmp("-h", args[i]) == 0) { } else if (strcmp("-h", args[i]) == 0) {
1752 1975 usage(); usage();
1753 1976 exit(0); exit(0);
 
... ... static void opts_parse(int argc, u8 **args, u8 **url, u8 **pcm_str,
1762 1985 pout("playing ####%s####\n", *url); pout("playing ####%s####\n", *url);
1763 1986 } }
1764 1987 #define RESET_DONE 0 #define RESET_DONE 0
1988 #define DONT_HOLD 0
1765 1989 static void cb_init_once(void) static void cb_init_once(void)
1766 1990 { {
1767 1991 u8 i; u8 i;
 
... ... static void cb_init_once(void)
1779 2003 atomic_store(&cb.sd, 0); atomic_store(&cb.sd, 0);
1780 2004 atomic_store(&cb.st_idx, -1); atomic_store(&cb.st_idx, -1);
1781 2005 atomic_store(&cb.reset, RESET_DONE); atomic_store(&cb.reset, RESET_DONE);
2006 atomic_store(&cb.hold, DONT_HOLD);
1782 2007 } }
1783 2008 #undef RESET_DONE #undef RESET_DONE
1784 static void filter_graph_init_once(void)
2009 #undef DONT_HOLD
2010 static void filt_graph_init_once(void)
1785 2011 { {
1786 filter_graph = 0;
2012 filt_graph = 0;
1787 2013 abufsrc_ctx = 0; abufsrc_ctx = 0;
1788 2014 abufsrc_filt = 0; abufsrc_filt = 0;
1789 2015 vol_ctx = 0; vol_ctx = 0;
 
... ... static void filter_graph_init_once(void)
1795 2021 /* floating point strs are localized... */ /* floating point strs are localized... */
1796 2022 snprintf(double_zero_l10n_str, sizeof(double_zero_l10n_str), "%f", 0.); snprintf(double_zero_l10n_str, sizeof(double_zero_l10n_str), "%f", 0.);
1797 2023 memset(&filt_frs, 0, sizeof(filt_frs)); memset(&filt_frs, 0, sizeof(filt_frs));
1798 filt_frs.av = av_frames_alloc();
2024 filt_frs.av = av_frs_alloc();
1799 2025 if (filt_frs.av == 0) if (filt_frs.av == 0)
1800 2026 fatal("ffmpeg:unable to allocate a filtered frames structure\n"); fatal("ffmpeg:unable to allocate a filtered frames structure\n");
2027 filt_frs.pcm_written_ufrs_n = 0;
1801 2028 } }
1802 2029 static void dec_init_once(void) static void dec_init_once(void)
1803 2030 { {
1804 2031 dec = 0; dec = 0;
1805 2032 dec_ctx = 0; dec_ctx = 0;
1806 dec_frs.av = av_frames_alloc();
2033 dec_frs.av = av_frs_alloc();
1807 2034 if (dec_frs.av == 0) if (dec_frs.av == 0)
1808 2035 fatal("ffmpeg:unable to allocate a decoded frames structure\n"); fatal("ffmpeg:unable to allocate a decoded frames structure\n");
2036 dec_frs.pushed_in_filt_graph = true;
1809 2037 dec_frs.most_recent_ts = AV_NOPTS_VALUE; dec_frs.most_recent_ts = AV_NOPTS_VALUE;
1810 2038 } }
1811 2039 static void rd_thd_init_once(void) static void rd_thd_init_once(void)
 
... ... static void fmt_init_once(u8 *url)
1819 2047 int r; int r;
1820 2048
1821 2049 fmt_ctx = 0; fmt_ctx = 0;
1822 r = avformat_open_input(&fmt_ctx, url, NULL, NULL);
2050 r = av_fmt_open_input(&fmt_ctx, url, NULL, NULL);
1823 2051 if (r < 0) if (r < 0)
1824 2052 fatal("ffmpeg:unable to open \"%s\"\n", url); fatal("ffmpeg:unable to open \"%s\"\n", url);
1825 2053 /* probe beyond the header, if any */ /* probe beyond the header, if any */
1826 r = avformat_find_stream_info(fmt_ctx, 0);
2054 r = av_fmt_find_st_info(fmt_ctx, 0);
1827 2055 if (r < 0) if (r < 0)
1828 2056 fatal("ffmpeg:unable to probe \"%s\"\n", url); fatal("ffmpeg:unable to probe \"%s\"\n", url);
1829 2057 r = pthread_mutex_init(&fmt_ctx_mutex, 0); r = pthread_mutex_init(&fmt_ctx_mutex, 0);
 
... ... static void pcm_init_once(u8 *pcm_str)
1840 2068 r = snd_output_stdio_attach(&pcm_perr, stderr, 0); r = snd_output_stdio_attach(&pcm_perr, stderr, 0);
1841 2069 if (r < 0) if (r < 0)
1842 2070 fatal("alsa:unable to attach stderr\n"); fatal("alsa:unable to attach stderr\n");
1843 r = snd_pcm_open(&pcm_g, pcm_str, SND_PCM_STREAM_PLAYBACK,
2071 r = snd_pcm_open(&pcm_g, pcm_str, SND_PCM_ST_PLAYBACK,
1844 2072 SND_PCM_NONBLOCK); SND_PCM_NONBLOCK);
1845 2073 if (r < 0) { if (r < 0) {
1846 2074 if (r == -EAGAIN) if (r == -EAGAIN)
 
... ... static void init_once(u8 *url, u8 *pcm_str)
1868 2096 stdout_init_once(); stdout_init_once();
1869 2097 input_state_init_once(); input_state_init_once();
1870 2098 cb_init_once(); cb_init_once();
1871 filter_graph_init_once();
2099 filt_graph_init_once();
1872 2100 silence_bufs_init_once(); silence_bufs_init_once();
1873 2101 dec_init_once(); dec_init_once();
1874 2102 pcm_init_once(pcm_str); pcm_init_once(pcm_str);
 
... ... static int find_best_st(void)
1880 2108 { {
1881 2109 int r; int r;
1882 2110
1883 r = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, 0, 0);
2111 r = av_find_best_st(fmt_ctx, AV_MEDIA_TYPE_AUDIO, -1, -1, 0, 0);
1884 2112 if (r < 0) if (r < 0)
1885 2113 fatal("ffmpeg:no audio stream found\n"); fatal("ffmpeg:no audio stream found\n");
1886 2114 return r; return r;
 
... ... static void pcm_hw_chans_n_decide(snd_pcm_t *pcm,
1892 2120 unsigned int chans_n_max; unsigned int chans_n_max;
1893 2121 unsigned int chans_n_min; unsigned int chans_n_min;
1894 2122
1895 r = snd_pcm_hw_params_test_channels(pcm, pcm_hw_params, chans_n);
2123 r = snd_pcm_hw_params_test_chans(pcm, pcm_hw_params, chans_n);
1896 2124 if (r == 0) { if (r == 0) {
1897 r = snd_pcm_hw_params_set_channels(pcm, pcm_hw_params, chans_n);
2125 r = snd_pcm_hw_params_set_chans(pcm, pcm_hw_params, chans_n);
1898 2126 if (r != 0) if (r != 0)
1899 2127 fatal("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n); fatal("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n);
1900 2128 pout("alsa:using %u channels\n", chans_n); pout("alsa:using %u channels\n", chans_n);
 
... ... static void pcm_hw_chans_n_decide(snd_pcm_t *pcm,
1902 2130 } }
1903 2131 pout("alsa:unable to use %u channels\n", chans_n); pout("alsa:unable to use %u channels\n", chans_n);
1904 2132 /* try to use the max chans n the pcm can */ /* try to use the max chans n the pcm can */
1905 r = snd_pcm_hw_params_get_channels_max(pcm_hw_params, &chans_n_max);
2133 r = snd_pcm_hw_params_get_chans_max(pcm_hw_params, &chans_n_max);
1906 2134 if (r != 0) if (r != 0)
1907 2135 fatal("alsa:unable to get the maximum count of pcm device channels\n"); fatal("alsa:unable to get the maximum count of pcm device channels\n");
1908 r = snd_pcm_hw_params_test_channels(pcm, pcm_hw_params, chans_n_max);
2136 r = snd_pcm_hw_params_test_chans(pcm, pcm_hw_params, chans_n_max);
1909 2137 if (r == 0) { if (r == 0) {
1910 r = snd_pcm_hw_params_set_channels(pcm, pcm_hw_params,
2138 r = snd_pcm_hw_params_set_chans(pcm, pcm_hw_params,
1911 2139 chans_n_max); chans_n_max);
1912 2140 if (r != 0) if (r != 0)
1913 2141 fatal("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n_max); fatal("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n_max);
 
... ... static void pcm_hw_chans_n_decide(snd_pcm_t *pcm,
1915 2143 return; return;
1916 2144 } }
1917 2145 /* ok... last try, the pcm dev min chans n */ /* ok... last try, the pcm dev min chans n */
1918 r = snd_pcm_hw_params_get_channels_min(pcm_hw_params, &chans_n_min);
2146 r = snd_pcm_hw_params_get_chans_min(pcm_hw_params, &chans_n_min);
1919 2147 if (r != 0) if (r != 0)
1920 2148 fatal("alsa:unable to get the minimum count of pcm device channels\n"); fatal("alsa:unable to get the minimum count of pcm device channels\n");
1921 r = snd_pcm_hw_params_test_channels(pcm, pcm_hw_params, chans_n_min);
2149 r = snd_pcm_hw_params_test_chans(pcm, pcm_hw_params, chans_n_min);
1922 2150 if (r == 0) { if (r == 0) {
1923 r = snd_pcm_hw_params_set_channels(pcm, pcm_hw_params,
2151 r = snd_pcm_hw_params_set_chans(pcm, pcm_hw_params,
1924 2152 chans_n_min); chans_n_min);
1925 2153 if (r != 0) if (r != 0)
1926 2154 fatal("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n_min); fatal("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n_min);
 
... ... static void pcm_hw_rate_decide(snd_pcm_t *pcm,
1938 2166 unsigned int rate_min; unsigned int rate_min;
1939 2167
1940 2168 r = snd_pcm_hw_params_test_rate(pcm, pcm_hw_params, rate, r = snd_pcm_hw_params_test_rate(pcm, pcm_hw_params, rate,
1941 SND_PCM_STREAM_PLAYBACK);
2169 SND_PCM_ST_PLAYBACK);
1942 2170 if (r == 0) { if (r == 0) {
1943 2171 r = snd_pcm_hw_params_set_rate(pcm, pcm_hw_params, rate, r = snd_pcm_hw_params_set_rate(pcm, pcm_hw_params, rate,
1944 SND_PCM_STREAM_PLAYBACK);
2172 SND_PCM_ST_PLAYBACK);
1945 2173 if (r != 0) if (r != 0)
1946 2174 fatal("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate); fatal("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate);
1947 2175 pout("alsa:using %uHz\n", rate); pout("alsa:using %uHz\n", rate);
 
... ... static void pcm_hw_rate_decide(snd_pcm_t *pcm,
1950 2178 pout("alsa:unable to use %uHz\n", rate); pout("alsa:unable to use %uHz\n", rate);
1951 2179 /* try to use the max rate the pcm can */ /* try to use the max rate the pcm can */
1952 2180 r = snd_pcm_hw_params_get_rate_max(pcm_hw_params, &rate_max, r = snd_pcm_hw_params_get_rate_max(pcm_hw_params, &rate_max,
1953 SND_PCM_STREAM_PLAYBACK);
2181 SND_PCM_ST_PLAYBACK);
1954 2182 if (r != 0) if (r != 0)
1955 2183 fatal("alsa:unable to get the maximum rate of pcm device\n"); fatal("alsa:unable to get the maximum rate of pcm device\n");
1956 2184 r = snd_pcm_hw_params_test_rate(pcm, pcm_hw_params, rate_max, r = snd_pcm_hw_params_test_rate(pcm, pcm_hw_params, rate_max,
1957 SND_PCM_STREAM_PLAYBACK);
2185 SND_PCM_ST_PLAYBACK);
1958 2186 if (r == 0) { if (r == 0) {
1959 2187 r = snd_pcm_hw_params_set_rate(pcm, pcm_hw_params, rate_max, r = snd_pcm_hw_params_set_rate(pcm, pcm_hw_params, rate_max,
1960 SND_PCM_STREAM_PLAYBACK);
2188 SND_PCM_ST_PLAYBACK);
1961 2189 if (r != 0) if (r != 0)
1962 2190 fatal("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate_max); fatal("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate_max);
1963 2191 pout("alsa:using pcm device %uHz\n", rate_max); pout("alsa:using pcm device %uHz\n", rate_max);
 
... ... static void pcm_hw_rate_decide(snd_pcm_t *pcm,
1966 2194 /* try to use a rate "near" of what the pcm dev can */ /* try to use a rate "near" of what the pcm dev can */
1967 2195 rate_near = rate; rate_near = rate;
1968 2196 r = snd_pcm_hw_params_set_rate_near(pcm, pcm_hw_params, &rate_near, r = snd_pcm_hw_params_set_rate_near(pcm, pcm_hw_params, &rate_near,
1969 SND_PCM_STREAM_PLAYBACK);
2197 SND_PCM_ST_PLAYBACK);
1970 2198 if (r == 0) { if (r == 0) {
1971 2199 pout("alsa:using pcm device %uHz\n", rate_near); pout("alsa:using pcm device %uHz\n", rate_near);
1972 2200 return; return;
1973 2201 } }
1974 2202 /* even a "near" rate did failed... try the min */ /* even a "near" rate did failed... try the min */
1975 2203 r = snd_pcm_hw_params_get_rate_min(pcm_hw_params, &rate_min, r = snd_pcm_hw_params_get_rate_min(pcm_hw_params, &rate_min,
1976 SND_PCM_STREAM_PLAYBACK);
2204 SND_PCM_ST_PLAYBACK);
1977 2205 if (r != 0) if (r != 0)
1978 2206 fatal("alsa:unable to get the minimum rate of pcm device\n"); fatal("alsa:unable to get the minimum rate of pcm device\n");
1979 2207 r = snd_pcm_hw_params_test_rate(pcm, pcm_hw_params, rate_min, r = snd_pcm_hw_params_test_rate(pcm, pcm_hw_params, rate_min,
1980 SND_PCM_STREAM_PLAYBACK);
2208 SND_PCM_ST_PLAYBACK);
1981 2209 if (r == 0) { if (r == 0) {
1982 2210 r = snd_pcm_hw_params_set_rate(pcm, pcm_hw_params, rate_min, r = snd_pcm_hw_params_set_rate(pcm, pcm_hw_params, rate_min,
1983 SND_PCM_STREAM_PLAYBACK);
2211 SND_PCM_ST_PLAYBACK);
1984 2212 if (r != 0) if (r != 0)
1985 2213 fatal("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate_min); fatal("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate_min);
1986 2214 pout("alsa:using pcm device %uHz\n", rate_min); pout("alsa:using pcm device %uHz\n", rate_min);
 
... ... static void pcm_hw_rate_decide(snd_pcm_t *pcm,
1988 2216 } }
1989 2217 fatal("alsa:unable to find a suitable rate\n"); fatal("alsa:unable to find a suitable rate\n");
1990 2218 } }
1991 static bool ff_fmt2pcm_layout_best_effort(enum AVSampleFormat ff_fmt,
1992 snd_pcm_format_t *alsa_fmt, snd_pcm_access_t *alsa_access)
2219 static bool ff_fmt2pcm_layout_best_effort(enum av_fr_fmt ff_fmt,
2220 snd_pcm_fmt_t *alsa_fmt, snd_pcm_access_t *alsa_access)
1993 2221 { {
1994 2222 static u8 ff_fmt_str[STR_SZ]; static u8 ff_fmt_str[STR_SZ];
1995 2223
1996 av_get_sample_fmt_string(ff_fmt_str, STR_SZ, ff_fmt);
2224 av_get_fr_fmt_str(ff_fmt_str, STR_SZ, ff_fmt);
1997 2225 /* XXX: only classic non-mmap ones */ /* XXX: only classic non-mmap ones */
1998 2226 switch (ff_fmt) { switch (ff_fmt) {
1999 case AV_SAMPLE_FMT_U8:
2000 *alsa_fmt = SND_PCM_FORMAT_U8;
2227 case AV_FR_FMT_U8:
2228 *alsa_fmt = SND_PCM_FMT_U8;
2001 2229 *alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED; *alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED;
2002 2230 break; break;
2003 case AV_SAMPLE_FMT_S16:
2004 *alsa_fmt = SND_PCM_FORMAT_S16;
2231 case AV_FR_FMT_S16:
2232 *alsa_fmt = SND_PCM_FMT_S16;
2005 2233 *alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED; *alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED;
2006 2234 break; break;
2007 case AV_SAMPLE_FMT_S32:
2008 *alsa_fmt = SND_PCM_FORMAT_S32;
2235 case AV_FR_FMT_S32:
2236 *alsa_fmt = SND_PCM_FMT_S32;
2009 2237 *alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED; *alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED;
2010 2238 break; break;
2011 case AV_SAMPLE_FMT_FLT:
2012 *alsa_fmt = SND_PCM_FORMAT_FLOAT;
2239 case AV_FR_FMT_FLT:
2240 *alsa_fmt = SND_PCM_FMT_FLT;
2013 2241 *alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED; *alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED;
2014 2242 break; break;
2015 2243 /* ff "planar" fmts are actually non interleaved fmts */ /* ff "planar" fmts are actually non interleaved fmts */
2016 case AV_SAMPLE_FMT_U8P:
2017 *alsa_fmt = SND_PCM_FORMAT_U8;
2244 case AV_FR_FMT_U8P:
2245 *alsa_fmt = SND_PCM_FMT_U8;
2018 2246 *alsa_access = SND_PCM_ACCESS_RW_NONINTERLEAVED; *alsa_access = SND_PCM_ACCESS_RW_NONINTERLEAVED;
2019 2247 break; break;
2020 case AV_SAMPLE_FMT_S16P:
2021 *alsa_fmt = SND_PCM_FORMAT_S16;
2248 case AV_FR_FMT_S16P:
2249 *alsa_fmt = SND_PCM_FMT_S16;
2022 2250 *alsa_access = SND_PCM_ACCESS_RW_NONINTERLEAVED; *alsa_access = SND_PCM_ACCESS_RW_NONINTERLEAVED;
2023 2251 break; break;
2024 case AV_SAMPLE_FMT_S32P:
2025 *alsa_fmt = SND_PCM_FORMAT_S32;
2252 case AV_FR_FMT_S32P:
2253 *alsa_fmt = SND_PCM_FMT_S32;
2026 2254 *alsa_access = SND_PCM_ACCESS_RW_NONINTERLEAVED; *alsa_access = SND_PCM_ACCESS_RW_NONINTERLEAVED;
2027 2255 break; break;
2028 case AV_SAMPLE_FMT_FLTP:
2029 *alsa_fmt = SND_PCM_FORMAT_FLOAT;
2256 case AV_FR_FMT_FLTP:
2257 *alsa_fmt = SND_PCM_FMT_FLT;
2030 2258 *alsa_access = SND_PCM_ACCESS_RW_NONINTERLEAVED; *alsa_access = SND_PCM_ACCESS_RW_NONINTERLEAVED;
2031 2259 break; break;
2032 2260 default: default:
2033 2261 pout("best effort:unable to wire ffmpeg sample format \"%sbits\" to alsa sample format, \n,", ff_fmt_str); pout("best effort:unable to wire ffmpeg sample format \"%sbits\" to alsa sample format, \n,", ff_fmt_str);
2034 2262 return false; return false;
2035 2263 } }
2036 pout("best effort:ffmpeg format \"%sbits\" (%u bytes) to alsa layout \"%s\" and access \"%s\"\n", ff_fmt_str, av_get_bytes_per_sample(ff_fmt), snd_pcm_format_description(*alsa_fmt), snd_pcm_access_name(*alsa_access));
2264 pout("best effort:ffmpeg format \"%sbits\" (%u bytes) to alsa layout \"%s\" and access \"%s\"\n", ff_fmt_str, av_get_bytes_per_sample(ff_fmt), snd_pcm_fmt_desc(*alsa_fmt), snd_pcm_access_name(*alsa_access));
2037 2265 return true; return true;
2038 2266 } }
2039 2267 static bool pcm_hw_fmt_decide_x(snd_pcm_t *pcm, static bool pcm_hw_fmt_decide_x(snd_pcm_t *pcm,
2040 snd_pcm_hw_params_t *pcm_hw_params, snd_pcm_format_t fmt)
2268 snd_pcm_hw_params_t *pcm_hw_params, snd_pcm_fmt_t fmt)
2041 2269 { {
2042 2270 int r; int r;
2043 2271
2044 r = snd_pcm_hw_params_test_format(pcm, pcm_hw_params, fmt);
2272 r = snd_pcm_hw_params_test_fmt(pcm, pcm_hw_params, fmt);
2045 2273 if (r != 0) if (r != 0)
2046 2274 return false; return false;
2047 r = snd_pcm_hw_params_set_format(pcm, pcm_hw_params, fmt);
2275 r = snd_pcm_hw_params_set_fmt(pcm, pcm_hw_params, fmt);
2048 2276 if (r != 0) if (r != 0)
2049 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_format_description(fmt));
2050 pout("alsa:using \"%s\" format\n", snd_pcm_format_description(fmt));
2277 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_fmt_desc(fmt));
2278 pout("alsa:using \"%s\" format\n", snd_pcm_fmt_desc(fmt));
2051 2279 return true; return true;
2052 2280 } }
2053 2281 #define PCM_HW_FMT_DECIDE_X(fmt) pcm_hw_fmt_decide_x(pcm, pcm_hw_params, fmt) #define PCM_HW_FMT_DECIDE_X(fmt) pcm_hw_fmt_decide_x(pcm, pcm_hw_params, fmt)
2054 2282 static void pcm_hw_fmt_decide(snd_pcm_t *pcm, static void pcm_hw_fmt_decide(snd_pcm_t *pcm,
2055 2283 snd_pcm_hw_params_t *pcm_hw_params, bool force, snd_pcm_hw_params_t *pcm_hw_params, bool force,
2056 snd_pcm_format_t forced_fmt)
2284 snd_pcm_fmt_t forced_fmt)
2057 2285 { {
2058 2286 int r; int r;
2059 snd_pcm_format_t *fmt;
2287 snd_pcm_fmt_t *fmt;
2060 2288
2061 2289 if (force) { if (force) {
2062 r = snd_pcm_hw_params_test_format(pcm, pcm_hw_params,
2063 forced_fmt);
2290 r = snd_pcm_hw_params_test_fmt(pcm, pcm_hw_params, forced_fmt);
2064 2291 if (r == 0) { if (r == 0) {
2065 r = snd_pcm_hw_params_set_format(pcm, pcm_hw_params,
2292 r = snd_pcm_hw_params_set_fmt(pcm, pcm_hw_params,
2066 2293 forced_fmt); forced_fmt);
2067 2294 if (r != 0) if (r != 0)
2068 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_format_description(forced_fmt));
2069 pout("alsa:using forced \"%s\" format\n", snd_pcm_format_description(forced_fmt));
2295 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_fmt_desc(forced_fmt));
2296 pout("alsa:using forced \"%s\" format\n", snd_pcm_fmt_desc(forced_fmt));
2070 2297 return; return;
2071 2298 } }
2072 2299 } }
2073 2300 /* then we try to select from the reasonable "best" to the lowest */ /* then we try to select from the reasonable "best" to the lowest */
2074 2301 /* prefer fmts we know supported by ff */ /* prefer fmts we know supported by ff */
2075 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_FLOAT))
2302 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_FLT))
2076 2303 return; return;
2077 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_S32))
2304 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_S32))
2078 2305 return; return;
2079 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_S16))
2306 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_S16))
2080 2307 return; return;
2081 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_U8))
2308 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_U8))
2082 2309 return; return;
2083 2310 /* /*
2084 2311 * from here, at the time of writting, those fmts have no ff * from here, at the time of writting, those fmts have no ff
2085 2312 * wiring, but we are alsa centric here, validate that later * wiring, but we are alsa centric here, validate that later
2086 2313 */ */
2087 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_U32))
2314 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_U32))
2088 2315 return; return;
2089 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_S24))
2316 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_S24))
2090 2317 return; return;
2091 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_U24))
2318 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_U24))
2092 2319 return; return;
2093 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_U16))
2320 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_U16))
2094 2321 return; return;
2095 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FORMAT_S8))
2322 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_S8))
2096 2323 return; return;
2097 2324 fatal("alsa:unable to find a suitable format\n"); fatal("alsa:unable to find a suitable format\n");
2098 2325 } }
 
... ... static void pcm_hw_buf_sz_cfg(snd_pcm_t *pcm,
2155 2382 snd_pcm_hw_params_t *pcm_hw_params) snd_pcm_hw_params_t *pcm_hw_params)
2156 2383 { {
2157 2384 int r; int r;
2158 snd_pcm_uframes_t latency_control_target_buf_ufrs_n;
2159 snd_pcm_uframes_t latency_control_buf_ufrs_n;
2385 snd_pcm_ufrs_t latency_control_target_buf_ufrs_n;
2386 snd_pcm_ufrs_t latency_control_buf_ufrs_n;
2160 2387 unsigned int rate; unsigned int rate;
2161 2388
2162 2389 r = snd_pcm_hw_params_get_rate(pcm_hw_params, &rate, 0); r = snd_pcm_hw_params_get_rate(pcm_hw_params, &rate, 0);
 
... ... static void pcm_hw_buf_sz_cfg(snd_pcm_t *pcm,
2164 2391 warning("alsa:latency control:DISABLING LATENCY CONTROL:unable to get the decided rate from the current device parameters\n"); warning("alsa:latency control:DISABLING LATENCY CONTROL:unable to get the decided rate from the current device parameters\n");
2165 2392 return; return;
2166 2393 } }
2167 latency_control_target_buf_ufrs_n = (snd_pcm_uframes_t)rate;
2394 latency_control_target_buf_ufrs_n = (snd_pcm_ufrs_t)rate;
2168 2395 latency_control_target_buf_ufrs_n /= 4; latency_control_target_buf_ufrs_n /= 4;
2169 2396 latency_control_buf_ufrs_n = latency_control_target_buf_ufrs_n; latency_control_buf_ufrs_n = latency_control_target_buf_ufrs_n;
2170 r = snd_pcm_hw_params_set_buffer_size_near(pcm, pcm_hw_params,
2397 r = snd_pcm_hw_params_set_buf_size_near(pcm, pcm_hw_params,
2171 2398 &latency_control_buf_ufrs_n); &latency_control_buf_ufrs_n);
2172 2399 if (r < 0) { if (r < 0) {
2173 2400 warning("alsa:latency control:DISABLING_LATENCY_CONTROL:unable to set the audio buffer size (count of frames) to %u periods for the current device parameters\n", latency_control_buf_ufrs_n); warning("alsa:latency control:DISABLING_LATENCY_CONTROL:unable to set the audio buffer size (count of frames) to %u periods for the current device parameters\n", latency_control_buf_ufrs_n);
 
... ... static void pcm_cfg_sw(snd_pcm_t *pcm)
2208 2435 * we try to use a sensible restrict order regarding audio props * we try to use a sensible restrict order regarding audio props
2209 2436 */ */
2210 2437 static void pcm_cfg_hw_core(snd_pcm_t *pcm, snd_pcm_hw_params_t *pcm_hw_params, static void pcm_cfg_hw_core(snd_pcm_t *pcm, snd_pcm_hw_params_t *pcm_hw_params,
2211 int chans_n, int rate, enum AVSampleFormat ff_fmt)
2438 int chans_n, int rate, enum av_fr_fmt ff_fmt)
2212 2439 { {
2213 2440 int r; int r;
2214 2441 bool best_effort_wiring_success; bool best_effort_wiring_success;
2215 snd_pcm_format_t fmt_from_best_effort;
2442 snd_pcm_fmt_t fmt_from_best_effort;
2216 2443 snd_pcm_access_t access_from_best_effort; snd_pcm_access_t access_from_best_effort;
2217 2444
2218 2445 /* the return value is from a first refine of the raw hw params */ /* the return value is from a first refine of the raw hw params */
 
... ... static void pcm_cfg_hw_core(snd_pcm_t *pcm, snd_pcm_hw_params_t *pcm_hw_params,
2231 2458 pcm_hw_buf_sz_cfg(pcm, pcm_hw_params); pcm_hw_buf_sz_cfg(pcm, pcm_hw_params);
2232 2459 } }
2233 2460 static void pcm_cfg_hw(snd_pcm_t *pcm, unsigned int chans_n, unsigned int rate, static void pcm_cfg_hw(snd_pcm_t *pcm, unsigned int chans_n, unsigned int rate,
2234 enum AVSampleFormat ff_fmt)
2461 enum av_fr_fmt ff_fmt)
2235 2462 { {
2236 2463 int r; int r;
2237 2464 snd_pcm_access_t access; snd_pcm_access_t access;
 
... ... static void pcm_cfg_hw(snd_pcm_t *pcm, unsigned int chans_n, unsigned int rate,
2253 2480 pout("ALSA:HW_PARAMS END--------------------------------------------------------------\n"); pout("ALSA:HW_PARAMS END--------------------------------------------------------------\n");
2254 2481 } }
2255 2482 static void pcm_cfg(snd_pcm_t *pcm, unsigned int chans_n, unsigned int rate, static void pcm_cfg(snd_pcm_t *pcm, unsigned int chans_n, unsigned int rate,
2256 enum AVSampleFormat ff_fmt)
2483 enum av_fr_fmt ff_fmt)
2257 2484 { {
2258 2485 pcm_cfg_hw(pcm, chans_n, rate, ff_fmt); pcm_cfg_hw(pcm, chans_n, rate, ff_fmt);
2259 2486 pcm_cfg_sw(pcm); pcm_cfg_sw(pcm);
 
... ... static void evt_pcm_install(void)
2281 2508 } }
2282 2509 pout("alsa:pcm events installed\n"); pout("alsa:pcm events installed\n");
2283 2510 } }
2284 static void evt_pcm_uninstall(void)
2285 {
2286 u8 i;
2287
2288 i = 0;
2289 loop {
2290 if (i == pcm_pollfds_n)
2291 break;
2292 (void)epoll_ctl(ep_fd, EPOLL_CTL_DEL, pcm_pollfds[i].fd, 0);
2293 ++i;
2294 }
2295 pout("alsa:pcm events uninstalled\n");
2296 }
2297 2511 #define PRINT_INFO true #define PRINT_INFO true
2298 static void play(int st_idx, double initial_vol, bool do_rd_thd_reset)
2299 {
2300 enum AVSampleFormat dst_fmt;
2512 #define CHANS_N_NOT_OVERRIDDEN 0
2513 #define RATE_NOT_OVERRIDDEN 0
2514 #define FR_FMT_NOT_OVERRIDDEN AV_FR_FMT_NONE
2515 static void prepare(int st_idx, double initial_vol,
2516 int override_initial_ff_chans_n, int override_initial_ff_rate,
2517 enum av_fr_fmt override_initial_ff_audio_fr_fmt)
2518 {
2519 enum av_fr_fmt dst_fmt;
2301 2520 int dst_rate; int dst_rate;
2302 2521 int dst_chans_n; int dst_chans_n;
2303 2522 uint64_t src_chans_layout; uint64_t src_chans_layout;
2304 2523 uint64_t dst_chans_layout; uint64_t dst_chans_layout;
2524 int initial_ff_chans_n;
2525 int initial_ff_rate;
2526 enum av_fr_fmt initial_ff_audio_fr_fmt;
2305 2527
2306 2528 current_st_idx = st_idx; current_st_idx = st_idx;
2307 /* XXX: reset will flush all pkts dmuxed by the the rd thd until now */
2308 if (do_rd_thd_reset)
2309 rd_thd_reset(st_idx);
2310 2529 fmt_ctx_lock(); fmt_ctx_lock();
2311 dec_ctx_cfg(fmt_ctx->streams[st_idx]->codecpar);
2312 dec_frs.most_recent_ts = fmt_ctx->streams[st_idx]->start_time;
2530 dec_ctx_cfg(fmt_ctx->sts[st_idx]->codecpar);
2531 dec_frs.most_recent_ts = fmt_ctx->sts[st_idx]->start_time;
2313 2532 cmd_info_data.fmt.duration = fmt_ctx->duration; cmd_info_data.fmt.duration = fmt_ctx->duration;
2314 2533 cmd_info_data.fmt.m = fmt_ctx->duration_estimation_method; cmd_info_data.fmt.m = fmt_ctx->duration_estimation_method;
2315 cmd_info_data.st.tb = fmt_ctx->streams[st_idx]->time_base;
2316 cmd_info_data.st.id = fmt_ctx->streams[st_idx]->id;
2317 cmd_info_data.st.duration = fmt_ctx->streams[st_idx]->duration;
2534 cmd_info_data.st.tb = fmt_ctx->sts[st_idx]->tb;
2535 cmd_info_data.st.id = fmt_ctx->sts[st_idx]->id;
2536 cmd_info_data.st.duration = fmt_ctx->sts[st_idx]->duration;
2318 2537 fmt_ctx_unlock(); fmt_ctx_unlock();
2319 2538
2320 evt_pcm_uninstall();
2321 /*
2322 * do our best to match the pcm cfg to audio ff dec output, BUT we don't
2323 * expect to match it "exactly": see right below why
2324 */
2325 pcm_cfg(pcm_g, dec_ctx->channels, dec_ctx->sample_rate,
2326 dec_ctx->sample_fmt);
2327 evt_pcm_install();
2328 /* use a ff filt to fill in the gap between the pcm and audio ff dec */
2329 pcm2ff(pcm_g, &dst_fmt, &dst_rate, &dst_chans_n,
2330 &dst_chans_layout, PRINT_INFO);
2331 /* the audio dec ctx may not have a valid chans layout */
2332 if (dec_ctx->channel_layout == 0) {
2333 src_chans_layout = av_get_default_channel_layout(
2334 dec_ctx->channels);
2335 } else
2336 src_chans_layout = dec_ctx->channel_layout;
2337 filter_graph_cfg(
2338 dec_ctx->sample_fmt, dec_ctx->sample_rate,
2339 dec_ctx->channels, src_chans_layout,
2340 false, initial_vol,
2341 dst_fmt, dst_rate, dst_chans_n, dst_chans_layout,
2342 PRINT_INFO);
2539 if (override_initial_ff_chans_n == CHANS_N_NOT_OVERRIDDEN)
2540 initial_ff_chans_n = dec_ctx->chans_n;
2541 else
2542 initial_ff_chans_n = override_initial_ff_chans_n;
2543 if (override_initial_ff_rate == RATE_NOT_OVERRIDDEN)
2544 initial_ff_rate = dec_ctx->fr_rate;
2545 else
2546 initial_ff_rate = override_initial_ff_rate;
2547 if (override_initial_ff_audio_fr_fmt == FR_FMT_NOT_OVERRIDDEN)
2548 initial_ff_audio_fr_fmt = dec_ctx->fr_fmt;
2549 else
2550 initial_ff_audio_fr_fmt = override_initial_ff_audio_fr_fmt;
2551 /* best effort configuration of the pcm based on initial ff params */
2552 pcm_cfg(pcm_g, initial_ff_chans_n, initial_ff_rate,
2553 initial_ff_audio_fr_fmt);
2343 2554 silence_bufs_cfg(pcm_g, PRINT_INFO); silence_bufs_cfg(pcm_g, PRINT_INFO);
2555 evt_pcm_install();
2344 2556 filt_frs.vol = initial_vol; filt_frs.vol = initial_vol;
2345 2557 } }
2346 2558 #undef PRINT_INFO #undef PRINT_INFO
2559 #undef CHANS_N_NOT_OVERRIDDEN
2560 #undef RATE_NOT_OVERRIDDEN
2561 #undef AUDIO_FR_FMT_NOT_OVERRIDDEN
2562 #define HOLD 1
2563 #define DONT_HOLD 0
2347 2564 static void seek_x(int64_t delta) static void seek_x(int64_t delta)
2348 2565 { {
2349 2566 int r; int r;
2350 2567 int64_t new_ts; int64_t new_ts;
2351 AVStream *st;
2352 AVRational st_tb;
2568 av_st *st;
2569 av_rational st_tb;
2353 2570
2354 2571 if (dec_frs.most_recent_ts == AV_NOPTS_VALUE) if (dec_frs.most_recent_ts == AV_NOPTS_VALUE)
2355 2572 warning("unable to seek because no time stamp are currently available\n"); warning("unable to seek because no time stamp are currently available\n");
2356 2573 fmt_ctx_lock(); fmt_ctx_lock();
2357 st = fmt_ctx->streams[current_st_idx];
2358 st_tb = st->time_base;
2574 st = fmt_ctx->sts[current_st_idx];
2575 st_tb = st->tb;
2359 2576 fmt_ctx_unlock(); fmt_ctx_unlock();
2360 2577
2361 new_ts = dec_frs.most_recent_ts + delta * st_tb.den / st_tb.num;
2578 new_ts = dec_frs.most_recent_ts + delta * (int64_t)st_tb.den
2579 / (int64_t)st_tb.num;
2362 2580 /* rewind capping */ /* rewind capping */
2363 2581 pout("trying to seek to %"PRId64" stream time base units\n", new_ts); pout("trying to seek to %"PRId64" stream time base units\n", new_ts);
2582
2583 atomic_store(&cb.hold, HOLD);
2584 rd_thd_reset(current_st_idx);
2364 2585 fmt_ctx_lock(); fmt_ctx_lock();
2365 2586 r = av_seek_pkt(fmt_ctx, st->id, new_ts, 0); r = av_seek_pkt(fmt_ctx, st->id, new_ts, 0);
2366 2587 fmt_ctx_unlock(); fmt_ctx_unlock();
2367 2588 if (r < 0) if (r < 0)
2368 2589 warning("unable to seek to %"PRId64" stream time base units\n", new_ts); warning("unable to seek to %"PRId64" stream time base units\n", new_ts);
2369 2590 dec_frs.most_recent_ts = AV_NOPTS_VALUE; dec_frs.most_recent_ts = AV_NOPTS_VALUE;
2370 rd_thd_reset(current_st_idx);
2371 avcodec_flush_buffers(dec_ctx);
2372 filt_frs.no_more_dec_frs = false; /* reset by the previous line */
2591 av_flush_bufs(dec_ctx);
2373 2592 filt_flush(); filt_flush();
2374 if (!filt_frs_get())
2375 exit_ok("no more audio frames to play\n");
2593 atomic_store(&cb.hold, DONT_HOLD);
2376 2594 } }
2595 #undef HOLD
2596 #undef DONT_HOLD
2377 2597 static void cmd_rewind(void) static void cmd_rewind(void)
2378 2598 { {
2379 2599 pout("COMMAND:rewind\n"); pout("COMMAND:rewind\n");
 
... ... static void cmd_vol_up(void)
2417 2637 pout("COMMAND:volume up to value %s(%s)\n", vol_l10n_str, filt_frs.muted ? "muted" : "unmuted"); pout("COMMAND:volume up to value %s(%s)\n", vol_l10n_str, filt_frs.muted ? "muted" : "unmuted");
2418 2638 if (filt_frs.muted) if (filt_frs.muted)
2419 2639 return; return;
2420 r = avfilter_graph_send_command(filter_graph, "vol", "volume",
2421 vol_l10n_str, response, sizeof(response), 0);
2640 r = av_filt_graph_send_cmd(filt_graph, "vol", "volume", vol_l10n_str,
2641 response, sizeof(response), 0);
2422 2642 if (r < 0) if (r < 0)
2423 2643 warning("ffmpeg:volume context:unable to set the volume up to \"%s\":response from volume filter:\"%s\"\n", response); warning("ffmpeg:volume context:unable to set the volume up to \"%s\":response from volume filter:\"%s\"\n", response);
2424 2644 } }
 
... ... static void cmd_vol_down(void)
2435 2655 pout("COMMAND:volume down to value %s(%s)\n", vol_l10n_str, filt_frs.muted ? "muted" : "unmuted"); pout("COMMAND:volume down to value %s(%s)\n", vol_l10n_str, filt_frs.muted ? "muted" : "unmuted");
2436 2656 if (filt_frs.muted) if (filt_frs.muted)
2437 2657 return; return;
2438 r = avfilter_graph_send_command(filter_graph, "vol", "volume",
2439 vol_l10n_str, response, sizeof(response), 0);
2658 r = av_filt_graph_send_cmd(filt_graph, "vol", "volume", vol_l10n_str,
2659 response, sizeof(response), 0);
2440 2660 if (r < 0) if (r < 0)
2441 2661 warning("ffmpeg:volume context:unable to set the volume down to \"%s\":response from volume filter:\"%s\"\n", response); warning("ffmpeg:volume context:unable to set the volume down to \"%s\":response from volume filter:\"%s\"\n", response);
2442 2662 } }
 
... ... static void cmd_mute(void)
2451 2671
2452 2672 snprintf(vol_l10n_str, sizeof(vol_l10n_str), "%f", snprintf(vol_l10n_str, sizeof(vol_l10n_str), "%f",
2453 2673 filt_frs.vol); filt_frs.vol);
2454 r = avfilter_graph_send_command(filter_graph, "vol", "volume",
2674 r = av_filt_graph_send_cmd(filt_graph, "vol", "volume",
2455 2675 vol_l10n_str, response, sizeof(response), 0); vol_l10n_str, response, sizeof(response), 0);
2456 2676 if (r < 0) { if (r < 0) {
2457 2677 warning("ffmpeg:volume context:unable to mute the volume to 0:response from volume filter:%s\n", response); warning("ffmpeg:volume context:unable to mute the volume to 0:response from volume filter:%s\n", response);
 
... ... static void cmd_mute(void)
2461 2681 } else { } else {
2462 2682 pout("COMMAND:muting\n"); pout("COMMAND:muting\n");
2463 2683
2464 r = avfilter_graph_send_command(filter_graph, "vol", "volume",
2684 r = av_filt_graph_send_cmd(filt_graph, "vol", "volume",
2465 2685 double_zero_l10n_str, response, sizeof(response), 0); double_zero_l10n_str, response, sizeof(response), 0);
2466 2686 if (r < 0) { if (r < 0) {
2467 2687 warning("ffmpeg:volume context:unable to mute the volume to 0:response from volume filter:%s\n", response); warning("ffmpeg:volume context:unable to mute the volume to 0:response from volume filter:%s\n", response);
 
... ... static void cmd_mute(void)
2470 2690 } }
2471 2691 } }
2472 2692 } }
2473 #define NO_RD_THD_RESET false
2693 #define CHANS_N_NOT_OVERRIDDEN 0
2694 #define RATE_NOT_OVERRIDDEN 0
2695 #define FR_FMT_NOT_OVERRIDDEN AV_FR_FMT_NONE
2474 2696 int main(int argc, u8 **args) int main(int argc, u8 **args)
2475 2697 { {
2476 2698 u8 *url; u8 *url;
2477 2699 u8 *pcm_str; u8 *pcm_str;
2478 2700 double initial_vol; double initial_vol;
2479 2701 int best_st_idx; int best_st_idx;
2702 /* audio override -- start */
2703 /*
2704 * we could have got direct parameters for alsa, but doing only an
2705 * override triggers an autoconfiguration of any missing parameters
2706 * based on initial codec params. In other words, the user is not
2707 * required to provide all audio params, the code will try to fit the
2708 * missing ones with the initial codec params, which is the default
2709 * behavior.
2710 */
2711 int override_initial_ff_chans_n;
2712 int override_initial_ff_rate;
2713 enum av_fr_fmt override_initial_ff_audio_fr_fmt;
2714 /* audio override -- end */
2480 2715 /* "turn on utf8" processing in used libs if any *AND* locale system */ /* "turn on utf8" processing in used libs if any *AND* locale system */
2481 2716 setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
2482 2717 /* av_log_set_level(AV_LOG_VERBOSE); */ /* av_log_set_level(AV_LOG_VERBOSE); */
2483 2718 /* av_log_set_level(AV_LOG_DEBUG); */ /* av_log_set_level(AV_LOG_DEBUG); */
2484 2719 url = 0; url = 0;
2720 override_initial_ff_chans_n = CHANS_N_NOT_OVERRIDDEN;
2721 override_initial_ff_rate = RATE_NOT_OVERRIDDEN;
2722 override_initial_ff_audio_fr_fmt = FR_FMT_NOT_OVERRIDDEN;
2485 2723 pcm_str = "default"; pcm_str = "default";
2486 2724 initial_vol = 1.; initial_vol = 1.;
2487 opts_parse(argc, args, &url, &pcm_str, &initial_vol);
2725 opts_parse(argc, args, &url, &pcm_str, &initial_vol,
2726 &override_initial_ff_chans_n, &override_initial_ff_rate,
2727 &override_initial_ff_audio_fr_fmt);
2488 2728 init_once(url, pcm_str); init_once(url, pcm_str);
2489 2729 best_st_idx = find_best_st(); best_st_idx = find_best_st();
2490 2730 rd_thd_start(best_st_idx); rd_thd_start(best_st_idx);
2491 /* play with reset will flush the already dmuxed pkts */
2492 play(best_st_idx, initial_vol, NO_RD_THD_RESET);
2493 /* switch the ffmpeg log to stdout for metadata/etc dump */
2494 av_log_set_callback(ffmpeg_log_stdout);
2731 prepare(best_st_idx, initial_vol, override_initial_ff_chans_n,
2732 override_initial_ff_rate, override_initial_ff_audio_fr_fmt);
2733 /* switch the ff log to stdout for metadata/etc dump */
2734 av_log_set_callback(ff_log_stdout);
2495 2735 fmt_ctx_lock(); fmt_ctx_lock();
2496 av_dump_format(fmt_ctx, 0, url, 0);
2736 av_dump_fmt(fmt_ctx, 0, url, 0);
2497 2737 fmt_ctx_unlock(); fmt_ctx_unlock();
2498 2738 av_log_set_callback(av_log_default_callback); av_log_set_callback(av_log_default_callback);
2499 if (!filt_frs_get()) /* must have some frames to play */
2500 exit_ok("no initial audio frames to play\n");
2501 2739 loop evts_loop(); loop evts_loop();
2502 2740 /* unreachable */ /* unreachable */
2503 2741 } }
2504 #undef NO_RD_THD_RESET
2742 #undef CHANS_N_NOT_OVERRIDDEN
2743 #undef RATE_NOT_OVERRIDDEN
2744 #undef AUDIO_FR_FMT_NOT_OVERRIDDEN
2505 2745 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
2506 #undef ARRAY_N
2507 #undef av_frames_alloc
2508 #undef av_frame_fmt_is_planar
2509 #undef av_frames_set_silence
2510 #undef av_frames_unref
2511 #undef av_get_frame_fmt_name
2512 #undef av_get_frame_fmt_string
2746 /* alsa */
2747 #undef snd_pcm_fmt_desc
2748 #undef snd_pcm_fmt_set_silence
2749 #undef SND_PCM_FMT_FLT
2750 #undef SND_PCM_FMT_S16
2751 #undef SND_PCM_FMT_S24
2752 #undef SND_PCM_FMT_S32
2753 #undef SND_PCM_FMT_S8
2754 #undef snd_pcm_fmt_t
2755 #undef SND_PCM_FMT_U16
2756 #undef SND_PCM_FMT_U24
2757 #undef SND_PCM_FMT_U32
2758 #undef SND_PCM_FMT_U8
2759 #undef SND_PCM_ST_PLAYBACK
2760 #undef snd_pcm_frs_to_bytes
2761 #undef snd_pcm_hw_params_get_chans
2762 #undef snd_pcm_hw_params_get_chans_max
2763 #undef snd_pcm_hw_params_get_chans_min
2764 #undef snd_pcm_hw_params_get_buf_size
2765 #undef snd_pcm_hw_params_get_fmt
2766 #undef snd_pcm_hw_params_set_buf_size_near
2767 #undef snd_pcm_hw_params_set_chans
2768 #undef snd_pcm_hw_params_set_fmt
2769 #undef snd_pcm_hw_params_test_chans
2770 #undef snd_pcm_hw_params_test_fmt
2771 #undef snd_pcm_sfrs_t
2772 #undef snd_pcm_ufrs_t
2773 /*----------------------------------------------------------------------------*/
2774 /* ff */
2775 #undef AV_AUDIO_FR_FMT_NONE
2776 #undef av_bufsink_get_frs
2777 #undef av_bufsrc_add_frs_flags
2778 #undef AV_BUFSRC_FLAG_KEEP_REF
2779 #undef AV_BUFSRC_FLAG_PUSH
2780 #undef av_codec
2781 #undef av_codec_ctx
2782 #undef av_dump_fmt
2783 #undef av_duration_estimation_method
2784 #undef av_filt
2785 #undef av_filt_ctx
2786 #undef av_filt_get_by_name
2787 #undef av_filt_graph
2788 #undef av_filt_graph_alloc
2789 #undef av_filt_graph_alloc_filt
2790 #undef av_filt_graph_cfg
2791 #undef av_filt_graph_dump
2792 #undef av_filt_graph_free
2793 #undef av_filt_graph_send_cmd
2794 #undef av_filt_init_str
2795 #undef av_filt_link
2796 #undef av_find_best_st
2797 #undef av_flush_bufs
2798 #undef av_fmt_ctx
2799 #undef AV_FMT_DURATION_FROM_BITRATE
2800 #undef AV_FMT_DURATION_FROM_PTS
2801 #undef AV_FMT_DURATION_FROM_ST
2802 #undef av_fmt_find_st_info
2803 #undef av_fmt_flush
2804 #undef av_fmt_open_input
2805 #undef av_fr_fmt_is_planar
2806 #undef AV_FR_FMT_FLT
2807 #undef AV_FR_FMT_FLTP
2808 #undef AV_FR_FMT_S16
2809 #undef AV_FR_FMT_S16P
2810 #undef AV_FR_FMT_S32
2811 #undef AV_FR_FMT_S32P
2812 #undef AV_FR_FMT_U8P
2813 #undef AV_FR_FMT_U8
2814 #undef av_frs_alloc
2815 #undef av_frs_set_silence
2816 #undef av_frs_unref
2817 #undef av_get_chan_layout_str
2818 #undef av_get_default_chans_layout
2819 #undef av_get_fr_fmt_name
2820 #undef av_get_fr_fmt_str
2821 #undef av_io_flush
2822 #undef AV_MEDIA_TYPE_AUDIO
2823 #undef av_pkt
2824 #undef av_pkt_unref
2513 2825 #undef av_read_pkt #undef av_read_pkt
2826 #undef av_rational
2514 2827 #undef av_seek_pkt #undef av_seek_pkt
2515 #undef avcodec_receive_frames
2516 #undef AVFrameFormat
2517 #undef AVFrames
2828 #undef av_receive_frs
2829 #undef av_fr_fmt
2830 #undef av_frs
2831 #undef av_sd_pkt
2832 #undef av_st
2833 #undef chan_layout
2834 #undef chans_n
2835 #undef format
2836 #undef fr_fmt
2837 #undef fr_rate
2838 #undef frs_n
2839 #undef st_idx
2840 #undef sts
2841 /*----------------------------------------------------------------------------*/
2842 #undef ARRAY_N
2518 2843 #undef esc_seq_sz #undef esc_seq_sz
2519 2844 #undef f32 #undef f32
2520 #undef frame_fmt
2521 #undef frame_rate
2522 #undef frames_n
2523 2845 #undef INPUT_ESC_SEQ_TIMEOUT_SECS_N #undef INPUT_ESC_SEQ_TIMEOUT_SECS_N
2524 2846 #undef loop #undef loop
2525 2847 #undef PCM_POLLFDS_N_MAX #undef PCM_POLLFDS_N_MAX
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/nyanmp

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/nyanmp

Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/nyanmp

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main