Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define PIPE_OUT 0
- #define PIPE_IN 1
- // based on https://github.com/tsoding/musializer/blob/master/src/ffmpeg_linux.c
- typedef struct{
- int out_fd;
- pid_t pid;
- } FFMPEG;
- bool ffmpeg_start_screen_capture(
- FFMPEG* self,
- unsigned int pos_x,
- unsigned int pos_y,
- unsigned int res_x,
- unsigned int res_y
- ){
- int pipefd[2];
- if(pipe(pipefd) < 0){
- TraceLog(LOG_ERROR, "ffmpeg failed to init pipe");
- return false;
- }
- pid_t child = fork();
- if(child < 0){
- TraceLog(LOG_ERROR, "ffmpeg failed to fork()");
- return false;
- }
- if(child == 0){
- if(dup2(pipefd[PIPE_IN], STDOUT_FILENO) < 0){
- TraceLog(LOG_ERROR, "ffmpeg failed to bind parent pipe to child stdout");
- return false;
- }
- close(pipefd[PIPE_OUT]);
- // redirects ffmpeg logging
- #if 1
- int null_fd = open("/dev/null", O_WRONLY);
- if(null_fd < 0){
- TraceLog(LOG_ERROR, "ffmpeg failed to open null pipe");
- return false;
- }
- if(dup2(null_fd, STDERR_FILENO) < 0){
- TraceLog(LOG_ERROR, "ffmpeg failed to bind null pipe to child stderr");
- return false;
- }
- #endif
- char res_arg[128];
- snprintf(res_arg, sizeof(res_arg), "%ux%u", res_x, res_y);
- char scale_arg[256];
- int res = snprintf(scale_arg, sizeof(res_arg), "scale=%u:%u", res_x, res_y);
- assert(res > 10);
- char pos_arg[128];
- snprintf(pos_arg, sizeof(res_arg), ":0.0+%u,%u", pos_x, pos_y);
- fprintf(stderr, "scale_arg res: %d\n", res);
- fprintf(stderr, "scale_arg: %s\n", res_arg);
- int ret = execlp(
- "ffmpeg",
- "ffmpeg",
- "-video_size", "1920x1080",//res_arg,
- "-framerate", "30",
- "-f", "x11grab",
- "-i", pos_arg,
- "-f", "rawvideo",
- "-vf", scale_arg,
- "-pix_fmt","rgba",
- "-an",
- "-",
- NULL
- );
- if (ret < 0) {
- TraceLog(LOG_ERROR, "FFMPEG CHILD: could not run ffmpeg as a child process: %s", strerror(errno));
- exit(1);
- }
- assert(0 && "unreachable");
- exit(1);
- }
- self->pid = child;
- self->out_fd = pipefd[PIPE_OUT];
- return true;
- }
- void ffmpeg_read(FFMPEG* self, unsigned char* buffer, unsigned int res_x, unsigned int res_y){
- int frame_size = res_x * res_y * sizeof(Color);
- while(frame_size > 0){
- int res = read(self->out_fd, buffer, frame_size);
- if(res < 0){
- TraceLog(LOG_ERROR, "ffmpeg read error: %s", strerror(errno));
- exit(1);
- }
- frame_size-=res;
- buffer+=res;
- }
- }
- void ffmpeg_stop(FFMPEG* self){
- close(self->out_fd);
- kill(self->pid, SIGTERM);
- waitpid(self->pid, NULL, 0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement