LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-08-2019, 07:09 AM   #121
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,257
Blog Entries: 13

Rep: Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350

Quote:
Originally Posted by jsbjsb001 View Post
Here's what the code looks like now;
Code:
    // check if input file can be read, and if not, abort program execution - no point in continuing execution in that case...
    int access_return = access(argv[2], R_OK);
    if ( access_return == -1) {
       fprintf(stderr, "Input file cannot be read, aborting.\nDoes it exist?\n");
       exit (1);
    }
    ...
    if ( (configfile = fopen("ffcliFront.conf", "r") ) == NULL )  {
Perhaps an incremental change you ought to consider is to actually use the program argument you have validated versus a hard-coded file name.

Test case #1 would be to pass in the name of your config file and verify that it continues to work.
 
Old 08-08-2019, 12:14 PM   #122
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,827

Original Poster
Rep: Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020
I'm sorry, I'm not following you RT. The input file and the config file are two different things for two different purposes. The input file (argv[2]) is the filename that's passed to ffmpeg, the config file (ffcliFront.conf) is for the program to get the arguments from to pass to ffmpeg, AFTER the input filename.

Anyway, I've got good news and bad news. The good news is that, I managed to get my program to send the args to the function that executes ffmpeg and passes the args from the config file to ffmpeg. And execute ffmpeg from my program, with the args in the ffargs array. But it doesn't seem to passing them to ffmpeg properly. Basically ffmpeg complains about the same arguments from my program, but if I run ffmpeg directly at the command-line with exactly the same arguments, it does "see" them properly. Admittedly, I had a "presets" file from WinFF laying around, so I just copied and pasted some lines from that. So while the version of ffmpeg I have doesn't seem to have the "hq" preset, ffmpeg should be giving a different message complaining about that to the one it's giving. I've got a strong feeling the problem is related to the output file arg (argv[3]).

Also, I've been trying to figure out how to get my program to display an error message and quit, if say for example you were to only have the format_id (argv[1]) in the config file, but nothing after it, like for example just "test, ", and that's it (no args to be passed to ffmpeg), but I cannot get anything I try to work - it either doesn't make any difference and uploads the line into the array anyway, or it issues the error message even when the line is a valid one. I ended up giving up, but it would be nice for my program to be able to detect lines that only have a string for the format_id (argv[1]), but nothing after it, and be able to issue an error and quit.

On the upside, I've added some code to hopefully deal with comments - so they should be ignored.

Anyway, this is what happens when I use my program to launch ffmpeg;

Code:
james@jamespc: ffcliFront> ./ffcliFront test /multimediavol/tvrec/Australian\ Crime\ Stories.mpg /multimediavol/tvrec/test.mp4
argv[1] = test
Line from config file: test, -crf 35.0, -vcodec libx264, -vpre hq, -acodec libfaac, -ar 48000, -ab 128kb, -coder 1, -flags +loop, -cmp +chroma, -partitions +parti4x4+partp8x8+partb8x8, -me_method hex, -subq 6, -me_range 16, -g 250, -keyint_min 25, -sc_threshold 40, -i_qfactor 0.71, -b_strategy 1, -threads 0

Found string: test
tokenPtr = test
arg: -i 
arg: /multimediavol/tvrec/Australian Crime Stories.mpg
arg:  -crf 35.0
arg:  -vcodec libx264
arg:  -vpre hq
arg:  -acodec libfaac
arg:  -ar 48000
arg:  -ab 128kb
arg:  -coder 1
arg:  -flags +loop
arg:  -cmp +chroma
arg:  -partitions +parti4x4+partp8x8+partb8x8
arg:  -me_method hex
arg:  -subq 6
arg:  -me_range 16
arg:  -g 250
arg:  -keyint_min 25
arg:  -sc_threshold 40
arg:  -i_qfactor 0.71
arg:  -b_strategy 1
arg:  -threads 0

arg: /multimediavol/tvrec/test.mp4
ffmpeg version 4.1.3 Copyright (c) 2000-2019 the FFmpeg developers
  built with clang version 8.0.1 (branches/release_80)
  configuration: --cc=/usr/bin/clang --cxx=/usr/bin/clang++ --ranlib=ranlib --prefix=/usr --enable-shared --libdir=/usr/lib64 --shlibdir=/usr/lib64 --incdir=/usr/include --disable-stripping --enable-avresample --enable-postproc --enable-gpl --enable-version3 --enable-nonfree --enable-ffplay --disable-lto --enable-pthreads --enable-libtheora --enable-libvorbis --disable-encoder=vorbis --enable-libvpx --enable-runtime-cpudetect --enable-libdc1394 --enable-librtmp --enable-libspeex --enable-libfreetype --enable-libgsm --enable-libcelt --enable-libopencv --enable-frei0r --enable-libopenjpeg --enable-libxavs --enable-libmodplug --enable-libass --enable-gnutls --enable-libcdio --enable-libpulse --enable-libv4l2 --enable-openal --enable-opengl --enable-libzmq --enable-libzvbi --enable-libwavpack --enable-libssh --enable-libsoxr --enable-libtwolame --enable-libopus --enable-libilbc --enable-libiec61883 --enable-libgme --enable-libcaca --enable-libbluray --enable-ladspa --enable-libwebp --enable-avisynth --enable-fontconfig --enable-libvidstab --enable-libflite --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-libbs2b --enable-libmp3lame --enable-libfdk-aac-dlopen --enable-libopencore-amrnb-dlopen --enable-libopencore-amrwb-dlopen --enable-libx264-dlopen --enable-libx265-dlopen --enable-libxvid-dlopen --enable-opencl
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
Output #0, mpeg, to '/multimediavol/tvrec/Australian Crime Stories.mpg':
Output file #0 does not contain any stream
This is what happens when using ffmpeg directly (where clearly the "hq" preset isn't present on my system);

Code:
james@jamespc: ffcliFront> ffmpeg -i /multimediavol/tvrec/Australian\ Crime\ Stories.mpg -crf 35.0 -vcodec libx264 -vpre hq -acodec libfaac -ar 48000 -ab 128kb -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 /multimediavol/tvrec/test.mp4
ffmpeg version 4.1.3 Copyright (c) 2000-2019 the FFmpeg developers
  built with clang version 8.0.1 (branches/release_80)
  configuration: --cc=/usr/bin/clang --cxx=/usr/bin/clang++ --ranlib=ranlib --prefix=/usr --enable-shared --libdir=/usr/lib64 --shlibdir=/usr/lib64 --incdir=/usr/include --disable-stripping --enable-avresample --enable-postproc --enable-gpl --enable-version3 --enable-nonfree --enable-ffplay --disable-lto --enable-pthreads --enable-libtheora --enable-libvorbis --disable-encoder=vorbis --enable-libvpx --enable-runtime-cpudetect --enable-libdc1394 --enable-librtmp --enable-libspeex --enable-libfreetype --enable-libgsm --enable-libcelt --enable-libopencv --enable-frei0r --enable-libopenjpeg --enable-libxavs --enable-libmodplug --enable-libass --enable-gnutls --enable-libcdio --enable-libpulse --enable-libv4l2 --enable-openal --enable-opengl --enable-libzmq --enable-libzvbi --enable-libwavpack --enable-libssh --enable-libsoxr --enable-libtwolame --enable-libopus --enable-libilbc --enable-libiec61883 --enable-libgme --enable-libcaca --enable-libbluray --enable-ladspa --enable-libwebp --enable-avisynth --enable-fontconfig --enable-libvidstab --enable-libflite --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-libbs2b --enable-libmp3lame --enable-libfdk-aac-dlopen --enable-libopencore-amrnb-dlopen --enable-libopencore-amrwb-dlopen --enable-libx264-dlopen --enable-libx265-dlopen --enable-libxvid-dlopen --enable-opencl
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
[mpeg @ 0x1dd5c40] start time for stream 0 is not set in estimate_timings_from_pts
Input #0, mpeg, from '/multimediavol/tvrec/Australian Crime Stories.mpg':
  Duration: 00:46:10.66, start: 0.242378, bitrate: 2042 kb/s
    Stream #0:0[0x1bf]: Data: dvd_nav_packet
    Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:2[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 256 kb/s
File for preset 'hq' not found
This is the config file (ffcliFront.conf);

Code:
# mp4 video
test, -crf 35.0, -vcodec libx264, -vpre hq, -acodec libfaac, -ar 48000, -ab 128kb, -coder 1, -flags +loop, -cmp +chroma, -partitions +parti4x4+partp8x8+partb8x8, -me_method hex, -subq 6, -me_range 16, -g 250, -keyint_min 25, -sc_threshold 40, -i_qfactor 0.71, -b_strategy 1, -threads 0
# mp3 audio
test1, -acodec libmp3lame, -ab 192kb, -ac 2, -ar 44100, -vn
# wmv video
test2, -vn,  -acodec wmav2, -ab 160kb
test3,
And here's the code as it stands;

Code:
// includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>

char readConfigFile(char *argv[]);
char buildFfCmdline(char *tokenPtr, char *argv[]);
char execFfmpeg(char *ffcmdline[]);

// main function
int main(int argc, char *argv[]) {
  
    if ( argc < 4 ) {
       fprintf (stderr, "Missing option or filename\nUSAGE: ffcliFront <format_id> <input_file> <output_file>\n");
       return 1;
    }
    
    // check if input file can be read, and if not, abort program execution - no point in continuing execution in that case...
    int access_return = access(argv[2], R_OK);
    if ( access_return == -1 ) {
       fprintf(stderr, "Input file cannot be read, aborting.\nDoes it exist?\n");
       exit (1);
    }          
    readConfigFile(argv);
   
    return 0;    
}

char readConfigFile(char *argv[]) {

    char configLine[300];
    char *tokenPtr;
    bool foundStr = false;
                  
    // read config file
    FILE *configfile;
      
    if ( (configfile = fopen("ffcliFront.conf", "r")) == NULL )  {
       fprintf(stderr, "Configuration file not found, exiting.\n");
       return 1;        
    }
    
    printf("argv[1] = %s\n", argv[1]);
           
    while( fgets(configLine, 300, configfile ) != NULL) {
          if ( configLine[0] == '#' ) {
             continue;
          }
          printf("Line from config file: %s\n", configLine);
          tokenPtr = strtok(configLine, ",");               
          int result = strcasecmp(tokenPtr, argv[1]);
          if ( result == 0 )  {
             foundStr = true;
             printf("Found string: %s\ntokenPtr = %s\n", configLine, tokenPtr);
             buildFfCmdline(tokenPtr, argv);                    
          }
               
    }
    if (foundStr == false) {
       fprintf(stderr, "\"%s\" format_id not found in configuration file, exiting.\nCheck ffcliFront.conf for a valid format_id or specify a format_id that exists.\n", argv[1]);
       return 1;
    }     
    fclose(configfile);
    
    return 0;
}
                   
char buildFfCmdline(char *tokenPtr, char *argv[]) {
    
    static char *ffargs[300] = {0};
    size_t i = 0;
                
    //ffargs[i++] = "/usr/bin/ffmpeg";
    ffargs[i++] = "-i ";
    ffargs[i++] = argv[2];
        
    while( tokenPtr != NULL ) {
          tokenPtr = strtok(NULL, ",");                
          if (tokenPtr) {                    
             ffargs[i++] = tokenPtr;                    
          }               
    }    
    ffargs[i++] = argv[3];                   
    //pass char array with ffmpeg args & call execFfmpeg() fuction with args from config file
    execFfmpeg(ffargs);
 
    return 0;
}      

char execFfmpeg(char *ffcmdline[]) {
        
    for ( char **p = ffcmdline ; *p ; p++ ) {
            printf("arg: %s\n", *p);
    }
    //run fmpeg with args from config file & filename supplied to this program. 
    execv ("/usr/bin/ffmpeg", ffcmdline);
	
    return 0;
}
Thanks again for any help.
 
Old 08-08-2019, 01:22 PM   #123
GazL
LQ Veteran
 
Registered: May 2008
Posts: 5,789

Rep: Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705
When you run strtok, make sure that you're also using space and \n as delimiters. It looks like your "-threads" "0" was actually a "-threads" "0\n" there because of the \n on the end of the line and that is likely upsetting ffmpeg.

fgets() doesn't strip \n from the input.

Try:
strtok(NULL, ", \n")

Note: there is a space character in there, it's not very obvious when posted on LQ.

You might want to change that on all strtoks.
Also, though the above will fix it:
-acodec libmp3lame, isn't one arg, it's two.

Last edited by GazL; 08-08-2019 at 02:01 PM.
 
1 members found this post helpful.
Old 08-09-2019, 10:16 AM   #124
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,827

Original Poster
Rep: Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020
I tried what you said, but I'm still having the same problem. The args printed out by the for loop look better as you'll see in my output below, but even if I copy a video into the same folder as my program, ffmpeg still complains with the same error message anyway. But interesingly if I specify my empty text file (testinput) as the input file for ffmpeg, it sees that it isn't a valid video/audio file and complains with the relevant message (as you'll see below). Also, if I put a comma after every single arg in the first in my config file, like "-threads, 0", it complains "thread" isn't a valid option, and therefore misses the "s 0" after the word thread. But just having for example "-threads 0" (and the same for every other option, <-option_name_here> <value_here> then it does include all of the options in the array passed to ffmpeg.

The only code I've changed in my program is what you said above for strtok, so;

Code:
tokenPtr = strtok(configLine, ", \n"); 
tokenPtr = strtok(NULL, ", \n");
and that's it - the rest of my code is the same as I posted above before.

This is my config file (ffcliFront.conf);

Code:
# mp4 video
test, -crf 35.0, -vcodec libx264, -vpre hq, -acodec libfaac, -ar 48000, -ab 128kb, -coder 1, -flags +loop, -cmp +chroma, -partitions +parti4x4+partp8x8+partb8x8, -me_method hex, -subq 6, -me_range 16, -g 250, -keyint_min 25, -sc_threshold 40, -i_qfactor 0.71, -b_strategy 1, -threads 0
# mp3 audio
test1, -acodec, libmp3lame, -ab, 192kb, -ac, 2, -ar, 44100, -vn
# wmv video
test2, -vn,  -acodec, wmav2, -ab, 160kb
test3,
(it doesn't miss any args with the comma after both the option name and it's value under the comments "mp3 audio" and "wmv video")

Here's what happens trying my program with a real video file;

Code:
james@jamespc: ffcliFront> ./ffcliFront test /multimediavol/tvrec/Australian\ Crime\ Stories.mpg /multimediavol/tvrec/test.mp4 
argv[1] = test
Line from config file: test, -crf 35.0, -vcodec libx264, -vpre hq, -acodec libfaac, -ar 48000, -ab 128kb, -coder 1, -flags +loop, -cmp +chroma, -partitions +parti4x4+partp8x8+partb8x8, -me_method hex, -subq 6, -me_range 16, -g 250, -keyint_min 25, -sc_threshold 40, -i_qfactor 0.71, -b_strategy 1, -threads 0

Found string: test
tokenPtr = test
arg: -i 
arg: /multimediavol/tvrec/Australian Crime Stories.mpg
arg: -crf
arg: 35.0
arg: -vcodec
arg: libx264
arg: -vpre
arg: hq
arg: -acodec
arg: libfaac
arg: -ar
arg: 48000
arg: -ab
arg: 128kb
arg: -coder
arg: 1
arg: -flags
arg: +loop
arg: -cmp
arg: +chroma
arg: -partitions
arg: +parti4x4+partp8x8+partb8x8
arg: -me_method
arg: hex
arg: -subq
arg: 6
arg: -me_range
arg: 16
arg: -g
arg: 250
arg: -keyint_min
arg: 25
arg: -sc_threshold
arg: 40
arg: -i_qfactor
arg: 0.71
arg: -b_strategy
arg: 1
arg: -threads
arg: 0
arg: /multimediavol/tvrec/test.mp4
ffmpeg version 4.1.3 Copyright (c) 2000-2019 the FFmpeg developers
  built with clang version 8.0.1 (branches/release_80)
  configuration: --cc=/usr/bin/clang --cxx=/usr/bin/clang++ --ranlib=ranlib --prefix=/usr --enable-shared --libdir=/usr/lib64 --shlibdir=/usr/lib64 --incdir=/usr/include --disable-stripping --enable-avresample --enable-postproc --enable-gpl --enable-version3 --enable-nonfree --enable-ffplay --disable-lto --enable-pthreads --enable-libtheora --enable-libvorbis --disable-encoder=vorbis --enable-libvpx --enable-runtime-cpudetect --enable-libdc1394 --enable-librtmp --enable-libspeex --enable-libfreetype --enable-libgsm --enable-libcelt --enable-libopencv --enable-frei0r --enable-libopenjpeg --enable-libxavs --enable-libmodplug --enable-libass --enable-gnutls --enable-libcdio --enable-libpulse --enable-libv4l2 --enable-openal --enable-opengl --enable-libzmq --enable-libzvbi --enable-libwavpack --enable-libssh --enable-libsoxr --enable-libtwolame --enable-libopus --enable-libilbc --enable-libiec61883 --enable-libgme --enable-libcaca --enable-libbluray --enable-ladspa --enable-libwebp --enable-avisynth --enable-fontconfig --enable-libvidstab --enable-libflite --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-libbs2b --enable-libmp3lame --enable-libfdk-aac-dlopen --enable-libopencore-amrnb-dlopen --enable-libopencore-amrwb-dlopen --enable-libx264-dlopen --enable-libx265-dlopen --enable-libxvid-dlopen --enable-opencl
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
Output #0, mpeg, to '/multimediavol/tvrec/Australian Crime Stories.mpg':
Output file #0 does not contain any stream
(and the bash cursor goes red as well - but then changes back to it's normal color after I hit enter/enter in another command. As the very last line/error message from ffmpeg in the output above is in red)

Here's what happens with my dummy "testinput" file (which is just an empty text file);

Code:
james@jamespc: ffcliFront> ./ffcliFront test testinput /multimediavol/tvrec/test.mp4            argv[1] = test
Line from config file: test, -crf 35.0, -vcodec libx264, -vpre hq, -acodec libfaac, -ar 48000, -ab 128kb, -coder 1, -flags +loop, -cmp +chroma, -partitions +parti4x4+partp8x8+partb8x8, -me_method hex, -subq 6, -me_range 16, -g 250, -keyint_min 25, -sc_threshold 40, -i_qfactor 0.71, -b_strategy 1, -threads 0

Found string: test
tokenPtr = test
arg: -i 
arg: testinput
arg: -crf
arg: 35.0
arg: -vcodec
arg: libx264
arg: -vpre
arg: hq
arg: -acodec
arg: libfaac
arg: -ar
arg: 48000
arg: -ab
arg: 128kb
arg: -coder
arg: 1
arg: -flags
arg: +loop
arg: -cmp
arg: +chroma
arg: -partitions
arg: +parti4x4+partp8x8+partb8x8
arg: -me_method
arg: hex
arg: -subq
arg: 6
arg: -me_range
arg: 16
arg: -g
arg: 250
arg: -keyint_min
arg: 25
arg: -sc_threshold
arg: 40
arg: -i_qfactor
arg: 0.71
arg: -b_strategy
arg: 1
arg: -threads
arg: 0
arg: /multimediavol/tvrec/test.mp4
ffmpeg version 4.1.3 Copyright (c) 2000-2019 the FFmpeg developers
  built with clang version 8.0.1 (branches/release_80)
  configuration: --cc=/usr/bin/clang --cxx=/usr/bin/clang++ --ranlib=ranlib --prefix=/usr --enable-shared --libdir=/usr/lib64 --shlibdir=/usr/lib64 --incdir=/usr/include --disable-stripping --enable-avresample --enable-postproc --enable-gpl --enable-version3 --enable-nonfree --enable-ffplay --disable-lto --enable-pthreads --enable-libtheora --enable-libvorbis --disable-encoder=vorbis --enable-libvpx --enable-runtime-cpudetect --enable-libdc1394 --enable-librtmp --enable-libspeex --enable-libfreetype --enable-libgsm --enable-libcelt --enable-libopencv --enable-frei0r --enable-libopenjpeg --enable-libxavs --enable-libmodplug --enable-libass --enable-gnutls --enable-libcdio --enable-libpulse --enable-libv4l2 --enable-openal --enable-opengl --enable-libzmq --enable-libzvbi --enable-libwavpack --enable-libssh --enable-libsoxr --enable-libtwolame --enable-libopus --enable-libilbc --enable-libiec61883 --enable-libgme --enable-libcaca --enable-libbluray --enable-ladspa --enable-libwebp --enable-avisynth --enable-fontconfig --enable-libvidstab --enable-libflite --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-libbs2b --enable-libmp3lame --enable-libfdk-aac-dlopen --enable-libopencore-amrnb-dlopen --enable-libopencore-amrwb-dlopen --enable-libx264-dlopen --enable-libx265-dlopen --enable-libxvid-dlopen --enable-opencl
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
[NULL @ 0x10afd80] Unable to find a suitable output format for 'testinput'
testinput: Invalid argument
Not sure exactly what's happening here. Thanks again for your help.

EDIT: I also tried removing the spaces in the input file name (with a real video file), but ffmpeg still gives the same error message as above anyway.

Last edited by jsbjsb001; 08-09-2019 at 10:20 AM. Reason: addition
 
Old 08-10-2019, 04:36 AM   #125
GazL
LQ Veteran
 
Registered: May 2008
Posts: 5,789

Rep: Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705
Don't comment out: ffargs[i++] = "/usr/bin/ffmpeg"; it's required.

by doing so, the '-i' becomes the argv[0] of the ffmpeg execv() and gets ignored as an argument by ffmpeg.


I'd also recommend not using ',' as a field separator in your config file as some ffmpeg options do use it. It's not a problem with your existing config lines but it might catch you out in the future.

Using a ':' as terminator for your label (but not the arguments) might be a good idea, as that's a pretty common way of writing config files, so I'll suggest that also.

Finally, some of your ffmpeg options are old syntax. -acodec -vcodec rather than -c:a -c:v. You might want to update them to use the more modern ffmpeg options. I'd recommend searching for examples on ffmpeg.org.

Last edited by GazL; 08-10-2019 at 04:47 AM.
 
1 members found this post helpful.
Old 08-10-2019, 08:09 AM   #126
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,827

Original Poster
Rep: Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020
Well, I've got some good news - it's passing the args to ffmpeg correctly!!! And it works, it f***ing works!!!!

Thanks you so much GazL!!! I couldn't have done without you guys!!

So before I post the updated code and the WORKING output; I'll just try and explain what I done... I uncommented the line you were talking about above GazL, so that was the first "breakthrough moment". Then I changed the delimiter (I think that's the right name for it - the comma that separates the args for ffmpeg with a semi-colon), and I also removed the newline character from the first strtok() call in the readConfigFile() function. I was reading the main() function for 0ad, and remembered seeing the code where it checks if you are trying to run it as root, so I added a check for that too. I figured since geteuid() gets the "effective user ID", that sounded like the way to go (yes, I did read it's very short man page too ). As we don't want it run as root!

Now I was wondering how I would get it to actually check that there is actually some args specified after the format_id string? So in the updated ffcliFront.conf below, you'll notice that the last line just has "test3;", and that's it - meaning no args would be passed to ffmpeg if you run my program as ffcliFront test3 <input file> <output file>

Also, while it might be a little off-topic (I'll take the blame for that in advance mod's ); I've been meaning to ask, when you guys first started out programming; how did ya's get to the point of being able to read code for complex stuff, like say ffmpeg itself, and be able to follow it? Because I've tried, but I just end up getting completely overwhelmed, then lose track of where I'm even up to - if ya's know what I mean.

And one more thing; since I've got it working now, I wouldn't mind seeing how you done it GazL (if you still have that code of course)

Here's what the config file (ffcliFront.conf) looks like now (the args at least for the first arg line do work, and are correct - I checked);

Code:
# mp4 video
test; -crf 35.0; -c:v libx264; -c:a aac; -coder 1; -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8; -me_method hex; -subq 6; -me_range 16; -g 250; -keyint_min 25; -sc_threshold 40; -i_qfactor 0.71; -b_strategy 1; -threads 0
# mp3 audio
test1; -c:a libmp3lame; -ab 192kb; -ac 2; -ar 44100; -vn
# wmv video
test2; -vn;  -c:a wmav2; -ab 160kb
test3;
Here's the updated code;

Code:
// includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/types.h>

char readConfigFile(char *argv[]);
char buildFfCmdline(char *tokenPtr, char *argv[]);
char execFfmpeg(char *ffcmdline[]);

// main function
int main(int argc, char *argv[]) {
    
    // check if user is logged in as root/effective user ID is root, and if so, abort program execution
    if (geteuid() == 0) {
        fprintf(stderr, "Don't run me as root, exiting.\n");
        return 1;
    }
  
    if ( argc < 4 ) {
       fprintf (stderr, "Missing option or filename\nUSAGE: ffcliFront <format_id> <input_file> <output_file>\n");
       return 1;
    }
    
    // check if input file can be read, and if not, abort program execution - no point in continuing execution in that case...
    int access_return = access(argv[2], R_OK);
    if ( access_return == -1) {
        fprintf(stderr, "Input file cannot be read, aborting.\nDoes it exist?\n");
        exit (1);
    }          
    readConfigFile(argv);
   
    return 0;    
}

char readConfigFile(char *argv[]) {

    char configLine[350];
    char *tokenPtr;
    bool foundStr = false;
                  
    // read config file
    FILE *configfile;
      
    if ( (configfile = fopen("ffcliFront.conf", "r")) == NULL )  {
       fprintf(stderr, "Configuration file not found, exiting.\n");
       return 1;        
    }
    
    printf("argv[1] = %s\n", argv[1]);
           
    while( fgets(configLine, 300, configfile ) != NULL) {
          if ( configLine[0] == '#' ) {
             continue;
          }
             printf("Line from config file: %s\n", configLine);                
             tokenPtr = strtok(configLine, "; ");
             int result = strcasecmp(tokenPtr, argv[1]);
             if ( result == 0 )  {
                foundStr = true;
                printf("Found string: %s\ntokenPtr = %s\n", configLine, tokenPtr);
                buildFfCmdline(tokenPtr, argv);                    
             }
               
    }
    if (foundStr == false) {
       fprintf(stderr, "\"%s\" format_id not found in configuration file, exiting.\nCheck ffcliFront.conf for a valid format_id or specify a format_id that exists.\n", argv[1]);
       return 1;
    }     
    fclose(configfile);
    
    return 0;
}
                   
char buildFfCmdline(char *tokenPtr, char *argv[]) {
    
    static char *ffargs[350] = {0};
    size_t i = 0;
                
    ffargs[i++] = "/usr/bin/ffmpeg";
    ffargs[i++] = "-i";
    ffargs[i++] = argv[2];
        
    while( tokenPtr != NULL ) {
          tokenPtr = strtok(NULL, "; \n");               
          if (tokenPtr) {                    
             ffargs[i++] = tokenPtr;                    
          }               
    }    
    ffargs[i++] = argv[3];                   
   // pass char array with ffmpeg args & call execFfmpeg() fuction with args from config file
    execFfmpeg(ffargs);
 
    return 0;
}      

char execFfmpeg(char *ffcmdline[]) {
        
    for ( char **p = ffcmdline ; *p ; p++ ) {
            printf("arg: %s\n", *p);            
    }
    // run fmpeg with args from config file & filename supplied to this program. 
    execv ("/usr/bin/ffmpeg", ffcmdline);
	
    return 0;
}
And here's the WORKING output;

Code:
james@jamespc: ffcliFront> ./ffcliFront test /multimediavol/tvrec/Australian\ Crime\ Stories.mpg /multimediavol/tvrec/test.mp4
argv[1] = test
Line from config file: test; -crf 35.0; -c:v libx264; -c:a aac; -coder 1; -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8; -me_method hex; -subq 6; -me_range 16; -g 250; -keyint_min 25; -sc_threshold 40; -i_qfactor 0.71; -b_strategy 1; -threads 0

Found string: test
tokenPtr = test
arg: /usr/bin/ffmpeg
arg: -i
arg: /multimediavol/tvrec/Australian Crime Stories.mpg
arg: -crf
arg: 35.0
arg: -c:v
arg: libx264
arg: -c:a
arg: aac
arg: -coder
arg: 1
arg: -flags
arg: +loop
arg: -cmp
arg: +chroma
arg: -partitions
arg: +parti4x4+partp8x8+partb8x8
arg: -me_method
arg: hex
arg: -subq
arg: 6
arg: -me_range
arg: 16
arg: -g
arg: 250
arg: -keyint_min
arg: 25
arg: -sc_threshold
arg: 40
arg: -i_qfactor
arg: 0.71
arg: -b_strategy
arg: 1
arg: -threads
arg: 0
arg: /multimediavol/tvrec/test.mp4
ffmpeg version 4.1.4 Copyright (c) 2000-2019 the FFmpeg developers
  built with clang version 8.0.1 (branches/release_80)
  configuration: --cc=/usr/bin/clang --cxx=/usr/bin/clang++ --ranlib=ranlib --prefix=/usr --enable-shared --libdir=/usr/lib64 --shlibdir=/usr/lib64 --incdir=/usr/include --disable-stripping --enable-avresample --enable-postproc --enable-gpl --enable-version3 --enable-nonfree --enable-ffplay --disable-lto --enable-pthreads --enable-libtheora --enable-libvorbis --disable-encoder=vorbis --enable-libvpx --enable-runtime-cpudetect --enable-libdc1394 --enable-librtmp --enable-libspeex --enable-libfreetype --enable-libgsm --enable-libcelt --enable-libopencv --enable-frei0r --enable-libopenjpeg --enable-libxavs --enable-libmodplug --enable-libass --enable-gnutls --enable-libcdio --enable-libpulse --enable-libv4l2 --enable-openal --enable-opengl --enable-libzmq --enable-libzvbi --enable-libwavpack --enable-libssh --enable-libsoxr --enable-libtwolame --enable-libopus --enable-libilbc --enable-libiec61883 --enable-libgme --enable-libcaca --enable-libbluray --enable-ladspa --enable-libwebp --enable-avisynth --enable-fontconfig --enable-libvidstab --enable-libflite --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-libbs2b --enable-libmp3lame --enable-libfdk-aac-dlopen --enable-libopencore-amrnb-dlopen --enable-libopencore-amrwb-dlopen --enable-libx264-dlopen --enable-libx265-dlopen --enable-libxvid-dlopen --enable-opencl
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
[mpeg @ 0x1badd00] start time for stream 0 is not set in estimate_timings_from_pts
Input #0, mpeg, from '/multimediavol/tvrec/Australian Crime Stories.mpg':
  Duration: 00:46:10.66, start: 0.242378, bitrate: 2042 kb/s
    Stream #0:0[0x1bf]: Data: dvd_nav_packet
    Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:2[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 256 kb/s
File '/multimediavol/tvrec/test.mp4' already exists. Overwrite ? [y/N] y
Stream mapping:
  Stream #0:1 -> #0:0 (mpeg2video (native) -> h264 (libx264))
  Stream #0:2 -> #0:1 (mp2 (native) -> aac (native))
Press [q] to stop, [?] for help
dlsym x264_picture_init
dlsym x264_encoder_encode
dlsym x264_encoder_delayed_frames
dlsym x264_encoder_reconfig
dlsym x264_encoder_close
dlsym x264_param_default
dlsym x264_param_apply_fastfirstpass
dlsym x264_param_parse
dlsym x264_param_default_preset
dlsym x264_param_apply_profile
dlsym x264_param_apply_fastfirstpass
dlsym x264_encoder_headers
[libx264 @ 0x1bcfc40] using SAR=64/45
[libx264 @ 0x1bcfc40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264 @ 0x1bcfc40] profile High, level 3.0
[libx264 @ 0x1bcfc40] 264 - core 155 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x111 me=hex subme=6 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=35.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.41 aq=1:1.00
Output #0, mp4, to '/multimediavol/tvrec/test.mp4':
  Metadata:
    encoder         : Lavf58.20.100
    Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p(top coded first (swapped)), 720x576 [SAR 64:45 DAR 16:9], q=-1--1, 25 fps, 12800 tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.35.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
    Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc58.35.100 aac
frame=   83 fps=0.0 q=40.0 size=       0kB time=00:00:02.33 bitrate=   0.2kbits/s speed=4.62x   frame=  194 fps=193 q=40.0 size=       0kB time=00:00:06.87 bitrate=   0.1kbits/s speed=6.84x   frame=  324 fps=214 q=40.0 size=     256kB time=00:00:12.06 bitrate= 173.9kbits/s speed=7.95x   frame=  463 fps=230 q=40.0 size=     256kB time=00:00:17.58 bitrate= 119.3kbits/s speed=8.72x   frame=  601 fps=238 q=40.0 size=     512kB time=00:00:23.08 bitrate= 181.7kbits/s speed=9.14x   frame=  743 fps=246 q=40.0 size=     512kB time=00:00:28.80 bitrate= 145.6kbits/s speed=9.52x   frame=  840 fps=238 q=40.0 size=     768kB time=00:00:32.66 bitrate= 192.6kbits/s speed=9.24x   frame=  920 fps=221 q=-1.0 Lsize=    1126kB time=00:00:36.68 bitrate= 251.5kbits/s speed=8.82x    
video:533kB audio:565kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.582111%
[libx264 @ 0x1bcfc40] frame I:11    Avg QP:29.44  size:  6985
[libx264 @ 0x1bcfc40] frame P:257   Avg QP:33.84  size:  1208
[libx264 @ 0x1bcfc40] frame B:652   Avg QP:38.34  size:   242
[libx264 @ 0x1bcfc40] consecutive B-frames:  2.6%  8.0%  2.0% 87.4%
[libx264 @ 0x1bcfc40] mb I  I16..4: 25.2% 69.3%  5.5%
[libx264 @ 0x1bcfc40] mb P  I16..4:  4.8%  0.0%  0.4%  P16..4: 20.8%  1.8%  0.8%  0.0%  0.0%    skip:71.4%
[libx264 @ 0x1bcfc40] mb B  I16..4:  0.7%  0.0%  0.0%  B16..8:  4.2%  0.4%  0.0%  direct: 1.6%  skip:93.0%  L0:41.0% L1:56.1% BI: 2.9%
[libx264 @ 0x1bcfc40] 8x8 transform intra:26.4% inter:89.6%
[libx264 @ 0x1bcfc40] coded y,uvDC,uvAC intra: 15.7% 15.3% 2.5% inter: 1.6% 1.6% 0.0%
[libx264 @ 0x1bcfc40] i16 v,h,dc,p: 58% 16% 13% 13%
[libx264 @ 0x1bcfc40] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 32% 11% 35%  4%  3%  4%  3%  4%  4%
[libx264 @ 0x1bcfc40] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 28% 13% 30%  5%  6%  7%  4%  5%  2%
[libx264 @ 0x1bcfc40] i8c dc,h,v,p: 86%  5%  8%  1%
[libx264 @ 0x1bcfc40] Weighted P-Frames: Y:14.8% UV:13.6%
[libx264 @ 0x1bcfc40] ref P L0: 59.9% 18.1% 16.7%  5.0%  0.4%
[libx264 @ 0x1bcfc40] ref B L0: 88.0%  9.8%  2.2%
[libx264 @ 0x1bcfc40] ref B L1: 96.2%  3.8%
[libx264 @ 0x1bcfc40] kb/s:118.54
[aac @ 0x1d43fc0] Qavg: 156.598
Exiting normally, received signal 2.
(I pressed CTRL C before it finished converting the file)

Thanks so much again!!!
 
1 members found this post helpful.
Old 08-10-2019, 09:12 AM   #127
GazL
LQ Veteran
 
Registered: May 2008
Posts: 5,789

Rep: Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705
Yes, no problem, I've still got it. I'll upload mine as a diff against an empty directory so you can extract it to an empty directory easily with patch < ffclifront.diff.txt or view it as is.

I wouldn't have normally used a static for the array or configLine, and I would have used getline() instead of fgets(), but I was trying to keep close to the way you were working knowing that you've not got into using heap memory (mallocs and suchlike) yet.

There's not a whole lot of difference between our approaches. The main one being that in mine the functions are both called from main rather than chaining one from the other and I make more use of function returns because of that.

Oh, and I've included my enhanced strtok_q functions that can handle basic quoting in case that interests you for later. It's a first draft so there might be better ways to do it, but it seems to work.

As for reading other people's code, it depends on who's written it. There's stuff out there that I simply can't fathom, but it comes with practice.

I didn't worry about the empty config line case on mine as ffmpeg -i infile outfile is actually a valid command, but you could just check the number of args after you've assembled the array if you want to stop that from happening.

Anyway, congrats on your progress, and enjoy.

edit: and just to be a good example, I'll cop to missing something and admit that I should have included this just in case someone plays silly buggers.
Code:
diff --git a/ffclifront.c b/ffclifront.c
index 419c8f6..e4331a9 100644
--- a/ffclifront.c
+++ b/ffclifront.c
@@ -21,7 +21,7 @@ char *getConfigLine( char *type )
         return NULL;
 
     size_t typeLength = strlen(type);
-    if ( typeLength == 0 )
+    if ( typeLength == 0 || typeLength >= CONFIG_LINE_MAX )
         return NULL;
         
     FILE *configFile = fopen(CONFIG_FILE_PATH, "r");
strncasecmp will stop at the end of the shorter string anyway, but it doesn't hurt to do an explicit check.

Last edited by GazL; 10-14-2019 at 10:18 AM.
 
1 members found this post helpful.
Old 08-10-2019, 11:03 AM   #128
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,149

Rep: Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523
Maybe something like this would do:
Code:
static struct {
    char *args[350];
    size_t nargs;
} ffargs = {
    { NULL },
    0
};

static void ffarg_add (const char *nextarg)
{
   ffargs.args[ffargs.nargs] = strdup (nextarg); /* check for NULL */
   ++ffargs.nargs;
}

static void ffarg_init (const char *progname)
{
    ffargs.nargs= 0;
    ffarg_add (progname);
}
 
2 members found this post helpful.
Old 08-10-2019, 11:21 AM   #129
GazL
LQ Veteran
 
Registered: May 2008
Posts: 5,789

Rep: Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705Reputation: 3705
I avoided strdup() and getline() specifically because jsb has been avoiding anything involving dynamic allocation so far, but certainly a nicer way to do it.
 
Old 08-10-2019, 10:35 PM   #130
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,827

Original Poster
Rep: Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020
Thanks NevemTeve, but I couldn't figure out how to incorporate your code into even just the little program I wrote to figure out how to use strtok(), etc (without using any command-line args, etc). I'm not sure I even understand exactly what your code is doing beyond the obvious. Everything I tried just ended in a stack of errors. But thanks again for your help tho.

Quote:
Originally Posted by GazL View Post
I avoided strdup() and getline() specifically because jsb has been avoiding anything involving dynamic allocation so far, but certainly a nicer way to do it.
I do want to learn how to do "dynamic memory allocation" - so I'll try and "dynamically allocate" the ffargs array in my program above (and have a look at the strdup() and getline() functions).

I had a look at your code attached above, but while it wasn't too bad trying to understand it; I think some of it is probably beyond my skill level at this point. But thanks again for all of your help though GazL!
 
1 members found this post helpful.
Old 08-11-2019, 05:41 AM   #131
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,827

Original Poster
Rep: Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020
So I was playing with calloc(), and while I was able to dynamically allocate memory; I cannot figure out how to get it to check if the array size needs to be reallocated with realloc(). Basically, if I set the array size to 10, then depending on whether I use the greater than or less than operator, it either doesn't change the size from the original size or it changes the size even if the contents of the input file doesn't change/it's still uploading the same thing into the array. But if I set the array size to 1, calloc() goes crazy and I see what looks like an infinite loop. I wrote a separate program just to try and figure out calloc before I modify ffcliFront. I really don't understand what's going on here.

Here's my test code;

Code:
#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 1 

int main(void) {

    size_t arraySize = ARRAY_SIZE;
    char *array = NULL;

    array = calloc(arraySize, sizeof(int));
    printf("arraySize = %ld\n", arraySize);

    FILE *arrayfile;

    if ( (arrayfile = fopen("calloc_test.txt", "r")) == NULL ) {
       fprintf(stderr, "File doesn't exist\n");
       exit (1);
    }

    while( fgets(array, arraySize, arrayfile ) !=NULL) {
          if ( array[0] == '#' ) {
             continue;
          }
          printf("Line from file: %s\n", array);
     }
     
     if ( sizeof(array)/sizeof(int) < arraySize ) {
        arraySize += 10;
        array = realloc(array, sizeof(int) * ARRAY_SIZE);
     }
     printf("arraySize = %ld\n", arraySize);
     fclose(arrayfile); 
     free(array);
    
     return 0;
}
Here's the output;

Code:
...
Line from file: 
Line from file: 
Line from file: 
Line from file: 
Line from file: 
Line from file: 
Line from file: 
Line from file: 
Line from file: 
Line from file: 
Line from file: 
^C
(I had to CTRL C out of it)
 
Old 08-11-2019, 08:29 AM   #132
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,257
Blog Entries: 13

Rep: Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350
Have you used gdb to debug that code?

Have you verified you're using all library functions correctly and are properly qualifying return values?
 
Old 08-11-2019, 09:00 AM   #133
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,827

Original Poster
Rep: Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020
Quote:
Originally Posted by rtmistler View Post
Have you used gdb to debug that code?
Yes, but other than it's reporting nothing in the array, and what I've already said; I'm no closer to knowing what's going on. And yes RT, I did read the man page, I even looked at the example jpollard gave me from my other thread in this particular forum, and I cannot see where I'm going wrong. The only other thing I've discovered is that it's happening as soon as it gets to the while loop (which I suspected before anyway) - as I commented out the if statement that run realloc(), and it still goes crazy on me.

Quote:
Have you verified you're using all library functions correctly and are properly qualifying return values?
Honestly RT, I don't know nor have a clue if I am or not at this point. I haven't used the dynamic memory allocation functions much before this attempt - I even went back and read what Hazel said earlier on in this thread about "dynamic memory allocation".

So any insight you can give me will be appreciated. Thanks in advance if you would be so kind.
 
Old 08-11-2019, 11:10 AM   #134
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,257
Blog Entries: 13

Rep: Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350Reputation: 4350
The error is not with calloc().

Examine where you see a problem when you run your program.
 
Old 08-11-2019, 12:01 PM   #135
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,827

Original Poster
Rep: Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020Reputation: 2020
Thank you RT. Your comment caused me to look elsewhere in my code, and I noticed the array size was 1, so I changed that, and it stopped the infinite loop. So I assume that was upsetting fgets() ? In any case, I was trying to resize the array with realloc(), so I could try and figure out how to do dynamic memory allocation in ffcliFront above, before making any changes to ffcliFront before I'd figured it out.

Anyways, I've adjusted, and added to my code, and realloc() just increases the size of the array anyway. Even if I have less that 10 elements in the file the code looks at. So how do I get it to only change the array size IF, and ONLY IF there is more than 10 elements (whatever is specified in the arraySize variable) ? As this isn't making sense to me, and nothing I seem to do seems to work.

This is the code I've got now;

Code:
#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 10 

int main(void) {

    size_t arraySize = ARRAY_SIZE;
    char *array = NULL;

    array = calloc(arraySize, sizeof(int));
    printf("arraySize = %ld\n", arraySize);

    FILE *arrayfile;

    if ( (arrayfile = fopen("calloc_test.txt", "r")) == NULL ) {
       fprintf(stderr, "File doesn't exist\n");
       exit (1);
    }

    while( fgets(array, arraySize, arrayfile ) !=NULL) {
          if ( array[0] == '#' ) {
             continue;
          }
          printf("Line from file: %s\n", array);
          break;
    }
     
    if ( sizeof(array)/sizeof(int) < arraySize ) {
       arraySize += 10;
       array = realloc(array, sizeof(int) * ARRAY_SIZE);
    }
    printf("arraySize = %ld\n", arraySize);
     
    rewind(arrayfile);
     
    while( fgets(array, arraySize, arrayfile ) !=NULL) {
          if ( array[0] == '#' ) {
             continue;
          }
          printf("Line from file: %s\n", array);
          break;
    }
    printf("arraySize = %ld\n", arraySize);
    printf("array content: %s\n", array);
    fclose(arrayfile); 
    free(array);
    
    return 0;
}
Here's the content of calloc_test.txt;

Code:
k j
That's it, that is only 3 elements.

But if I run the code;

Code:
james@jamespc: devel> ./calloc_array 
arraySize = 10
Line from file: k j

arraySize = 20
Line from file: k j

arraySize = 20
array content: k j
As you can see, it still increases the array size anyway. What am I doing wrong, I don't get it.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] virtualbox installs pcbsd again and again and again straffetoebak Linux - Virtualization and Cloud 4 11-21-2014 07:14 PM
LXer: Do you want a seriousóI mean seriousódeveloper laptop? Then Dell and Ubuntu have the system fo LXer Syndicated Linux News 0 11-29-2012 03:30 PM
Firefox...I have tried and tried... Basslord1124 Fedora 4 10-29-2004 11:51 PM
my ps/2's wheel doesn't work. tried and tried but failed. Choey Linux - Hardware 5 09-17-2003 06:47 PM
I have tried and tried, I really have! Ewen Linux - General 13 01-14-2003 11:31 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:53 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration