[FFmpeg-devel] [PATCH] ffprobe integration

Stefano Sabatini stefano.sabatini-lala
Fri Jan 8 00:54:46 CET 2010


On date Monday 2010-01-04 23:27:34 +0100, Michael Niedermayer encoded:
> On Sun, Jan 03, 2010 at 06:38:28PM +0100, Stefano Sabatini wrote:
> > On date Sunday 2010-01-03 17:49:37 +0100, Stefano Sabatini encoded:
> > > On date Sunday 2010-01-03 01:23:25 +0100, Michael Niedermayer encoded:
> > > > On Sun, Jan 03, 2010 at 12:21:20AM +0100, Stefano Sabatini wrote:
> > > > [...]
> > > > > +#undef exit
> > > > > +#undef printf
> > > > > +#undef fprintf
> > > > 
> > > > no chance
> > > > new applications using libav* must be compileable without this hackery
> > > > this is just a bad example
> > > 
> > > The simplest solution looks to me to do #undef HAVE_AV_CONFIG_H before
> > > to include libav* headers, this way the inclusion of
> > > libavutil/internal.h is inhibited, a better solution would be to
> > > change the Makefiles in order to avoid to bestow the
> > > -DHAVE_AV_CONFIH_H flag when compiling programs / test / example
> > > files, I'd say to await for Mans before to try that (yes this would
> > > allow to remove a bunch of ugly #undefs).
> > > 
> > > > > +
> > > > > +const char program_name[] = "FFprobe";
> > > > > +const int program_birth_year = 2007;
> > > > > +
> > > > > +/* globals */
> > > > > +const OptionDef options[];
> > > > > +
> > > > > +/* FFprobe context */
> > > > > +static const char *input_filename;
> > > > > +static int value_string_flags = 0;
> > > > > +static int do_show_format = 0;
> > > > > +static int do_show_streams = 0;
> > > > > +
> > > > 
> > > > > +const char *binary_unit_prefixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
> > > > > +static const int binary_unit_prefixes_nb = FF_ARRAY_ELEMS(binary_unit_prefixes);
> > > > > +
> > > > > +const char *decimal_unit_prefixes[] = { "", "K", "M", "G", "T", "P" };
> > > > > +static const int decimal_unit_prefixes_nb = FF_ARRAY_ELEMS(decimal_unit_prefixes);
> > > > 
> > > > dont we have this already somewhere?
> > > 
> > > Yes in libavcodec/eval.c, which is private.
> > > 
> > > > [...]
> > > > > +    if (unit == UNIT_SECOND && flags & VALUE_STRING_USE_SEXAGESIMAL_TIME_FORMAT) {
> > > > > +        int hours, mins, secs, usecs;
> > > > > +        /* takes the 6 digits representing the microseconds and round */
> > > > > +        usecs = (int)(round((val - floor(val)) * 1000000));
> > > > > +        secs  = (int)val;
> > > > > +        mins  = secs / 60;
> > > > > +        secs %= 60;
> > > > > +        hours = mins / 60;
> > > > > +        mins %= 60;
> > > > > +
> > > > > +        snprintf(buf, buf_size, "%d:%02d:%02d.%06d", hours, mins, secs, usecs);
> > > > 
> > > > isnt there some formatting with %f possible for sec/usec?
> > > 
> > > From the gnu libc manual:
> > > 
> > > |   The `%f' conversion prints its argument in fixed-point notation,
> > > |producing output of the form [`-']DDD`.'DDD, where the number of digits
> > > |following the decimal point is controlled by the precision you specify.
> > > 
> > > And I couldn't find a way to force printf to pad to 2 digits the
> > > decimal part, also it looks more complicate (I need to compute secs,
> > > and then re-add the microseconds like secs = secs + usecs / 1000000,
> > > maybe there is a simpler way though).
> > > 
> > > > > +        return buf;
> > > > > +    }
> > > > > +
> > > > > +    if (flags & VALUE_STRING_USE_PREFIX) {
> > > > > +        if (flags & VALUE_STRING_USE_BINARY_PREFIX) {
> > > > > +            index = (int) (log2(val)) / 10;
> > > > > +            index = FFMAX(0, index);
> > > > > +            index = FFMIN(index, binary_unit_prefixes_nb -1);
> > > > 
> > > > av_clip()
> > > 
> > > Used.
> > > > 
> > > > 
> > > > > +            val /= pow(2, index*10);
> > > > > +            prefix_str = binary_unit_prefixes[index];
> > > > > +        } else {
> > > > > +            index = (int) (log10(val)) / 3;
> > > > > +            index = FFMAX(0, index);
> > > > > +            index = FFMIN(index, decimal_unit_prefixes_nb -1);
> > > > > +            val /= pow(10, index*3);
> > > > > +            prefix_str = decimal_unit_prefixes[index];
> > > > > +        }
> > > > > +    } else
> > > > > +        prefix_str = "";
> > > > > +
> > > > > +    unit_str = flags & VALUE_STRING_USE_UNIT ? measure_units[unit].str : "";
> > > > > +
> > > > 
> > > > > +    if (flags & VALUE_STRING_USE_PREFIX)
> > > > > +        snprintf(buf, buf_size, "%.3f %s%s", val, prefix_str, unit_str);
> > > > > +    else
> > > > 
> > > > {}
> > > 
> > > Done.
> > > 
> > > > > +        snprintf(buf, buf_size, "%f %s", val, unit_str);
> > > > > +
> > > > > +    return buf;
> > > > > +}
> > > > > +
> > > > > +static char *time_value_string(char *buf, int buf_size, int64_t val,
> > > > > +                               AVRational *time_base, int value_string_flags)
> > > > > +{
> > > > > +    double d;
> > > > > +
> > > > > +    if (val == AV_NOPTS_VALUE) {
> > > > > +        snprintf(buf, buf_size, "N/A");
> > > > > +    } else {
> > > > > +        d = (double) (val * time_base->num) / (double) time_base->den;
> > > > 
> > > > av_q2d()
> > > 
> > > Yes.
> > >  
> > > > [...]
> > > > > +#define P(...) do { printf(__VA_ARGS__); } while(0)
> > > > 
> > > > obfuscated mess
> > > > next comes
> > > > #define I if(
> > > > #define SV static void
> > > > and so on
> > > 
> > > Removed the macro.
> > > 
> > > Also addressed Diego's remarks.
> > 
> > Added AVI codec tag printing (feature stolen by avcodec_string()).
> [...]
> 
> > +typedef enum UnitId {
> > +    UNIT_NONE,
> > +    UNIT_SECOND,
> > +    UNIT_HERTZ,
> > +    UNIT_BYTE_PER_SECOND,
> > +    UNIT_BIT_PER_SECOND,
> > +    UNIT_BIT,
> > +    UNIT_BYTE,
> > +    UNIT_NB,
> > +} UnitId;
> > +
> > +typedef struct Unit {
> > +    const UnitId id;
> > +    const char *str;
> > +} Unit;
> > +
> > +const Unit measure_units[UNIT_NB] = {
> > +    [UNIT_NONE]            = { UNIT_NONE           , ""       },
> > +    [UNIT_SECOND]          = { UNIT_SECOND         , "s"      },
> > +    [UNIT_HERTZ]           = { UNIT_HERTZ          , "Hz"     },
> > +    [UNIT_BIT]             = { UNIT_BIT            , "bit"    },
> > +    [UNIT_BYTE]            = { UNIT_BYTE           , "byte"   },
> > +    [UNIT_BYTE_PER_SECOND] = { UNIT_BYTE_PER_SECOND, "byte/s" },
> > +    [UNIT_BIT_PER_SECOND]  = { UNIT_BIT_PER_SECOND , "bit/s"  }
> > +};
> 
> Instead of this, isnt it simpler to just pass a string like "byte" ?
> 
> 
> 
> > +
> > +/** Print unit of measure. */
> > +#define VALUE_STRING_USE_UNIT                      0x0001
> > +
> > +/** Print using (binary or decimal) prefixes. */
> > +#define VALUE_STRING_USE_PREFIX                    0x0002
> > +/** Use binary type prefixes, implies the use of prefixes */
> > +#define VALUE_STRING_USE_BINARY_PREFIX             0x0004
> > +
> > +/** Force the use of binary prefixes with bytes measure units. */
> > +#define VALUE_STRING_USE_BYTE_BINARY_PREFIX        0x0008
> > +
> > +/* Use sexagesimal time format HH:MM:SS.MICROSECONDS. */
> > +#define VALUE_STRING_USE_SEXAGESIMAL_TIME_FORMAT   0x0010
> > +
> 
> > +static char *value_string(char *buf, int buf_size, double val,
> > +                          UnitId unit, int flags)
> > +{
> > +    int index;
> > +    const char *prefix_str;
> > +    const char *unit_str;
> > +
> > +    if (unit == UNIT_BYTE && flags & VALUE_STRING_USE_BYTE_BINARY_PREFIX)
> > +        flags |= VALUE_STRING_USE_BINARY_PREFIX;
> > +
> > +    if (unit == UNIT_SECOND && flags & VALUE_STRING_USE_SEXAGESIMAL_TIME_FORMAT) {
> > +        int hours, mins, secs, usecs;
> > +        /* takes the 6 digits representing the microseconds and round */
> > +        usecs = (int)(round((val - floor(val)) * 1000000));
> > +        secs  = (int)val;
> > +        mins  = secs / 60;
> > +        secs %= 60;
> > +        hours = mins / 60;
> > +        mins %= 60;
> > +
> > +        snprintf(buf, buf_size, "%d:%02d:%02d.%06d", hours, mins, secs, usecs);
> 
> how does %09.6f look?

duration=238.158000

But I believe the point of the function is to use sexagesimal format.

> also we have dump_format(), please dont duplicate it

I'm aware of dump_format(), its non-easily parsable format is one of
the reasons of existence of ffprobe.

The other idea is to make dump_format() use this function, making it
public.

Regards.
-- 
FFmpeg = Faboulous and Funny Magnificient Puritan Entertaining Guide



More information about the ffmpeg-devel mailing list