Opened 16 months ago
#11565 new enhancement
dshow wrapper packet AV_PKT_FLAG_KEY flagging
| Reported by: | Matt Carpenter | Owned by: | |
|---|---|---|---|
| Priority: | normal | Component: | avformat |
| Version: | 6.1.1 | Keywords: | dshow |
| Cc: | Matt Carpenter | Blocked By: | |
| Blocking: | Reproduced by developer: | no | |
| Analyzed by developer: | no |
Description
Summary of the enhancement:
Explanation:
% ffprobe -f dshow -video_pin_name 1 -i video="H264 USB Camera" -show_entries frame=key_frame ffmpeg version libavutil 56. 63.100 / 56. 63.100 libavcodec 58.115.102 / 58.115.102 libavformat 58. 65.101 / 58. 65.101 libavdevice 58. 11.103 / 58. 11.103 libavfilter 7. 95.100 / 7. 95.100 libswscale 5. 8.100 / 5. 8.100 libswresample 3. 8.100 / 3. 8.100 libpostproc 55. 8.100 / 55. 8.100
The above command displays key_frames coming from my USB camera once-per-second. Camera is ELP-USBFHD06H-BL170 with the h264 stream on video pin 1. Inside my recorder program the following code is used to try and detect key_frames on the same camera.
input->input_ctx = avformat_alloc_context(); input->input_ctx->video_codec_id = AV_CODEC_ID_H264; ... av_read_frame(input->input_ctx, in_packet); in_packet->flags & AV_PKT_FLAG_KEY) == AV_PKT_FLAG_KEY
The code above does not detect any packets having the key_frame flag set.
Original question asked and answered: https://superuser.com/questions/1888999/trying-to-understand-how-key-frames-work-when-using-ffmpeg-on-windows-with-a-usb
A workaround for my program was the following code to search for any IDR NAL units inside the packet, and consider any packets containing IDR NAL units as keyfames.
/*
* Look inside the packet's frame buffer for NAL units of type IDR frame
* @returns 0 if not 1 if found
*/
int is_idr_frame(AVPacket *pkt) {
if (pkt->size < 6) return 0; // Ensure packet is large enough for parsing
const uint8_t *data = pkt->data;
// Look for NAL unit start codes (00 00 00 01 or 00 00 01)
for (int i = 0; i < pkt->size - 4; i++) {
if (data[i] == 0x00 && data[i + 1] == 0x00 &&
((data[i + 2] == 0x01) || (data[i + 2] == 0x00 && data[i + 3] == 0x01))) {
uint8_t nal_type = data[i + 2] == 0x01 ? (data[i + 3] & 0x1F) : (data[i + 4] & 0x1F);
if (nal_type == 5) // NAL type 5 = IDR frame
return 1;
}
}
return 0;
}
Suggested enhancement for dshow wrapper - set the AV_PKT_FLAG_KEY on AVPacket.


