MCPcopy Create free account
hub / github.com/AbyssEngine/AbyssEngineOld / VideoStream

Method VideoStream

src/Abyss/Streams/VideoStream.cpp:122–232  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

120}
121
122VideoStream::VideoStream(FileSystem::InputStream stream, std::optional<FileSystem::InputStream> separateAudio)
123 : _stream(std::move(stream)), _ringBuffer(1024 * 4096), _texture(nullptr, SDL_DestroyTexture), _videoCodecContext(), _audioCodecContext(), _avFrame(),
124 _avBuffer(), _swsContext(), _sourceRect(), _targetRect(), _microsPerFrame(0), _videoTimestamp(0) {
125 _avBuffer = static_cast<unsigned char *>(av_malloc(DecodeBufferSize)); // AVIO is going to free this automagically... because why not?
126 memset(_avBuffer, 0, DecodeBufferSize);
127
128 _avioContext = avio_alloc_context(
129 _avBuffer, DecodeBufferSize, 0, this,
130 [](void *opaque, uint8_t *buffer, const int size) { return static_cast<VideoStream *>(opaque)->videoStreamRead(buffer, size); }, nullptr,
131 [](void *opaque, const int64_t offset, const int whence) { return static_cast<VideoStream *>(opaque)->videoStreamSeek(offset, whence); });
132
133 _avFormatContext = avformat_alloc_context();
134 _avFormatContext->pb = _avioContext;
135 _avFormatContext->flags |= AVFMT_FLAG_CUSTOM_IO;
136
137 int avError;
138 if ((avError = avformat_open_input(&_avFormatContext, "", nullptr, nullptr)) < 0)
139 throw std::runtime_error(absl::StrCat("Failed to open AV format context: ", avErrorCodeToString(avError)));
140
141 if ((avError = avformat_find_stream_info(_avFormatContext, nullptr)) < 0)
142 throw std::runtime_error(absl::StrCat("Failed to find stream info: ", avErrorCodeToString(avError)));
143
144 for (auto i = 0; i < _avFormatContext->nb_streams; i++) {
145 if (_avFormatContext->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
146 continue;
147
148 _videoStreamIdx = i;
149 break;
150 }
151
152 if (_videoStreamIdx == -1)
153 throw std::runtime_error("Could not locate video stream.");
154
155 for (auto i = 0; i < _avFormatContext->nb_streams; i++) {
156 if (_avFormatContext->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
157 continue;
158
159 _audioStreamIdx = i;
160 break;
161 }
162
163 _microsPerFrame = static_cast<uint64_t>(1000000 / static_cast<float>(_avFormatContext->streams[_videoStreamIdx]->r_frame_rate.num) /
164 static_cast<float>(_avFormatContext->streams[_videoStreamIdx]->r_frame_rate.den));
165
166 const auto videoCodecPar = _avFormatContext->streams[_videoStreamIdx]->codecpar;
167 const auto videoDecoder = avcodec_find_decoder(videoCodecPar->codec_id);
168
169 if (videoDecoder == nullptr)
170 throw std::runtime_error("Missing video codec.");
171
172 _videoCodecContext = avcodec_alloc_context3(videoDecoder);
173 if ((avError = avcodec_parameters_to_context(_videoCodecContext, videoCodecPar)) < 0)
174 throw std::runtime_error(absl::StrCat("Failed to apply parameters to video context: ", avErrorCodeToString(avError)));
175
176 if ((avError = avcodec_open2(_videoCodecContext, videoDecoder, nullptr)) < 0)
177 throw std::runtime_error(absl::StrCat("Failed to open video context: ", avErrorCodeToString(avError)));
178
179 if (_audioStreamIdx >= 0) {

Callers

nothing calls this directly

Calls 5

videoStreamReadMethod · 0.80
videoStreamSeekMethod · 0.80
getRendererMethod · 0.80
resizeMethod · 0.80
playMethod · 0.45

Tested by

no test coverage detected