pianod2
multisource multiuser scriptable networked music player
ffmpegplayer.h
Go to the documentation of this file.
1 
9 #pragma once
10 
11 #include <config.h>
12 
13 #include <string>
14 #include <memory>
15 
16 #pragma GCC diagnostic push
17 #pragma GCC diagnostic ignored "-Wdocumentation"
18 extern "C" {
19 #include <libavformat/avformat.h>
20 #include <libavcodec/avcodec.h>
21 #include <libavfilter/avfilter.h>
22 #ifdef HAVE_LIBAVFILTER_AVFILTERGRAPH_H
23 #include <libavfilter/avfiltergraph.h>
24 #endif
25 #include <libavutil/replaygain.h>
26 }
27 #pragma GCC diagnostic pop
28 
29 #include "mediaplayer.h"
30 #include "audio/audiooutput.h"
31 #include "fundamentals.h"
32 
33 namespace Audio {
34 
35  extern void flogav (const char *func, int err);
36 
39  public:
40  LavAudioException (const char *func, int error);
41  };
42 
43 
45  class LavAdapter {
46 #ifdef HAVE_AVCODECPARAMETERS
47  struct CodecParameterDeleter {
48  void operator() (AVCodecParameters *params) {
49  avcodec_parameters_free (&params);
50  }
51  };
52 #endif
53 
55  void operator()(AVFilterGraph *filter) {
56  avfilter_graph_free (&filter);
57  }
58  };
59 
60  // Filters are freed by freeing the graph
61  struct FrameDeleter {
62  void operator()(AVFrame *frame) {
63  av_frame_free (&frame);
64  }
65  };
66 
67 
68  AVFilterContext *buffer_filter = nullptr;
69  AVFilterContext *volume_filter = nullptr;
70  AVFilterContext *format_filter = nullptr;
71  AVFilterContext *endpoint_filter = nullptr;
72  std::unique_ptr <AVFilterGraph, FilterGraphDeleter> filter_stack;
73 
74  // Used to retrieve data from the endpoint filter.
75  // This should be local, but needs to be alloced/dealloced.
76  std::unique_ptr <AVFrame, FrameDeleter> output_frame = nullptr;
77  std::mutex adapter_mutex;
78 
79  AVFilterContext *pushFilter (AVFilterContext *prior_filter,
80  const char *name,
81  const char *optionformat = nullptr, ...);
82 
83  protected:
84  LavAdapter (const AVCodecContext *codec,
85  const AVStream *stream,
86  const AVSampleFormat output_format);
87  virtual bool playFrame (AVFrame *frame) = 0;
88  bool playFilteredPackets (const bool eof_return_value = true);
89  void flush ();
90  public:
91  virtual ~LavAdapter ();
92  bool play (AVFrame *frame);
93  void setVolume (float level);
94 
95  static LavAdapter *getOutput (const AudioSettings &settings,
96  const AVCodecContext *context,
97  const AVStream *stream);
98  };
99 
100 
102  class LavGenericAdapter : public LavAdapter {
103  std::unique_ptr <Output> output;
104 
105  public:
106  LavGenericAdapter (const AVCodecContext *codec, const AVStream *stream,
107  Output *out, const AVSampleFormat output_format);
109  virtual bool playFrame (AVFrame *frame) override;
110  };
111 
114  protected:
115  struct CodecDeleter {
116  void operator() (AVCodecContext *coder) {
117  avcodec_free_context (&coder);
118  }
119  };
120 
121  const std::string url;
122  bool is_network = false;
123  AVFormatContext *transport = nullptr;
124 
125  // Private functions
126  int initializeStream (std::unique_ptr <AVCodecContext, CodecDeleter> &codec_context);
127  void processReplayGain (AVReplayGain *gain, int size);
128  virtual void setGain (float gain) = 0;
129  public:
130  LibavMediaReader (const std::string &media_url, int timeout = 15);
131  virtual ~LibavMediaReader (void);
132  };
133 
134 
135 
138  private:
140  float gain = 0;
141 
142  volatile float duration = -1;
143  volatile float playpoint = 0;
145  std::unique_ptr <Audio::LavAdapter> output;
146 
147  // Private functions
148  bool playPacket (AVFrame *frame,
149  AVCodecContext *codec,
150  AVPacket *packet);
151  RESPONSE_CODE playStream (AVFormatContext *format,
152  AVCodecContext *codec,
153  const int audio_stream);
154  virtual void setGain (float gain) override;
155 
156  // Implement MediaPlayer API
157  virtual void setVolume (float volume) override;
158  virtual State currentState (void) const override;
159  virtual float trackDuration (void) const override;
160  virtual float playPoint (void) const override;
161  virtual RESPONSE_CODE playerThread (void) override;
162  virtual void pausing (void) override;
163  virtual void resuming (void) override;
164  public:
166  const std::string &media_url,
167  float audio_gain = 0);
168  };
169 
170 }
171 
Class to abstract away details of audio output system is in use.
Exception for audio output problems.
Definition: audiooutput.h:47
Adapter to feed a ffmpeg stream to an audio output.
Definition: ffmpegplayer.h:45
AVFilterContext * pushFilter(AVFilterContext *prior_filter, const char *name, const char *optionformat=nullptr,...)
Add a filter to the filter stack.
Definition: ffmpegadapter.cpp:74
void setVolume(float level)
Definition: ffmpegadapter.cpp:239
LavAdapter(const AVCodecContext *codec, const AVStream *stream, const AVSampleFormat output_format)
Adapt whatever output for input from ffmpeg.
Definition: ffmpegadapter.cpp:113
bool playFilteredPackets(const bool eof_return_value=true)
Read all the resulting frames coming out of the filter stack, and push them to the outputter.
Definition: ffmpegadapter.cpp:220
std::mutex adapter_mutex
Definition: ffmpegplayer.h:77
void flush()
Play any frames buffered in the filter.
Definition: ffmpegadapter.cpp:182
AVFilterContext * buffer_filter
Definition: ffmpegplayer.h:68
std::unique_ptr< AVFilterGraph, FilterGraphDeleter > filter_stack
Definition: ffmpegplayer.h:72
AVFilterContext * endpoint_filter
Definition: ffmpegplayer.h:71
virtual ~LavAdapter()
Definition: ffmpegadapter.cpp:177
AVFilterContext * format_filter
Definition: ffmpegplayer.h:70
bool play(AVFrame *frame)
Play a frame from a ffmpeg decoder.
Definition: ffmpegadapter.cpp:203
AVFilterContext * volume_filter
Definition: ffmpegplayer.h:69
static LavAdapter * getOutput(const AudioSettings &settings, const AVCodecContext *context, const AVStream *stream)
Choose an output, then get an adapter for libav and set it up to match the output's format.
Definition: ffmpegadapter.cpp:302
std::unique_ptr< AVFrame, FrameDeleter > output_frame
Definition: ffmpegplayer.h:76
virtual bool playFrame(AVFrame *frame)=0
Exception for ffmpeg audio output problems.
Definition: ffmpegplayer.h:38
LavAudioException(const char *func, int error)
Create an AudioException from a ffmpeg error.
Definition: ffmpegadapter.cpp:55
Adapter to feed a ffmpeg stream to a generic audio output.
Definition: ffmpegplayer.h:102
LavGenericAdapter(const AVCodecContext *codec, const AVStream *stream, Output *out, const AVSampleFormat output_format)
Adapt whatever output for input from ffmpeg.
Definition: ffmpegadapter.cpp:267
virtual bool playFrame(AVFrame *frame) override
Send a processed frame to the audio output device.
Definition: ffmpegadapter.cpp:282
~LavGenericAdapter()
Definition: ffmpegadapter.cpp:275
std::unique_ptr< Output > output
Definition: ffmpegplayer.h:103
ffmpeg audio player
Definition: ffmpegplayer.h:137
volatile Media::Player::State state
Definition: ffmpegplayer.h:144
float gain
Replay gain from track.
Definition: ffmpegplayer.h:140
virtual void setGain(float gain) override
Definition: ffmpegplayer.cpp:203
virtual void resuming(void) override
Called when the playback thread is resuming playback.
Definition: ffmpegplayer.cpp:197
bool playPacket(AVFrame *frame, AVCodecContext *codec, AVPacket *packet)
Definition: ffmpegplayer.cpp:220
virtual RESPONSE_CODE playerThread(void) override
Definition: ffmpegplayer.cpp:300
LavPlayer(const AudioSettings &AudioSettings, const std::string &media_url, float audio_gain=0)
Play a media file or URL using ffmpeg.
Definition: ffmpegplayer.cpp:165
virtual float trackDuration(void) const override
Length of track in seconds, or a negative number if unknown.
Definition: ffmpegplayer.cpp:178
volatile float duration
Length of song, in seconds.
Definition: ffmpegplayer.h:142
virtual State currentState(void) const override
Definition: ffmpegplayer.cpp:186
virtual void setVolume(float volume) override
Adjust volume in decibels.
Definition: ffmpegplayer.cpp:171
virtual void pausing(void) override
Called when the playback thread is pausing.
Definition: ffmpegplayer.cpp:191
std::unique_ptr< Audio::LavAdapter > output
Definition: ffmpegplayer.h:145
RESPONSE_CODE playStream(AVFormatContext *format, AVCodecContext *codec, const int audio_stream)
Definition: ffmpegplayer.cpp:267
virtual float playPoint(void) const override
Seconds from start, or a negative value if unknown.
Definition: ffmpegplayer.cpp:182
volatile float playpoint
Current point in song, in seconds.
Definition: ffmpegplayer.h:143
AudioSettings audio
Output settings.
Definition: ffmpegplayer.h:139
Base class for reading media streams via ffmpeg.
Definition: ffmpegplayer.h:113
void processReplayGain(AVReplayGain *gain, int size)
Process a replaygain packet by extracting the track gain, or if not found then then the album gain.
Definition: ffmpegplayer.cpp:71
virtual void setGain(float gain)=0
LibavMediaReader(const std::string &media_url, int timeout=15)
Base abstract class for reading a media file or URL using ffmpeg.
Definition: ffmpegplayer.cpp:42
const std::string url
Media URL or filename.
Definition: ffmpegplayer.h:121
int initializeStream(std::unique_ptr< AVCodecContext, CodecDeleter > &codec_context)
Prepare a ffmpeg source for playing its audio stream.
Definition: ffmpegplayer.cpp:102
AVFormatContext * transport
Definition: ffmpegplayer.h:123
virtual ~LibavMediaReader(void)
Definition: ffmpegplayer.cpp:64
bool is_network
True if media is network streaming.
Definition: ffmpegplayer.h:122
Base audio output class (abstract).
Definition: audiooutput.h:65
State
Definition: mediaplayer.h:48
@ Initializing
Player has been created but isn't doing anything yet.
Definition: mediaplayer.h:50
Base class for audio players that are spawned to a new thread.
Definition: mediaplayer.h:90
Essential data structures and support.
enum server_status_t RESPONSE_CODE
Public interface for media players.
Classes dealing with audio output drivers and decoding/playing audio files.
Definition: audiooutput.cpp:48
void flogav(const char *func, int err)
Log an ffmpeg error.
Definition: ffmpegadapter.cpp:46
Definition: ffmpegplayer.h:54
void operator()(AVFilterGraph *filter)
Definition: ffmpegplayer.h:55
Definition: ffmpegplayer.h:61
void operator()(AVFrame *frame)
Definition: ffmpegplayer.h:62
Definition: ffmpegplayer.h:115
void operator()(AVCodecContext *coder)
Definition: ffmpegplayer.h:116
Audio output device & driver parameters.
Definition: fundamentals.h:52