MythTV master
mythavformatbuffer.cpp
Go to the documentation of this file.
2
3// FFmpeg
4extern "C" {
5#include "libavformat/avio.h"
6#include "libavutil/error.h"
7}
8
9#include <QtGlobal>
10#include <QRecursiveMutex>
11
13
15 : m_buffer(Buffer), m_avioContext(alloc_context(write_flag, force_seek))
16{
17 if (m_avioContext == nullptr)
18 {
19 LOG(VB_GENERAL, LOG_ERR, "MythAVFormatBuffer failed to allocate an AVIOContext.");
20 }
21}
22
24{
25 if (m_avioContext != nullptr)
26 {
27 avio_flush(m_avioContext);
28 av_freep(reinterpret_cast<void*>(&m_avioContext->buffer));
29 if (m_avioContext->write_flag)
30 {
31 LOG(VB_LIBAV, LOG_DEBUG, QString("AVIOContext (%1): %2 bytes written")
32 .arg(pointerToQString(m_avioContext), QString::number(m_avioContext->bytes_written)));
33 }
34 else
35 {
36 LOG(VB_LIBAV, LOG_DEBUG, QString("AVIOContext (%1): %2 bytes read")
37 .arg(pointerToQString(m_avioContext), QString::number(m_avioContext->bytes_read)));
38 }
39 avio_context_free(&m_avioContext);
40 }
41}
42
43AVIOContext* MythAVFormatBuffer::alloc_context(bool write_flag, bool force_seek)
44{
45 AVIOContext* context = nullptr;
46 int buf_size = m_buffer->BestBufferSize();
47 auto *avio_buffer = static_cast<unsigned char *>(av_malloc(buf_size));
48 if (avio_buffer == nullptr)
49 {
50 LOG(VB_LIBAV, LOG_ERR, "av_malloc() failed to create a buffer for avio.");
51 return nullptr;
52 }
53 context = avio_alloc_context(avio_buffer, buf_size, write_flag, this,
55 if (context == nullptr)
56 {
57 return context;
58 }
59 if (m_buffer->IsStreamed() && !force_seek)
60 {
61 context->seekable &= ~AVIO_SEEKABLE_NORMAL;
62 }
63 return context;
64}
65
66int MythAVFormatBuffer::read_packet(void *opaque, uint8_t *buf, int buf_size)
67{
68 auto *p = reinterpret_cast<MythAVFormatBuffer*>(opaque);
69 if (!p)
70 return AVERROR(EINVAL);
71
72 int ret = p->m_buffer->Read(buf, buf_size);
73
74 if (ret == 0)
75 ret = AVERROR_EOF;
76 return ret;
77}
78
79int MythAVFormatBuffer::write_packet(void *opaque, const uint8_t *buf, int buf_size)
80{
81 auto *p = reinterpret_cast<MythAVFormatBuffer*>(opaque);
82 if (!p)
83 return AVERROR(EINVAL);
84
85 return p->m_buffer->Write(buf, static_cast<uint>(buf_size));
86}
87
88int64_t MythAVFormatBuffer::seek(void *opaque, int64_t offset, int whence)
89{
90 auto *p = reinterpret_cast<MythAVFormatBuffer*>(opaque);
91 if (!p)
92 return AVERROR(EINVAL);
93
94 if (whence == AVSEEK_SIZE)
95 return p->m_buffer->GetRealFileSize();
96
97 if (whence == SEEK_END)
98 return p->m_buffer->Seek(p->m_buffer->GetRealFileSize() + offset, SEEK_SET);
99
100 return p->m_buffer->Seek(offset, whence);
101}
102
104{
107}
108
110{
111 return m_initState;
112}
static int write_packet(void *opaque, const uint8_t *buf, int buf_size)
static int64_t seek(void *opaque, int64_t offset, int whence)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
AVIOContext * m_avioContext
MythAVFormatBuffer(MythMediaBuffer *Buffer, bool write_flag, bool force_seek)
void SetInInit(bool State)
MythMediaBuffer * m_buffer
AVIOContext * alloc_context(bool write_flag, bool force_seek)
bool IsInInit(void) const
virtual bool IsStreamed(void)
virtual int BestBufferSize(void)
bool SetReadInternalMode(bool Mode)
unsigned int uint
Definition: compat.h:60
QString pointerToQString(const void *p)
Definition: mythlogging.h:77
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
State
Definition: zmserver.h:69