| 128 | } |
| 129 | |
| 130 | void AVEncoder::encodeOneFrame(bool draw, TimeHolder frametime) { |
| 131 | if (!ffmpeg_pipe) |
| 132 | return; |
| 133 | |
| 134 | /* Check if ffmpeg did exit for some reason */ |
| 135 | int ret_pid = waitpid(ffmpeg_pid, nullptr, WNOHANG); |
| 136 | if (ret_pid == ffmpeg_pid) { |
| 137 | LOG(LL_WARN, LCF_DUMP, "ffmpeg process exited, encoding stopped"); |
| 138 | NATIVECALL(fclose(ffmpeg_pipe)); |
| 139 | ffmpeg_pipe = nullptr; |
| 140 | return; |
| 141 | } |
| 142 | |
| 143 | /* If the muxer is not initialized, try to initialize it. Otherwise, store |
| 144 | * that we skipped one frame and we need to encode it later. |
| 145 | */ |
| 146 | AudioContext& audiocontext = AudioContext::get(); |
| 147 | if (!nutMuxer) { |
| 148 | if (ScreenCapture::isInited()) { |
| 149 | initMuxer(); |
| 150 | |
| 151 | /* Encode audio samples that we skipped */ |
| 152 | nutMuxer->writeAudioFrame(startup_audio_bytes.data(), startup_audio_bytes.size()); |
| 153 | |
| 154 | /* Encode startup frames that we skipped */ |
| 155 | |
| 156 | /* Just getting the size of an image */ |
| 157 | int size = ScreenCapture::getSize(); |
| 158 | startup_audio_bytes.resize(size, 0); // reusing the audio samples vector |
| 159 | for (int i=0; i<startup_video_frames; i++) { |
| 160 | nutMuxer->writeVideoFrame(startup_audio_bytes.data(), size); |
| 161 | } |
| 162 | } |
| 163 | else { |
| 164 | startup_video_frames++; |
| 165 | /* Store audio samples that we skipped */ |
| 166 | startup_audio_bytes.insert(startup_audio_bytes.end(), audiocontext.outSamples.data(), audiocontext.outSamples.data() + audiocontext.outBytes); |
| 167 | return; |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | /*** Audio ***/ |
| 172 | LOG(LL_DEBUG, LCF_DUMP, "Encode an audio frame"); |
| 173 | |
| 174 | nutMuxer->writeAudioFrame(audiocontext.outSamples.data(), audiocontext.outBytes); |
| 175 | |
| 176 | /*** Video ***/ |
| 177 | |
| 178 | /* Number of frames to encode */ |
| 179 | int frames = 1; |
| 180 | |
| 181 | if (Global::shared_config.video_framerate) { |
| 182 | /* We must send as many video frames to match the video framerate parameter */ |
| 183 | frame_remainder += (frametime.tv_sec + ((double)frametime.tv_nsec) / 1000000000.0) * Global::shared_config.video_framerate; |
| 184 | |
| 185 | frames = (int)(frame_remainder + 0.5); |
| 186 | frame_remainder -= frames; |
| 187 | } |
no test coverage detected