| 197 | } |
| 198 | |
| 199 | FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, int Track, int Threads, int SeekMode) |
| 200 | : Index(Index), SeekMode(SeekMode) { |
| 201 | |
| 202 | try { |
| 203 | if (Track < 0 || Track >= static_cast<int>(Index.size())) |
| 204 | throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, |
| 205 | "Out of bounds track index selected"); |
| 206 | |
| 207 | if (Index[Track].TT != FFMS_TYPE_VIDEO) |
| 208 | throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, |
| 209 | "Not a video track"); |
| 210 | |
| 211 | if (Index[Track].empty()) |
| 212 | throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, |
| 213 | "Video track contains no frames"); |
| 214 | |
| 215 | if (!Index.CompareFileSignature(SourceFile)) |
| 216 | throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_MISMATCH, |
| 217 | "The index does not match the source file"); |
| 218 | |
| 219 | Frames = Index[Track]; |
| 220 | VideoTrack = Track; |
| 221 | |
| 222 | if (Threads < 1) |
| 223 | DecodingThreads = (std::min)(std::thread::hardware_concurrency(), 16u); |
| 224 | else |
| 225 | DecodingThreads = Threads; |
| 226 | |
| 227 | DecodeFrame = av_frame_alloc(); |
| 228 | LastDecodedFrame = av_frame_alloc(); |
| 229 | StashedPacket = av_packet_alloc(); |
| 230 | |
| 231 | if (!DecodeFrame || !LastDecodedFrame || !StashedPacket) |
| 232 | throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, |
| 233 | "Could not allocate dummy frame / stashed packet."); |
| 234 | |
| 235 | // Dummy allocations so the unallocated case doesn't have to be handled later |
| 236 | if (av_image_alloc(SWSFrameData, SWSFrameLinesize, 16, 16, AV_PIX_FMT_GRAY8, 4) < 0) |
| 237 | throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, |
| 238 | "Could not allocate dummy frame."); |
| 239 | |
| 240 | LAVFOpenFile(SourceFile, FormatContext, VideoTrack, Index.LAVFOpts); |
| 241 | |
| 242 | auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id); |
| 243 | if (Codec == nullptr) |
| 244 | throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, |
| 245 | "Video codec not found"); |
| 246 | |
| 247 | CodecContext = avcodec_alloc_context3(Codec); |
| 248 | if (CodecContext == nullptr) |
| 249 | throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, |
| 250 | "Could not allocate video codec context."); |
| 251 | if (avcodec_parameters_to_context(CodecContext, FormatContext->streams[VideoTrack]->codecpar) < 0) |
| 252 | throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, |
| 253 | "Could not copy video decoder parameters."); |
| 254 | CodecContext->thread_count = DecodingThreads; |
| 255 | CodecContext->has_b_frames = Frames.MaxBFrames; |
| 256 |
nothing calls this directly
no test coverage detected