| 337 | } |
| 338 | |
| 339 | std::vector<DecodedFrame> FfmpegDecoder::drain() { |
| 340 | std::vector<DecodedFrame> frames; |
| 341 | if (codec_ctx_ == nullptr) { |
| 342 | return frames; |
| 343 | } |
| 344 | |
| 345 | // Send NULL packet to drain |
| 346 | avcodec_send_packet(codec_ctx_, nullptr); |
| 347 | |
| 348 | AVFrame* frame = av_frame_alloc(); |
| 349 | while (avcodec_receive_frame(codec_ctx_, frame) >= 0) { |
| 350 | auto result = avFrameToDecodedFrame(frame); |
| 351 | if (result.has_value()) { |
| 352 | result->pts = frame->pts; |
| 353 | frames.push_back(std::move(*result)); |
| 354 | } |
| 355 | av_frame_unref(frame); |
| 356 | } |
| 357 | av_frame_free(&frame); |
| 358 | return frames; |
| 359 | } |
| 360 | |
| 361 | int FfmpegDecoder::width() const { |
| 362 | return codec_ctx_ != nullptr ? codec_ctx_->width : 0; |
no outgoing calls
no test coverage detected