19
19
20
20
21
21
namespace dali {
22
+ int MemoryVideoFile::Read (unsigned char *buffer, int buffer_size) {
23
+ int left_in_file = size_ - position_;
24
+ if (left_in_file == 0 ) {
25
+ return AVERROR_EOF;
26
+ }
27
+
28
+ int to_read = std::min (left_in_file, buffer_size);
29
+ std::copy (data_ + position_, data_ + position_ + to_read, buffer);
30
+ position_ += to_read;
31
+ return to_read;
32
+ }
33
+
34
+ /* *
35
+ * @brief Method for seeking the memory video. It sets position according to provided arguments.
36
+ *
37
+ * @param new_position Requested new_position.
38
+ * @param mode Chosen method of seeking. This argument changes how new_position is interpreted and how seeking is performed.
39
+ * @return int64_t actual new position in the file.
40
+ */
41
+ int64_t MemoryVideoFile::Seek (int64_t new_position, int mode) {
42
+ switch (mode) {
43
+ case SEEK_SET:
44
+ position_ = new_position;
45
+ break ;
46
+ case AVSEEK_SIZE:
47
+ return size_;
48
+
49
+ default :
50
+ DALI_FAIL (
51
+ make_string (
52
+ " Unsupported seeking method in FramesDecoder from memory file. Seeking method: " ,
53
+ mode));
54
+ }
55
+
56
+ return position_;
57
+ }
22
58
23
59
namespace detail {
24
60
std::string av_error_string (int ret) {
25
61
static char msg[AV_ERROR_MAX_STRING_SIZE];
26
62
memset (msg, 0 , sizeof (msg));
27
63
return std::string (av_make_error_string (msg, AV_ERROR_MAX_STRING_SIZE, ret));
28
64
}
65
+
66
+ int read_memory_video_file (void *data_ptr, uint8_t *av_io_buffer, int av_io_buffer_size) {
67
+ MemoryVideoFile *memory_video_file = static_cast <MemoryVideoFile *>(data_ptr);
68
+
69
+ return memory_video_file->Read (av_io_buffer, av_io_buffer_size);
29
70
}
30
71
72
+ int64_t seek_memory_video_file (void *data_ptr, int64_t new_position, int origin) {
73
+ MemoryVideoFile *memory_video_file = static_cast <MemoryVideoFile *>(data_ptr);
74
+
75
+ return memory_video_file->Seek (new_position, origin);
76
+ }
77
+
78
+ } // namespace detail
79
+
31
80
using AVPacketScope = std::unique_ptr<AVPacket, decltype(&av_packet_unref)>;
32
81
33
82
const std::vector<AVCodecID> FramesDecoder::SupportedCodecs = {
@@ -78,7 +127,7 @@ void FramesDecoder::FindVideoStream() {
78
127
}
79
128
}
80
129
81
- DALI_FAIL (make_string (" Could not find a valid video stream in a file " , filename_ ));
130
+ DALI_FAIL (make_string (" Could not find a valid video stream in a file " , Filename () ));
82
131
}
83
132
84
133
FramesDecoder::FramesDecoder (const std::string &filename)
@@ -89,8 +138,8 @@ FramesDecoder::FramesDecoder(const std::string &filename)
89
138
av_state_->ctx_ = avformat_alloc_context ();
90
139
DALI_ENFORCE (av_state_->ctx_ , " Could not alloc avformat context" );
91
140
92
- int ret = avformat_open_input (&av_state_->ctx_ , filename .c_str (), nullptr , nullptr );
93
- DALI_ENFORCE (ret == 0 , make_string (" Failed to open video file at path " , filename , " due to " ,
141
+ int ret = avformat_open_input (&av_state_->ctx_ , Filename () .c_str (), nullptr , nullptr );
142
+ DALI_ENFORCE (ret == 0 , make_string (" Failed to open video file " , Filename () , " due to " ,
94
143
detail::av_error_string (ret)));
95
144
96
145
FindVideoStream ();
@@ -99,13 +148,52 @@ FramesDecoder::FramesDecoder(const std::string &filename)
99
148
make_string (
100
149
" Unsupported video codec: " ,
101
150
av_state_->codec_ ->name ,
102
- " in file: " , filename ,
151
+ " in file: " , Filename () ,
103
152
" Supported codecs: h264, HEVC." ));
104
153
InitAvState ();
105
154
BuildIndex ();
106
155
DetectVfr ();
107
156
}
108
157
158
+
159
+
160
+ FramesDecoder::FramesDecoder (const char *memory_file, int memory_file_size)
161
+ : av_state_(std::make_unique<AvState>()),
162
+ memory_video_file_ (MemoryVideoFile(memory_file, memory_file_size)) {
163
+ av_log_set_level (AV_LOG_ERROR);
164
+
165
+ av_state_->ctx_ = avformat_alloc_context ();
166
+ DALI_ENFORCE (av_state_->ctx_ , " Could not alloc avformat context" );
167
+
168
+ uint8_t *av_io_buffer = static_cast <uint8_t *>(av_malloc (default_av_buffer_size));
169
+
170
+ AVIOContext *av_io_context = avio_alloc_context (
171
+ av_io_buffer,
172
+ default_av_buffer_size,
173
+ 0 ,
174
+ &memory_video_file_.value (),
175
+ detail::read_memory_video_file,
176
+ nullptr ,
177
+ detail::seek_memory_video_file);
178
+
179
+ av_state_->ctx_ ->pb = av_io_context;
180
+
181
+ int ret = avformat_open_input (&av_state_->ctx_ , " " , nullptr , nullptr );
182
+ DALI_ENFORCE (ret == 0 , make_string (" Failed to open video file " , Filename (), " due to " ,
183
+ detail::av_error_string (ret)));
184
+
185
+ FindVideoStream ();
186
+ DALI_ENFORCE (
187
+ CheckCodecSupport (),
188
+ make_string (
189
+ " Unsupported video codec: " ,
190
+ av_state_->codec_ ->name ,
191
+ " . Supported codecs: h264, HEVC." ));
192
+ InitAvState ();
193
+ BuildIndex ();
194
+ DetectVfr ();
195
+ }
196
+
109
197
void FramesDecoder::BuildIndex () {
110
198
// TODO(awolant): Optimize this function for:
111
199
// - CFR
@@ -247,7 +335,7 @@ void FramesDecoder::Reset() {
247
335
ret >= 0 ,
248
336
make_string (
249
337
" Could not seek to the first frame of video " ,
250
- filename_ ,
338
+ Filename () ,
251
339
" due to" ,
252
340
detail::av_error_string (ret)));
253
341
avcodec_flush_buffers (av_state_->codec_ctx_ );
@@ -284,7 +372,7 @@ void FramesDecoder::SeekFrame(int frame_id) {
284
372
" with keyframe" ,
285
373
keyframe_id,
286
374
" in video " ,
287
- filename_ ,
375
+ Filename () ,
288
376
" due to " ,
289
377
detail::av_error_string (ret)));
290
378
0 commit comments