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/buffer_list.h"
|
||||||
#include "device/device.h"
|
#include "device/device.h"
|
||||||
#include "util/opts/log.h"
|
#include "util/opts/log.h"
|
||||||
|
#include "util/opts/fourcc.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@ -144,6 +145,24 @@ int buffer_list_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf)
|
|||||||
return 1;
|
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 *buffer_list_dequeue(buffer_list_t *buf_list)
|
||||||
{
|
{
|
||||||
buffer_t *buf = NULL;
|
buffer_t *buf = NULL;
|
||||||
@ -174,6 +193,10 @@ buffer_t *buffer_list_dequeue(buffer_list_t *buf_list)
|
|||||||
buf->dma_source = NULL;
|
buf->dma_source = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buf_list->fmt.format == V4L2_PIX_FMT_H264) {
|
||||||
|
buffer_update_h264_key_frame(buf);
|
||||||
|
}
|
||||||
|
|
||||||
buf_list->frames++;
|
buf_list->frames++;
|
||||||
return buf;
|
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)
|
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) {
|
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) {
|
if (!status->had_key_frame) {
|
||||||
|
@ -31,31 +31,10 @@ typedef struct {
|
|||||||
bool requested_key_frame;
|
bool requested_key_frame;
|
||||||
} http_video_status_t;
|
} 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)
|
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) {
|
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) {
|
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);
|
void http_option(struct http_worker_s *worker, FILE *stream);
|
||||||
|
|
||||||
// H264
|
// H264
|
||||||
bool h264_is_key_frame(struct buffer_s *buf);
|
|
||||||
void http_h264_video(struct http_worker_s *worker, FILE *stream);
|
void http_h264_video(struct http_worker_s *worker, FILE *stream);
|
||||||
void http_mkv_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);
|
void http_mp4_video(struct http_worker_s *worker, FILE *stream);
|
||||||
|
@ -75,7 +75,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h264_is_key_frame(buf)) {
|
if (buf->flags.is_keyframe) {
|
||||||
fHadKeyFrame = true;
|
fHadKeyFrame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!had_key_frame) {
|
if (!had_key_frame) {
|
||||||
if (!h264_is_key_frame(buf)) {
|
if (!buf->flags.is_keyframe) {
|
||||||
device_video_force_key(buf->buf_list->dev);
|
device_video_force_key(buf->buf_list->dev);
|
||||||
LOG_VERBOSE(self, "Skipping as key frame was not yet sent.");
|
LOG_VERBOSE(self, "Skipping as key frame was not yet sent.");
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user