Audacity 3.2.0
AVIOContextWrapper.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 AVIOContextWrapper.cpp
6
7 Dmitry Vedenko
8
9**********************************************************************/
10
11#include "AVIOContextWrapper.h"
12
13#include "FFmpegFunctions.h"
14
15#define AVSEEK_FORCE 0x20000
16#define AVSEEK_SIZE 0x10000
17
18constexpr int BufferSize = 32 * 1024;
19
21 const FFmpegFunctions& ffmpeg) noexcept
22 : mFFmpeg(ffmpeg)
23{
24}
25
27{
28 return mAVIOContext;
29}
30
32{
33 return mAVIOContext;
34}
35
37{
38 if (mAVIOContext == nullptr)
39 return;
40
41 if (mFFmpeg.avio_context_free != nullptr)
43 else
45}
46
48AVIOContextWrapper::Open(const wxString& fileName, bool forWriting)
49{
50 auto pFile = std::make_unique<wxFile>();
51 if (!pFile->Open(fileName, forWriting ? wxFile::write : wxFile::read))
53
54 unsigned char* buffer =
55 static_cast<unsigned char*>(mFFmpeg.av_malloc(BufferSize));
56
57 if (buffer == nullptr)
59
60 /*
61 "The buffer must be allocated with av_malloc() and friends. It may be freed
62 and replaced with a new buffer by libavformat. AVIOContext.buffer holds the
63 buffer currently in use, which must be later freed with av_free()."
64
65 See ~AVIOContextWrapperImpl() for the deallocation
66 */
68 buffer, BufferSize,
69 static_cast<int>(forWriting),
70 this,
72 );
73
74 if (mAVIOContext == nullptr) {
75 mFFmpeg.av_free(buffer);
77 }
78
79 mpFile = move(pFile);
80
82}
83
84int AVIOContextWrapper::FileRead(void* opaque, uint8_t* buf, int size)
85{
86 AVIOContextWrapper* wrapper = static_cast<AVIOContextWrapper*>(opaque);
87
88 if (wrapper == nullptr)
89 return AUDACITY_AVERROR(EINVAL);
90
91 return wrapper->Read(buf, size);
92}
93
94int AVIOContextWrapper::FileWrite(void* opaque, const uint8_t* buf, int size)
95{
96 AVIOContextWrapper* wrapper = static_cast<AVIOContextWrapper*>(opaque);
97 if (!(wrapper && wrapper->mpFile))
98 return {};
99 return wrapper->mpFile->Write(buf, size);
100}
101
102int64_t AVIOContextWrapper::FileSeek(void* opaque, int64_t pos, int whence)
103{
104 AVIOContextWrapper* wrapper = static_cast<AVIOContextWrapper*>(opaque);
105 if (!(wrapper && wrapper->mpFile))
106 return {};
107
108 wxSeekMode mode = wxFromStart;
109
110 switch (whence & ~AVSEEK_FORCE)
111 {
112 case (SEEK_SET):
113 mode = wxFromStart;
114 break;
115 case (SEEK_CUR):
116 mode = wxFromCurrent;
117 break;
118 case (SEEK_END):
119 mode = wxFromEnd;
120 break;
121 case (AVSEEK_SIZE):
122 return wrapper->mpFile->Length();
123 }
124
125
126 return wrapper->mpFile->Seek(pos, mode);
127}
#define AVSEEK_SIZE
constexpr int BufferSize
#define AVSEEK_FORCE
#define AUDACITY_AVERROR(e)
Definition: FFmpegTypes.h:28
static int64_t FileSeek(void *opaque, int64_t pos, int whence)
static int FileRead(void *opaque, uint8_t *buf, int size)
AVIOContext * mAVIOContext
AVIOContext * GetWrappedValue() noexcept
virtual int Read(uint8_t *buf, int size)=0
AVIOContextWrapper(const AVIOContextWrapper &)=delete
const FFmpegFunctions & mFFmpeg
OpenResult Open(const wxString &fileName, bool forWriting)
static int FileWrite(void *opaque, const uint8_t *buf, int size)
std::unique_ptr< wxFile > mpFile
This is held indirectly by unique_ptr just so it can be swapped.
void(* avio_context_free)(AVIOContext **s)
AVIOContext *(* avio_alloc_context)(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, const uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
void *(* av_malloc)(size_t size)
void(* av_free)(void *ptr)