Discover H264 keyframes on dequeue
This commit is contained in:
parent
ec2ed5e392
commit
79e9bca11f
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (h264_is_key_frame(buf)) {
|
||||
if (buf->flags.is_keyframe) {
|
||||
fHadKeyFrame = true;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user