MythTV  master
mytharchive/mytharchive/remoteavformatcontext.h
Go to the documentation of this file.
1 // Wrapper for AVFormatContext (av_open_input_file/stream)
2 // supporting myth remote files
3 #ifndef REMOTEAVFORMATCONTEXT_H
4 #define REMOTEAVFORMATCONTEXT_H
5 
6 #include <QString>
7 
8 #include <remotefile.h>
9 #include <mythlogging.h>
10 
11 extern "C" {
12 #include <libavformat/avformat.h>
13 #include <libavformat/avio.h>
14 }
15 
17 {
18  public:
19  explicit RemoteAVFormatContext(const QString &filename = "") :
20  m_inputFC(nullptr), m_inputIsRemote(false), m_rf(nullptr), m_byteIOContext(nullptr), m_buffer(nullptr)
21  { if (!filename.isEmpty()) Open(filename); }
22 
24  {
25  Close();
26  if (m_buffer)
28  }
29 
30  bool Open(const QString &filename)
31  {
32  if (isOpen())
33  return false;
34 
35  if (m_inputFC)
36  avformat_free_context(m_inputFC);
37  m_inputFC = avformat_alloc_context();
38 
39  if (m_rf)
40  delete m_rf;
41 
42  m_inputIsRemote = filename.startsWith("myth://");
43  if (m_inputIsRemote)
44  {
45  m_rf = new RemoteFile(filename);
46 
47  if (!m_rf->isOpen())
48  return false;
49 
50  const int BUFFER_SIZE = 0x8000;
51  if (!m_buffer)
52  {
53  m_buffer = (unsigned char*)av_malloc(BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
54  if (!m_buffer)
55  return false;
56  }
57  m_byteIOContext = avio_alloc_context(m_buffer, BUFFER_SIZE, 0,
59 
60  m_byteIOContext->seekable = 1;
61 
62  // probe the stream
63  AVProbeData probe_data;
64  memset(&probe_data, 0, sizeof(AVProbeData));
65  probe_data.filename = "stream";
66  probe_data.buf_size = m_rf->Read(m_buffer, BUFFER_SIZE);
67  probe_data.buf = m_buffer;
68 
69  AVInputFormat *fmt = av_probe_input_format(&probe_data, 1);
70  if (!fmt)
71  return false;
72 
73  m_rf->Seek(0, SEEK_SET);
74 
76 
77  int ret = avformat_open_input(&m_inputFC, "stream", fmt, nullptr);
78  if (ret)
79  return false;
80  }
81  else
82  {
83  int ret = avformat_open_input(&m_inputFC, qPrintable(filename), nullptr, nullptr);
84  if (ret)
85  return false;
86  }
87 
88  return true;
89  }
90 
91  void Close()
92  {
93  if (m_inputFC)
94  {
95  avformat_close_input(&m_inputFC);
96  m_inputFC = nullptr;
97  }
98 
99  if (m_rf)
100  {
101  delete m_rf;
102  m_rf = nullptr;
103  }
104  }
105 
106  bool isOpen() const
107  {
108  if (m_inputIsRemote)
109  return (m_inputFC != nullptr && m_rf != nullptr && m_rf->isOpen());
110  else
111  return (m_inputFC != nullptr);
112  }
113 
114  operator AVFormatContext * () const { return m_inputFC; }
115  AVFormatContext * operator -> () const { return m_inputFC; }
116 
117  private:
118  static int ReadFunc(void *opaque, uint8_t *buf, int buf_size)
119  {
120  RemoteFile *rf = reinterpret_cast< RemoteFile* >(opaque);
121  return rf->Read(buf, buf_size);
122  }
123 
124  static int WriteFunc(void *, uint8_t *, int) { return -1; }
125 
126  static int64_t SeekFunc(void *opaque, int64_t offset, int whence)
127  {
128  RemoteFile *rf = reinterpret_cast< RemoteFile* >(opaque);
129  if (whence == AVSEEK_SIZE)
130  return rf->GetFileSize();
131 
132  return rf->Seek(offset, whence);
133  }
134 
135  private:
136  AVFormatContext *m_inputFC;
139  AVIOContext *m_byteIOContext;
140  unsigned char *m_buffer;
141 };
142 #endif // REMOTEAVFORMATCONTEXT_H
static int ReadFunc(void *opaque, uint8_t *buf, int buf_size)
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
int Read(void *data, int size)
Definition: remotefile.cpp:936
#define BUFFER_SIZE
void * av_malloc(unsigned int size)
long long GetFileSize(void) const
GetFileSize: returns the remote file's size at the time it was first opened Will query the server in ...
static int64_t SeekFunc(void *opaque, int64_t offset, int whence)
bool isOpen(void) const
Definition: remotefile.cpp:246
void av_free(void *ptr)
long long Seek(long long pos, int whence, long long curpos=-1)
Definition: remotefile.cpp:759
static int WriteFunc(void *, uint8_t *, int)