Discover H264 keyframes on dequeue

This commit is contained in:
Kamil Trzciński 2022-10-29 11:36:58 +02:00
parent ec2ed5e392
commit 79e9bca11f
6 changed files with 27 additions and 26 deletions

View File

@ -2,6 +2,7 @@
#include "device/buffer_list.h"
#include "device/device.h"
#include "util/opts/log.h"
#include "util/opts/fourcc.h"
#include <pthread.h>
#include <inttypes.h>
@ -144,6 +145,24 @@ int buffer_list_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf)
return 1;
}
static void buffer_update_h264_key_frame(buffer_t *buf)
{
unsigned char *data = buf->start;
static const int N = 8;
char buffer [3*N+1];
buffer[sizeof(buffer)-1] = 0;
for(int j = 0; j < N; j++)
sprintf(&buffer[sizeof(buffer)/N*j], "%02X ", data[j]);
if (buf->flags.is_keyframe) {
LOG_DEBUG(buf, "Got key frame (from V4L2)!: %s", buffer);
} else if (buf->used >= 5 && (data[4] & 0x1F) == 0x07) {
LOG_DEBUG(buf, "Got key frame (from buffer)!: %s", buffer);
buf->flags.is_keyframe = true;
}
}
buffer_t *buffer_list_dequeue(buffer_list_t *buf_list)
{
buffer_t *buf = NULL;
@ -174,6 +193,10 @@ buffer_t *buffer_list_dequeue(buffer_list_t *buf_list)
buf->dma_source = NULL;
}
if (buf_list->fmt.format == V4L2_PIX_FMT_H264) {
buffer_update_h264_key_frame(buf);
}
buf_list->frames++;
return buf;

View File

@ -77,7 +77,7 @@ static int http_ffmpeg_write_to_stream(void *opaque, uint8_t *buf, int buf_size)
static int http_ffmpeg_video_buf_part(buffer_lock_t *buf_lock, buffer_t *buf, int frame, http_ffmpeg_status_t *status)
{
if (!status->had_key_frame) {
status->had_key_frame = h264_is_key_frame(buf);
status->had_key_frame = buf->flags.is_keyframe;
}
if (!status->had_key_frame) {

View File

@ -31,31 +31,10 @@ typedef struct {
bool requested_key_frame;
} http_video_status_t;
bool h264_is_key_frame(buffer_t *buf)
{
unsigned char *data = buf->start;
static const int N = 8;
char buffer [3*N+1];
buffer[sizeof(buffer)-1] = 0;
for(int j = 0; j < N; j++)
sprintf(&buffer[sizeof(buffer)/N*j], "%02X ", data[j]);
if (buf->flags.is_keyframe) {
LOG_DEBUG(buf, "Got key frame (from V4L2)!: %s", buffer);
return true;
} else if (buf->used >= 5 && (data[4] & 0x1F) == 0x07) {
LOG_DEBUG(buf, "Got key frame (from buffer)!: %s", buffer);
return true;
}
return false;
}
int http_video_buf_part(buffer_lock_t *buf_lock, buffer_t *buf, int frame, http_video_status_t *status)
{
if (!status->had_key_frame) {
status->had_key_frame = h264_is_key_frame(buf);
status->had_key_frame = buf->flags.is_keyframe;
}
if (!status->had_key_frame) {

View File

@ -17,7 +17,6 @@ void http_stream(struct http_worker_s *worker, FILE *stream);
void http_option(struct http_worker_s *worker, FILE *stream);
// H264
bool h264_is_key_frame(struct buffer_s *buf);
void http_h264_video(struct http_worker_s *worker, FILE *stream);
void http_mkv_video(struct http_worker_s *worker, FILE *stream);
void http_mp4_video(struct http_worker_s *worker, FILE *stream);

View File

@ -75,7 +75,7 @@ public:
return;
}
if (h264_is_key_frame(buf)) {
if (buf->flags.is_keyframe) {
fHadKeyFrame = true;
}

View File

@ -115,7 +115,7 @@ public:
}
if (!had_key_frame) {
if (!h264_is_key_frame(buf)) {
if (!buf->flags.is_keyframe) {
device_video_force_key(buf->buf_list->dev);
LOG_VERBOSE(self, "Skipping as key frame was not yet sent.");
return;