322 lines
7.6 KiB
C
322 lines
7.6 KiB
C
/*
|
|
* Copyright (c) XMEDIA. All rights reserved.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
|
|
#include "video_stream.h"
|
|
|
|
#include "sample_video.h"
|
|
#include "sample_video_yuv.h"
|
|
#include "sample_video_mjpeg.h"
|
|
#include "sample_video_h264.h"
|
|
#include "sample_video_mjpeg_h264.h"
|
|
|
|
#include "venc_log.h"
|
|
|
|
#include "frame_cache.h"
|
|
|
|
#define XMEDIA_ACCESS_ENABLE 1
|
|
|
|
#define EMBEDDING_H24_IN_MJPEG 0
|
|
|
|
#if !XMEDIA_ACCESS_ENABLE
|
|
#define STREAM_FILE_PATH "./stream.bin"
|
|
#endif
|
|
|
|
#define v4l2_fourcc(a, b, c, d) \
|
|
((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
|
|
|
|
#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */
|
|
#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */
|
|
#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
|
|
#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */
|
|
#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YUV 4:2:0 */
|
|
#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */
|
|
#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
|
|
#define V4L2_PIX_FMT_H265 v4l2_fourcc('H', '2', '6', '5') /* H265 with start codes */
|
|
|
|
static int g_start = 0;
|
|
static struct encoder_property g_encoder_property;
|
|
|
|
static xmedia_payload_type format_v4l2_to_mpp(uint32_t fcc)
|
|
{
|
|
xmedia_payload_type t;
|
|
|
|
switch (fcc) {
|
|
case V4L2_PIX_FMT_YVU420:
|
|
case V4L2_PIX_FMT_YUV420:
|
|
case V4L2_PIX_FMT_NV21:
|
|
case V4L2_PIX_FMT_NV12:
|
|
case V4L2_PIX_FMT_YUYV:
|
|
case V4L2_PIX_FMT_MJPEG:
|
|
t = PT_MJPEG;
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_H264:
|
|
t = PT_H264;
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_H265:
|
|
t = PT_H265;
|
|
break;
|
|
|
|
default:
|
|
t = PT_MJPEG;
|
|
break;
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
static void pic_format_convert(xmedia_payload_type *format)
|
|
{
|
|
*format = format_v4l2_to_mpp(g_encoder_property.format);
|
|
}
|
|
|
|
static void pic_size_convert(xmedia_video_size *wh)
|
|
{
|
|
wh->width = g_encoder_property.width;
|
|
wh->height = g_encoder_property.height;
|
|
}
|
|
|
|
void get_user_format(xmedia_payload_type *format, xmedia_video_size *wh, unsigned int *framerate)
|
|
{
|
|
if (wh != NULL) {
|
|
pic_size_convert(wh);
|
|
}
|
|
|
|
if (format != NULL) {
|
|
pic_format_convert(format);
|
|
}
|
|
|
|
if (framerate != NULL) {
|
|
*framerate = g_encoder_property.fps;
|
|
}
|
|
}
|
|
|
|
/*******************************************************
|
|
* Processing Unit Operation Functions
|
|
*******************************************************/
|
|
|
|
/* Processing Unit Operation Functions End */
|
|
|
|
/*******************************************************
|
|
* Input Terminal Operation Functions
|
|
*******************************************************/
|
|
|
|
/* Input Terminal Operation Functions End */
|
|
|
|
/*******************************************************
|
|
* Stream Control Operation Functions
|
|
*******************************************************/
|
|
static int sample_video_stream_set_idr(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int sample_video_stream_init(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int sample_video_stream_deinit(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#if !XMEDIA_ACCESS_ENABLE
|
|
static int g_stop = 0;
|
|
static pthread_t send_pid = -1;
|
|
static void* send_process(void* args)
|
|
{
|
|
FILE *fp = fopen(STREAM_FILE_PATH, "r");
|
|
uvc_cache_t *uvc_cache = NULL;
|
|
frame_node_t *fnode = NULL;
|
|
|
|
g_stop = 0;
|
|
while (!g_stop && fp != NULL) {
|
|
uvc_cache = uvc_cache_get();
|
|
if (uvc_cache) {
|
|
get_node_from_queue(uvc_cache->free_queue, &fnode);
|
|
}
|
|
|
|
if (!fnode) {
|
|
usleep(100000);
|
|
} else {
|
|
fseek(fp, 0L, SEEK_SET);
|
|
fnode->used = fread((char*)fnode->mem, 1, fnode->length, fp);
|
|
venc_logi("send %d\n", fnode->used);
|
|
put_node_to_queue(uvc_cache->ok_queue, fnode);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void start_send_file(int fcc)
|
|
{
|
|
pthread_create(&send_pid, NULL, &send_process, NULL);
|
|
}
|
|
|
|
static void stop_send_file(int fcc)
|
|
{
|
|
g_stop = 1;
|
|
|
|
if (send_pid != -1) {
|
|
pthread_join(send_pid, NULL);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static int sample_video_stream_startup(void)
|
|
{
|
|
int fcc = g_encoder_property.format;
|
|
|
|
venc_logi("sample stream startup.\n");
|
|
g_start = 1;
|
|
|
|
#if !XMEDIA_ACCESS_ENABLE
|
|
start_send_file(fcc);
|
|
#else
|
|
switch (fcc) {
|
|
case V4L2_PIX_FMT_MJPEG:
|
|
#if !EMBEDDING_H24_IN_MJPEG
|
|
sample_mjpeg_init();
|
|
sample_mjpeg_startup();
|
|
#else
|
|
sample_mjpeg_h264_init();
|
|
sample_mjpeg_h264_startup();
|
|
#endif
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_H264:
|
|
case V4L2_PIX_FMT_H265:
|
|
sample_h264_init();
|
|
sample_h264_startup();
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_NV21:
|
|
case V4L2_PIX_FMT_NV12:
|
|
case V4L2_PIX_FMT_YUYV:
|
|
case V4L2_PIX_FMT_YUV420:
|
|
case V4L2_PIX_FMT_YVU420:
|
|
sample_yuv_init();
|
|
sample_yuv_startup(fcc);
|
|
break;
|
|
|
|
default:
|
|
venc_loge("Unsupported stream type.\n");
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
venc_logi("sample stream startup ok.\n");
|
|
return 0;
|
|
}
|
|
|
|
static int sample_video_stream_shutdown(void)
|
|
{
|
|
int fcc = g_encoder_property.format;
|
|
|
|
if (!g_start) {
|
|
return 0;
|
|
}
|
|
|
|
#if !XMEDIA_ACCESS_ENABLE
|
|
stop_send_file(fcc);
|
|
#else
|
|
switch (fcc) {
|
|
case V4L2_PIX_FMT_MJPEG:
|
|
#if !EMBEDDING_H24_IN_MJPEG
|
|
sample_mjpeg_shutdown();
|
|
#else
|
|
sample_mjpeg_h264_shutdown();
|
|
#endif
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_H264:
|
|
case V4L2_PIX_FMT_H265:
|
|
sample_h264_shutdown();
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_NV21:
|
|
case V4L2_PIX_FMT_NV12:
|
|
case V4L2_PIX_FMT_YUYV:
|
|
case V4L2_PIX_FMT_YUV420:
|
|
case V4L2_PIX_FMT_YVU420:
|
|
sample_yuv_shutdown();
|
|
break;
|
|
|
|
default:
|
|
venc_loge("Unsupported stream type.\n");
|
|
return -1;
|
|
}
|
|
#endif
|
|
g_start = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int sample_video_stream_set_property(struct encoder_property *p)
|
|
{
|
|
g_encoder_property = *p;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Stream Control Operation Functions End */
|
|
|
|
static struct stream_control_ops venc_sc_ops = {
|
|
.init = &sample_video_stream_init,
|
|
.deinit = &sample_video_stream_deinit,
|
|
.startup = &sample_video_stream_startup,
|
|
.shutdown = &sample_video_stream_shutdown,
|
|
.set_idr = &sample_video_stream_set_idr,
|
|
.set_property = &sample_video_stream_set_property,
|
|
};
|
|
|
|
static struct processing_unit_ops venc_pu_ops = {
|
|
/* get */
|
|
.brightness_get = NULL,
|
|
.contrast_get = NULL,
|
|
.hue_get = NULL,
|
|
.power_line_frequency_get = NULL,
|
|
.saturation_get = NULL,
|
|
.white_balance_temperature_auto_get = NULL,
|
|
.white_balance_temperature_get = NULL,
|
|
/* set */
|
|
.brightness_set = NULL,
|
|
.contrast_set = NULL,
|
|
.hue_set = NULL,
|
|
.power_line_frequency_set = NULL,
|
|
.saturation_set = NULL,
|
|
.white_balance_temperature_auto_set = NULL,
|
|
.white_balance_temperature_set = NULL,
|
|
};
|
|
|
|
static struct input_terminal_ops venc_it_ops = {
|
|
/* get */
|
|
.exposure_ansolute_time_get = NULL,
|
|
.exposure_auto_mode_get = NULL,
|
|
|
|
/* set */
|
|
.exposure_ansolute_time_set = NULL,
|
|
.exposure_auto_mode_set = NULL,
|
|
};
|
|
|
|
//static struct extension_unit_ops venc_xu_ops;
|
|
|
|
void video_stream_register(void)
|
|
{
|
|
stream_register_mpi_ops(&venc_sc_ops, &venc_pu_ops, &venc_it_ops, NULL);
|
|
}
|
|
|
|
void video_stream_unregister(void)
|
|
{
|
|
stream_register_mpi_ops(NULL, NULL, NULL, NULL);
|
|
}
|