Open a video file.
62 {
64
65 if (avformat_open_input(&formatCtx, filename.c_str(), nullptr, nullptr) < 0) {
66 std::cout << std::format("mxvk_ff_capture: failed to open file: {}\n", filename);
68 return false;
69 }
70
71 if (avformat_find_stream_info(formatCtx, nullptr) < 0) {
72 std::cout << std::format("mxvk_ff_capture: failed to read stream info: {}\n", filename);
74 return false;
75 }
76
77 const int streamIndex = av_find_best_stream(formatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
78 if (streamIndex < 0) {
79 std::cout << std::format("mxvk_ff_capture: no video stream found: {}\n", filename);
81 return false;
82 }
83 videoStream = streamIndex;
84
85 AVStream *stream = formatCtx->streams[videoStream];
86 const AVCodecParameters *codecParams = stream->codecpar;
87 const AVCodec *decoder = avcodec_find_decoder(codecParams->codec_id);
88 if (decoder == nullptr) {
89 std::cout << "mxvk_ff_capture: no decoder found for video stream\n";
91 return false;
92 }
93
94 codecCtx = avcodec_alloc_context3(decoder);
95 if (codecCtx == nullptr || avcodec_parameters_to_context(codecCtx, codecParams) < 0) {
96 std::cout << "mxvk_ff_capture: failed to create decoder context\n";
98 return false;
99 }
100
101 codecCtx->opaque = this;
102 if (initHardwareDevice(decoder)) {
103 codecCtx->get_format = &VK_FF_Capture::chooseHwFormat;
104 codecCtx->hw_device_ctx = av_buffer_ref(hwDeviceCtx);
105 hardwareDecode = codecCtx->hw_device_ctx != nullptr;
106 }
107
108 if (avcodec_open2(codecCtx, decoder, nullptr) < 0) {
109 std::cout << "mxvk_ff_capture: failed to open decoder\n";
111 return false;
112 }
113
114 packet = av_packet_alloc();
115 frame = av_frame_alloc();
116 swFrame = av_frame_alloc();
117 if (packet == nullptr || frame == nullptr || swFrame == nullptr) {
118 std::cout << "mxvk_ff_capture: failed to allocate decoder frames\n";
120 return false;
121 }
122
123 frameWidth = codecCtx->width;
124 frameHeight = codecCtx->height;
126 if (frameFps <= 0.0) {
128 }
129 if (frameFps <= 0.0) {
130 frameFps = 30.0;
131 }
132
133 std::cout << std::format(
134 "mxvk_ff_capture: opened {} ({}x{}, {:.3f} fps, decode={})\n",
135 filename,
136 frameWidth,
137 frameHeight,
138 frameFps,
139 hardwareDecode ? "cuda" : "software");
140 return true;
141 }
double rationalToDouble(AVRational rational)