MythTV master
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
9
10extern "C" {
11#include <libavformat/avformat.h>
12#include <libavformat/avio.h>
13}
14
16{
17 public:
18 explicit ArchiveRemoteAVFormatContext(const QString &filename = "")
19 { if (!filename.isEmpty()) Open(filename); }
20
22 {
23 Close();
24 if (m_buffer)
25 av_free(m_buffer);
26 }
27
28 bool Open(const QString &filename)
29 {
30 if (isOpen())
31 return false;
32
33 if (m_inputFC)
34 avformat_free_context(m_inputFC);
35 m_inputFC = avformat_alloc_context();
36
37 delete m_rf;
38
39 m_inputIsRemote = filename.startsWith("myth://");
41 {
43
44 if (!m_rf->isOpen())
45 return false;
46
47 const int BUFFER_SIZE = 0x8000;
48 if (!m_buffer)
49 {
50 m_buffer = (unsigned char*)av_malloc(BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
51 if (!m_buffer)
52 return false;
53 }
54 m_byteIOContext = avio_alloc_context(m_buffer, BUFFER_SIZE, 0,
56
57 m_byteIOContext->seekable = 1;
58
59 // probe the stream
60 AVProbeData probe_data;
61 memset(&probe_data, 0, sizeof(AVProbeData));
62 probe_data.filename = "stream";
63 probe_data.buf_size = m_rf->Read(m_buffer, BUFFER_SIZE);
64 probe_data.buf = m_buffer;
65
66 const AVInputFormat *fmt = av_probe_input_format(&probe_data, 1);
67 if (!fmt)
68 return false;
69
70 m_rf->Seek(0, SEEK_SET);
71
73
74 int ret = avformat_open_input(&m_inputFC, "stream", fmt, nullptr);
75 if (ret)
76 return false;
77 }
78 else
79 {
80 int ret = avformat_open_input(&m_inputFC, qPrintable(filename), nullptr, nullptr);
81 if (ret)
82 return false;
83 }
84
85 return true;
86 }
87
88 void Close()
89 {
90 if (m_inputFC)
91 {
92 avformat_close_input(&m_inputFC);
93 m_inputFC = nullptr;
94 }
95
96 if (m_rf)
97 {
98 delete m_rf;
99 m_rf = nullptr;
100 }
101 }
102
103 bool isOpen() const
104 {
105 if (m_inputIsRemote)
106 return (m_inputFC != nullptr && m_rf != nullptr && m_rf->isOpen());
107 return (m_inputFC != nullptr);
108 }
109
110 operator AVFormatContext * () const { return m_inputFC; }
111 AVFormatContext * operator -> () const { return m_inputFC; }
112
113 private:
114 static int ReadFunc(void *opaque, uint8_t *buf, int buf_size)
115 {
116 auto *rf = reinterpret_cast< RemoteFile* >(opaque);
117 return rf->Read(buf, buf_size);
118 }
119
120 static int WriteFunc(void */*opaque*/, const uint8_t */*buf*/, int /*buf_size*/)
121 { return -1; }
122
123 static int64_t SeekFunc(void *opaque, int64_t offset, int whence)
124 {
125 auto *rf = reinterpret_cast< RemoteFile* >(opaque);
126 if (whence == AVSEEK_SIZE)
127 return rf->GetFileSize();
128
129 return rf->Seek(offset, whence);
130 }
131
132 private:
133 AVFormatContext *m_inputFC { nullptr };
134 bool m_inputIsRemote { false };
135 RemoteFile *m_rf { nullptr };
136 AVIOContext *m_byteIOContext { nullptr };
137 unsigned char *m_buffer { nullptr };
138};
139#endif // REMOTEAVFORMATCONTEXT_H
bool Open(const QString &filename)
static int ReadFunc(void *opaque, uint8_t *buf, int buf_size)
AVFormatContext * operator->() const
static int64_t SeekFunc(void *opaque, int64_t offset, int whence)
ArchiveRemoteAVFormatContext(const QString &filename="")
static int WriteFunc(void *, const uint8_t *, int)
int Read(void *data, int size)
Definition: remotefile.cpp:938
long long Seek(long long pos, int whence, long long curpos=-1)
Definition: remotefile.cpp:759
bool isOpen(void) const
Definition: remotefile.cpp:245
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 constexpr qint64 BUFFER_SIZE