简体   繁体   English

在C ++中从execve调用时,ffmpeg产生错误的输出

[英]ffmpeg produces bad output when called from execve in c++

im writing a c++ program that involves ffmpeg being called from a c++ program. 我正在编写一个涉及从c ++程序调用ffmpeg的c ++程序。 a couple of days ago i got it working using std::system 几天前,我使用std :: system使其正常工作

std::system("ffmpeg -threads auto -y -r 1.74659 -i /mnt/ev_ramdsk/1/%05d-capture.jpg -px_fmt yuv420p -preset ultrafast -r 10 /mnt/ev_ramdsk/1/video.mp4");

but this only worked once now this produces .mp4 videos of 8MB or so that cannot be played anywhere.. so because of a suggestion in a previous question i moved to execve. 但这现在只能工作一次,它会产生8MB左右的.mp4视频,因此无法在任何地方播放。.因此,由于上一个问题的建议,我移至execve。

Here is my code 这是我的代码

child_pid = fork();
        if(child_pid < 0){
            syslog(LOG_ERR, "ERROR: ffmpeg forking failed");
            return false;
        }
        else if(child_pid > 0){
            syslog(LOG_DEBUG, "DEBUG: forking succeeded, pid: %d", child_pid);
        }
        else if(child_pid == 0){
            char *newargv[16];
            for(int i=0; i < 15; i++) newargv[i] = (char *)malloc(sizeof(char) * 60); //allocate the array in memory
            strcpy(newargv[0], "/usr/bin/ffmpeg");
            strcpy(newargv[1], "-threads");
            strcpy(newargv[2], "auto");
            strcpy(newargv[3], "-y");
            strcpy(newargv[4], "-framerate");
            tempSS << fps;
            strcpy(newargv[5], tempSS.str().c_str());
            tempSS.str(std::string());
            strcpy(newargv[6], "-i");
            strcpy(newargv[7], std::string(conf->dir_ram + dest + "%05d-capture.jpg").c_str());
            strcpy(newargv[8], "-pix_fmt");
            strcpy(newargv[9], "yuv420p");
            strcpy(newargv[10], "-preset");
            strcpy(newargv[11], "ultrafast");
            strcpy(newargv[12], "-r");
            strcpy(newargv[13], "25");
            strcpy(newargv[14], std::string(conf->dir_ram + dest + "video.mp4").c_str());
            newargv[15] = NULL;

            for(int i=0; i < 15; i++){
                tempSS << "newargv[" << i << "] = \"" << newargv[i] << "\", ";
            }
            syslog(LOG_DEBUG, "DEBUG:newargv: %s", tempSS.str().c_str());
            tempSS.str(std::string());

            char *newenviron[] = { NULL };

            if(execve(newargv[0], newargv, newenviron) == -1){
                syslog(LOG_ERR, "ERROR: execve returned -1");
                exit(EXIT_SUCCESS);
            }
        }

        wpid = wait(&status);
        syslog(LOG_DEBUG, "DEBUG: ffmpeg child terminated, pid: %d, status: %d", wpid, status);

the output of syslog is: syslog的输出是:

May 28 00:25:03 SERVER dt_ev_maker[10471]: DEBUG: forking succeeded, pid: 10658
May 28 00:25:03 SERVER dt_ev_maker[10658]: DEBUG:newargv: 
newargv[0] = "/usr/bin/ffmpeg", 
newargv[1] = "-threads", 
newargv[2] = "auto", 
newargv[3] = "-y", 
newargv[4] = "-framerate", 
newargv[5] = "1.45097", 
newargv[6] = "-i", 
newargv[7] = "/mnt/ev_ramdsk/1/%05d-capture.jpg", 
newargv[8] = "-pix_fmt", 
newargv[9] = "yuv420p", 
newargv[10] = "-preset", 
newargv[11] = "ultrafast", 
newargv[12] = "-r", 
newargv[13] = "25", 
newargv[14] = "/mnt/ev_ramdsk/1/video.mp4",
May 28 00:25:03 SERVER dt_ev_maker[10471]: DEBUG: ffmpeg child terminated, pid: 10658, status: 256

in this case the video has about 90B size and is also corrupted. 在这种情况下,视频大小约为90B,并且也已损坏。

NOTE: if i run the same command from the command line the video can be played normally. 注意:如果我从命令行运行相同的命令,则视频可以正常播放。

what am i doing wrong? 我究竟做错了什么?

Thanks in advance! 提前致谢!

EDIT 编辑

Thanks to ouroborus (changes submitted above) i got it to make 18MB videos, but i cant play them. 感谢ouroborus(上面提交的更改),我可以制作18MB的视频,但是我不能播放它们。

It seems that execve() needs it's arrays to have a last element that is NULL . 似乎execve()需要它的数组具有最后一个为NULL元素。 Extend your newargv array by one and set the last element to NULL before passing it into execve() . newargv数组扩展1,并将最后一个元素设置为NULL然后再将其传递到execve()

Ref: Using execve for the first time 参考: 第一次使用execve

So, the code that finally worked was: 因此,最终起作用的代码是:

pid_t wpid, child_pid;
            int status;
            int fd = open(std::string(conf->dir_ram + "ffmpeg.txt").c_str(), O_CREAT | O_WRONLY, 0777);
            if(fd < 0){
                syslog(LOG_ERR, "ERROR: open returned -1");
                return false;
            }

            child_pid = fork();
            if(child_pid < 0){
                syslog(LOG_ERR, "ERROR: ffmpeg forking failed");
                return false;
            }
            else if(child_pid > 0){
                syslog(LOG_DEBUG, "DEBUG: forking succeeded, pid: %d", child_pid);
            }
            else if(child_pid == 0){

                if( close(1) < 0 ){
                    syslog(LOG_ERR, "ERROR: close returned -1");
                    return false;
                }
                if( dup2(fd, 1) < 0 ){
                    syslog(LOG_ERR, "ERROR: dup2 returned -1");
                    return false;
                }

                char *newargv[18];
                for(int i=0; i < 17; i++) newargv[i] = (char *)malloc(sizeof(char) * 60); //allocate the array in memory
                strcpy(newargv[0], conf->ffmpeg_path.c_str());
                strcpy(newargv[1], "-threads");
                strcpy(newargv[2], "auto");
                strcpy(newargv[3], "-y");
                strcpy(newargv[4], "-r");
                tempSS << fps;
                strcpy(newargv[5], tempSS.str().c_str());
                tempSS.str(std::string());
                strcpy(newargv[6], "-i");
                strcpy(newargv[7], std::string(conf->dir_ram + dest + "%05d-capture.jpg").c_str());
                strcpy(newargv[8], "-pix_fmt");
                strcpy(newargv[9], "yuv420p");
                strcpy(newargv[10], "-c:v");
                strcpy(newargv[11], "libx264");
                strcpy(newargv[12], "-preset");
                strcpy(newargv[13], "ultrafast");
                strcpy(newargv[14], "-r");
                strcpy(newargv[15], conf->ffmpeg_rate.c_str());
                strcpy(newargv[16], std::string(conf->dir_ram + dest + "video.mp4").c_str());
                newargv[17] = NULL;

                char *newenviron[] = { NULL };

                if(execve(newargv[0], newargv, newenviron) == -1){
                    syslog(LOG_ERR, "ERROR: execve returned -1");
                    exit(EXIT_SUCCESS);
                }
            }

            wpid = wait(&status);

if i comment the whole open() and dup2() part the videos get corrupted. 如果我评论整个open()和dup2()部分,则视频会损坏。 i have no idea why, but without that it doesnt work. 我不知道为什么,但没有它不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM