Skip to content

Commit

Permalink
simplify interface
Browse files Browse the repository at this point in the history
No need for separate interface for multi-frame and frame streaming.

The C way.

Related to #4
  • Loading branch information
bmegli committed Apr 12, 2020
1 parent a07ea52 commit e73095b
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 48 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ See [HVE](https://github.com/bmegli/hardware-video-encoder) docs for details abo
struct nhve_net_config net_config = {IP, PORT};
struct nhve_hw_config hw_config = {WIDTH, HEIGHT, FRAMERATE, DEVICE, ENCODER,
PIXEL_FORMAT, PROFILE, BFRAMES, BITRATE, QP, GOP_SIZE, COMPRESSION_LEVEL};
//initialize
struct nhve *streamer = nhve_init(&net_config, &hw_config);
//initialize single hardware encoder
struct nhve *streamer = nhve_init(&net_config, &hw_config, 1);

struct nhve_frame frame = { 0 };

Expand All @@ -125,12 +125,12 @@ See [HVE](https://github.com/bmegli/hardware-video-encoder) docs for details abo
frame.data[1]=color; //dummy UV plane
//encode and send this frame
if( nhve_send_frame(streamer, framenumber++, &frame) != NHVE_OK)
if( nhve_send(streamer, framenumber++, &frame) != NHVE_OK)
break; //break on error
}

//flush the streamer by sending NULL frame
nhve_send_frame(streamer, framenumber, NULL);
nhve_send(streamer, framenumber, NULL);

nhve_close(streamer);
```
Expand Down
6 changes: 3 additions & 3 deletions examples/nhve_stream_h264.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ int main(int argc, char* argv[])
struct nhve *streamer;

//initialize library with nhve_init
if( (streamer = nhve_init(&net_config, &hw_config)) == NULL )
if( (streamer = nhve_init(&net_config, &hw_config, 1)) == NULL )
return hint_user_on_failure(argv);

//do the actual encoding
Expand Down Expand Up @@ -92,15 +92,15 @@ int streaming_loop(struct nhve *streamer)
frame.data[1]=color;

//encode and send this frame, the framenumber f has to increase
if( nhve_send_frame(streamer, f, &frame) != NHVE_OK)
if(nhve_send(streamer, f, &frame) != NHVE_OK)
break; //break on error

//simulate real time source (sleep according to framerate)
usleep(useconds_per_frame);
}

//flush the encoder by sending NULL frame, encode some last frames returned from hardware
nhve_send_frame(streamer, f, NULL);
nhve_send(streamer, f, NULL);

//did we encode everything we wanted?
//convention 0 on success, negative on failure
Expand Down
6 changes: 3 additions & 3 deletions examples/nhve_stream_hevc10.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ int main(int argc, char* argv[])
struct nhve *streamer;

//initialize library with nhve_init
if( (streamer = nhve_init(&net_config, &hw_config)) == NULL )
if( (streamer = nhve_init(&net_config, &hw_config, 1)) == NULL )
return hint_user_on_failure(argv);

//do the actual encoding
Expand Down Expand Up @@ -95,15 +95,15 @@ int streaming_loop(struct nhve *streamer)
frame.data[1] = (uint8_t*)color;

//encode and send this frame, the framenumber f has to increase
if( nhve_send_frame(streamer, f, &frame) != NHVE_OK)
if(nhve_send(streamer, f, &frame) != NHVE_OK)
break; //break on error

//simulate real time source (sleep according to framerate)
usleep(useconds_per_frame);
}

//flush the encoder by sending NULL frame, encode some last frames returned from hardware
nhve_send_frame(streamer, f, NULL);
nhve_send(streamer, f, NULL);

//did we encode everything we wanted?
//convention 0 on success, negative on failure
Expand Down
6 changes: 3 additions & 3 deletions examples/nhve_stream_multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ int main(int argc, char* argv[])
struct nhve *streamer;

//initialize library with nhve_multi_init
if( (streamer = nhve_multi_init(&net_config, hw_config, 2)) == NULL )
if( (streamer = nhve_init(&net_config, hw_config, 2)) == NULL )
return hint_user_on_failure(argv);

//do the actual encoding
Expand Down Expand Up @@ -108,15 +108,15 @@ int streaming_loop(struct nhve *streamer)
frames[1].data[1]=color;

//encode and send this frame, the framenumber f has to increase
if( nhve_send_frames(streamer, f, frames, 2) != NHVE_OK)
if(nhve_send(streamer, f, frames) != NHVE_OK)
break; //break on error

//simulate real time source (sleep according to framerate)
usleep(useconds_per_frame);
}

//flush the encoder by sending NULL frame, encode some last frames returned from hardware
nhve_send_frame(streamer, f, NULL);
nhve_send(streamer, f, NULL);

//did we encode everything we wanted?
//convention 0 on success, negative on failure
Expand Down
38 changes: 11 additions & 27 deletions nhve.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,7 @@ struct nhve

static struct nhve *nhve_close_and_return_null(struct nhve *n);

struct nhve *nhve_init(const struct nhve_net_config *net_config,const struct nhve_hw_config *hw_config)
{
return nhve_multi_init(net_config, hw_config, 1);
}

struct nhve *nhve_multi_init(const struct nhve_net_config *net_config,const struct nhve_hw_config *hw_config, int hw_size)
struct nhve *nhve_init(const struct nhve_net_config *net_config,const struct nhve_hw_config *hw_config, int hw_size)
{
struct nhve *n, zero_nhve = {0};
struct mlsp_config mlsp_cfg = {net_config->ip, net_config->port, 0};
Expand All @@ -56,17 +51,17 @@ struct nhve *nhve_multi_init(const struct nhve_net_config *net_config,const stru
}

*n = zero_nhve;

if( (n->network_streamer = mlsp_init_client(&mlsp_cfg)) == NULL )
{
fprintf(stderr, "nhve: failed to initialize network client\n");
return nhve_close_and_return_null(n);
}

n->hardware_encoders_size = hw_size;

for(int i=0;i<hw_size;++i)
{
{
struct hve_config hve_cfg = {hw_config[i].width, hw_config[i].height, hw_config[i].framerate, hw_config[i].device,
hw_config[i].encoder, hw_config[i].pixel_format, hw_config[i].profile, hw_config[i].max_b_frames,
hw_config[i].bit_rate, hw_config[i].qp, hw_config[i].gop_size, hw_config[i].compression_level};
Expand All @@ -75,7 +70,7 @@ struct nhve *nhve_multi_init(const struct nhve_net_config *net_config,const stru
{
fprintf(stderr, "nhve: failed to initalize hardware encoder %d\n", i);
return nhve_close_and_return_null(n);
}
}
}

return n;
Expand All @@ -95,33 +90,22 @@ void nhve_close(struct nhve *n)
free(n);
}

// NULL frame to flush
int nhve_send_frame(struct nhve *n, uint16_t framenumber, struct nhve_frame *frame)
{
return nhve_send_frames(n, framenumber, frame, 1);
}

//NULL frames to flush all encoders
//NULL frames[i].data[0] is legal and silently skipped
//this is necessary to support multiple encoders with e.g. different B frames
int nhve_send_frames(struct nhve *n, uint16_t framenumber, struct nhve_frame *frames, int frames_size)
int nhve_send(struct nhve *n, uint16_t framenumber, struct nhve_frame *frames)
{
struct hve_frame video_frames[NHVE_MAX_ENCODERS] = {0};

if(frames_size > n->hardware_encoders_size)
{
fprintf(stderr, "nhve: requested to send more frames than initialized encoders\n");
return NHVE_ERROR;
}
const int encoders = n->hardware_encoders_size;

if(frames) //NULL frames is valid input - flush the encoders
for(int i=0;i<frames_size;++i)
for(int i=0;i<encoders;++i)
{ //copy pointers to data and linesizes (just a few bytes)
memcpy(video_frames[i].data, frames[i].data, sizeof(frames[i].data));
memcpy(video_frames[i].linesize, frames[i].linesize, sizeof(frames[i].linesize));
}

for(int i=0;i<frames_size;++i)
for(int i=0;i<encoders;++i)
{
if(!frames) //flush all encoders
if( hve_send_frame(n->hardware_encoder[i], NULL) != HVE_OK)
Expand Down Expand Up @@ -149,7 +133,7 @@ int nhve_send_frames(struct nhve *n, uint16_t framenumber, struct nhve_frame *fr

keep_working = 0;

for(int i=0;i<frames_size;++i)
for(int i=0;i<encoders;++i)
if( (encoded_frames[i] = hve_receive_packet(n->hardware_encoder[i], &failed[i])) )
{
network_frame.data[i] = encoded_frames[i]->data;
Expand All @@ -169,7 +153,7 @@ int nhve_send_frames(struct nhve *n, uint16_t framenumber, struct nhve_frame *fr
} while(keep_working);

//NULL packet and non-zero failed indicates failure during encoding
for(int i=0;i<frames_size;++i)
for(int i=0;i<encoders;++i)
if(failed[i] != HVE_OK)
{
fprintf(stderr, "nhve: failed to encode frame\n");
Expand Down
13 changes: 5 additions & 8 deletions nhve.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,16 @@ enum nhve_retval_enum
};

//NULL on error, non NULL on success
struct nhve *nhve_init(const struct nhve_net_config *net_config, const struct nhve_hw_config *hw_config);

//NULL on error, non NULL on success
struct nhve *nhve_multi_init(const struct nhve_net_config *net_config, const struct nhve_hw_config *hw_config, int hw_size);
struct nhve *nhve_init(const struct nhve_net_config *net_config, const struct nhve_hw_config *hw_config, int hw_size);

void nhve_close(struct nhve *n);


//NHVE_OK on success, NHVE_ERROR on error
//pass NULL frame to flush encoder
int nhve_send_frame(struct nhve *n, uint16_t framenumber, struct nhve_frame *frame);

int nhve_send_frames(struct nhve *n, uint16_t framenumber, struct nhve_frame *frames, int frames_size);
//NULL frames to flush all encoders
//NULL frames[i].data[0] is legal and silently skipped
//this is necessary to support e.g. different framerates or B frames
int nhve_send(struct nhve *n, uint16_t framenumber, struct nhve_frame *frames);


#ifdef __cplusplus
Expand Down

0 comments on commit e73095b

Please sign in to comment.