[xiph-cvs] cvs commit: vorbis-tools/ogginfo Makefile.am ogginfo.1 ogginfo.c
Stan Seibert
volsung at xiph.org
Sat Sep 8 20:12:13 PDT 2001
volsung 01/09/08 20:12:12
Modified: ogginfo Makefile.am ogginfo.1 ogginfo.c
Log:
Many ogginfo updates:
- chained bitstreams now handled properly
- ogginfo no longer uses libvorbisfile (not really necessary)
- vendor tag and sample now displayed
- total_playtime attribute gives total length of all bitstreams in a file
- whitespace and "---" added to improve readability
- man page updated, examples removed since they are not really useful and
a pain to keep up to date
Revision Changes Path
1.4 +1 -1 vorbis-tools/ogginfo/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogginfo/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Makefile.am 2001/08/04 22:23:22 1.3
+++ Makefile.am 2001/09/09 03:12:12 1.4
@@ -8,7 +8,7 @@
INCLUDES = @OGG_CFLAGS@ @VORBIS_CFLAGS@
-ogginfo_LDADD = @VORBISFILE_LIBS@ @VORBIS_LIBS@ @OGG_LIBS@
+ogginfo_LDADD = @VORBIS_LIBS@ @OGG_LIBS@
ogginfo_SOURCES = ogginfo.c
1.4 +23 -128 vorbis-tools/ogginfo/ogginfo.1
Index: ogginfo.1
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogginfo/ogginfo.1,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ogginfo.1 2001/07/31 00:19:54 1.3
+++ ogginfo.1 2001/09/09 03:12:12 1.4
@@ -20,160 +20,55 @@
.B filename
of the stream.
.B ogginfo
-cannot accept URLs.
+cannot accept URLs.
+
+In addition to the comments,
.B ogginfo
-will also print the following file attributes:
+will also print the following attributes for each logical bitstream within the file:
.RS
+.IP serial
+The serial number of the logical bitstream.
.IP header_integrity
"pass" if the header is intact, and "fail" if it is corrupted.
.IP stream_integrity
"pass" if the stream contains no bad packets or holes (not counting the last
packet), and "fail" otherwise.
-.IP file_truncated
+.IP stream_truncated
"true" if the last good packet in the stream is not marked as the last packet
and "false" if the stream is complete.
+.IP vendor
+The vendor string of the encoder used to make this stream.
.IP bitrate_upper
-The upper bitrate limit of the file, or "none" if not set.
+The upper bitrate limit of the stream, or "none" if not set.
.IP bitrate_nominal
-The "target" bitrate of the file, or "none" if not set.
+The "target" bitrate of the stream, or "none" if not set.
.IP bitrate_lower
-The lower bitrate limit of the file, or "none" if not set.
+The lower bitrate limit of the stream, or "none" if not set.
.IP bitrate_average
-The average bitrate of the file.
+The average bitrate of the stream.
.IP length
Length of of the file in seconds.
.IP playtime
Playing time in a humanly-readable MM:SS format.
.RE
-
-.SH OPTIONS
-None.
-
-.SH EXAMPLES
-The
+At the end of each file,
.B ogginfo
-command line accepts as many filenames as your shell will allow.
-
-.PP
-Information about one file:
+will also print:
.RS
-.B ogginfo track14.ogg
+.IP total_playtime
+The total playing time for the entire file in seconds.
.RE
-
-
-Will print:
-
-.RS
-.br
-.B
-filename=track14.ogg
-.br
-.B
-header_integrity=pass
-.br
-.B
-stream_integrity=pass
-.br
-.B
-file_truncated=false
-.br
-.B
-title=If I Had $1000000
-.br
-.B
-artist=Barenaked Ladies
-.br
-.B
-album=Gordon
-.br
-.B
-tracknumber=14
-.br
-.B
-length=267.040000
-.br
-.B
-playtime=4:27
-.RE
-
-.PP
-Information on multiple files:
-.RS
-.B ogginfo track1.ogg track2.ogg
-.RE
-
-.PP
-Will print:
-
-.RS
-.br
-.B
-filename=track1.ogg
-.br
-.B
-header_integrity=pass
-.br
-.B
-stream_integrity=pass
-.br
-.B
-file_truncated=false
-.br
-.B
-title=The Vorbis Theme
-.br
-.B
-artist=Monty and The Wet Trouts
-.br
-.B
-album=Musical Penguins 3
-.br
-.B
-tracknumber=1
-.br
-.B
-length=67.38383
-.br
-.B
-playtime=1:07
-.br
-.B
-filename=track2.ogg
-.br
-.B
-header_integrity=pass
-.br
-.B
-stream_integrity=pass
-.br
-.B
-file_truncated=false
-.br
-.B
-title=Being for the Benefit of Mr. Fish
-.br
-.B
-artist=Monty and The Wet Trouts
-.br
-.B
-album=Musical Penguins 3
-.br
-.B
-tracknumber=2
-.br
-.B
-length=449.0000
-.br
-.B
-playtime=7:29
-.RE
+.SH OPTIONS
+None.
.SH BUGS
-.B ogginfo
-only checks the first bitstream in a file.
+Although
+.B ogginfo
+properly handles chained bitstreams, it cannot handle multiplexed
+logical bitstreams
.SH AUTHORS
1.6 +154 -152 vorbis-tools/ogginfo/ogginfo.c
Index: ogginfo.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogginfo/ogginfo.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ogginfo.c 2001/07/31 00:19:54 1.5
+++ ogginfo.c 2001/09/09 03:12:12 1.6
@@ -14,18 +14,12 @@
#include <string.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
-#include <vorbis/vorbisfile.h>
-void doinfo(char *);
-int dointegritycheck(char *);
-int test_header(FILE *fp, ogg_sync_state *oy, ogg_stream_state *os,
- vorbis_info *vi, vorbis_comment *vc);
-int test_stream(FILE *fp, ogg_sync_state *oy, ogg_stream_state *os);
+int dointegritycheck(char *filename);
int main(int ac,char **av)
{
int i;
- int header_state;
if ( ac < 2 ) {
fprintf(stderr,"Usage: %s [filename1.ogg] ... [filenameN.ogg]\n",av[0]);
@@ -34,161 +28,65 @@
for(i=1;i!=ac;i++) {
printf("filename=%s\n",av[i]);
- header_state = dointegritycheck(av[i]);
- if (header_state == 1)
- doinfo(av[i]);
+ dointegritycheck(av[i]);
+ if (i < ac - 1)
+ printf("\n---\n\n");
}
- return(0);
-
+
+ return(0);
}
-void doinfo(char *filename)
-{
- FILE *fp;
- OggVorbis_File vf;
- int rc,i;
- vorbis_comment *vc;
- vorbis_info *vi;
- double playtime;
- long playmin,playsec;
- memset(&vf,0,sizeof(OggVorbis_File));
-
- fp = fopen(filename,"rb");
- if (!fp) {
- fprintf(stderr,"Unable to open \"%s\": %s\n",
- filename,
- strerror(errno));
- }
+void calc_playtime(double playtime, long *playmin, long *playsec)
+{
+ *playmin = (long)playtime / (long)60;
+ *playsec = (long)playtime - (*playmin*60);
+}
- rc = ov_open(fp,&vf,NULL,0);
- if (rc < 0) {
- fprintf(stderr,"Unable to understand \"%s\", errorcode=%d\n",
- filename,rc);
- return;
- }
-
- vc = ov_comment(&vf,-1);
+void print_header_info(vorbis_comment *vc, vorbis_info *vi)
+{
+ int rc,i;
for (i=0; i < vc->comments; i++) {
printf("%s\n",vc->user_comments[i]);
}
- vi = ov_info(&vf,-1);
- if (vi)
- {
- printf("version=%d\n"
- "channels=%d\n",
- vi->version, vi->channels);
-
- printf("bitrate_upper=");
- if (vi->bitrate_upper == -1)
- printf("none\n");
- else
- printf("%d\n", vi->bitrate_upper);
-
- printf("bitrate_nominal=");
- if (vi->bitrate_nominal == -1)
- printf("none\n");
- else
- printf("%d\n", vi->bitrate_nominal);
-
- printf("bitrate_lower=");
- if (vi->bitrate_lower == -1)
- printf("none\n");
- else
- printf("%d\n", vi->bitrate_lower);
-
- printf("bitrate_average=%ld\n", ov_bitrate(&vf,-1));
- }
+ printf("vendor=%s\n", vc->vendor);
- playtime = ov_time_total(&vf,-1);
-
- playmin = (long)playtime / (long)60;
- playsec = (long)playtime - (playmin*60);
- printf("length=%f\n",playtime);
- printf("playtime=%ld:%02ld\n",playmin,playsec);
-
- ov_clear(&vf);
-
- return;
+ printf("version=%d\n"
+ "channels=%d\n"
+ "rate=%ld\n",
+ vi->version, vi->channels, vi->rate);
+
+ printf("bitrate_upper=");
+ if (vi->bitrate_upper < 0)
+ printf("none\n");
+ else
+ printf("%ld\n", vi->bitrate_upper);
+
+ printf("bitrate_nominal=");
+ if (vi->bitrate_nominal < 0)
+ printf("none\n");
+ else
+ printf("%ld\n", vi->bitrate_nominal);
+
+ printf("bitrate_lower=");
+ if (vi->bitrate_lower < 0)
+ printf("none\n");
+ else
+ printf("%ld\n", vi->bitrate_lower);
}
-/* Tests the integrity of a vorbis stream. Returns 1 if the header is good
- (but not necessarily the rest of the stream) and 0 otherwise.
-
- Huge chunks of this function are from decoder_example.c (Copyright
- 1994-2001 Xiphophorus Company). */
-int dointegritycheck(char *filename)
-{
- int header_state = -1; /* Assume the worst */
- int stream_state = -1;
-
- ogg_sync_state oy; /* sync and verify incoming physical bitstream */
- ogg_stream_state os; /* take physical pages, weld into a logical
- stream of packets */
- vorbis_info vi; /* struct that stores all the static vorbis bitstream
- settings */
- vorbis_comment vc; /* struct that stores all the bitstream user comments */
-
- FILE *fp;
-
- /********** Decode setup ************/
-
- fp = fopen(filename,"rb");
- if (!fp) {
- fprintf(stderr,"Unable to open \"%s\": %s\n",
- filename,
- strerror(errno));
- return 0;
- }
- ogg_sync_init(&oy); /* Now we can read pages */
-
- if ( (header_state = test_header(fp, &oy, &os, &vi, &vc)) == 1 ) {
-
- stream_state = test_stream(fp, &oy, &os);
- }
-
- /* Output test results */
- if (header_state == 1)
- printf("header_integrity=pass\n");
- else
- printf("header_integrity=fail\n");
-
- if (stream_state >= 0)
- printf("stream_integrity=pass\n");
- else
- printf("stream_integrity=fail\n");
-
- if (stream_state > 0)
- printf("file_truncated=false\n");
- else
- printf("file_truncated=true\n");
-
-
- /* clean up this logical bitstream; before exit we see if we're
- followed by another [chained] */
-
- if (header_state == 0) {
- /* We got far enough to initialize these structures */
-
- ogg_stream_clear(&os);
-
- /* ogg_page and ogg_packet structs always point to storage in
- libvorbis. They're never freed or manipulated directly */
-
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi); /* must be called last */
- }
-
- /* OK, clean up the framer */
- ogg_sync_clear(&oy);
-
- fclose(fp);
+void print_stream_info (double playtime, ogg_int64_t bits)
+{
+ long playmin, playsec;
- return header_state > 0 ? 1 : 0;
+ calc_playtime(playtime, &playmin, &playsec);
+ printf("bitrate_average=%ld\n", (long) (bits/playtime));
+ printf("length=%f\n", playtime);
+ printf("playtime=%ld:%02ld\n", playmin, playsec);
}
/* Test the integrity of the stream header.
@@ -198,7 +96,7 @@
-1 if it is corrupted and os, vi, and vc were not initialized
(don't clear them) */
int test_header (FILE *fp, ogg_sync_state *oy, ogg_stream_state *os,
- vorbis_info *vi, vorbis_comment *vc)
+ vorbis_info *vi, vorbis_comment *vc, long *serialno)
{
ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
ogg_packet op; /* one raw packet of data for decode */
@@ -225,7 +123,8 @@
/* Get the serial number and set up the rest of decode. */
/* serialno first; use it to set up a logical stream */
- ogg_stream_init(os,ogg_page_serialno(&og));
+ *serialno = ogg_page_serialno(&og);
+ ogg_stream_init(os, *serialno);
/* extract the initial header from the first page and verify that the
Ogg bitstream is in fact Vorbis data */
@@ -300,12 +199,14 @@
return 1;
}
+
/* Test the integrity of the vorbis stream after the header.
Return:
>0 if the stream is correct and complete
0 if the stream is correct but truncated
-1 if the stream is corrupted somewhere in the middle */
-int test_stream (FILE *fp, ogg_sync_state *oy, ogg_stream_state *os)
+int test_stream (FILE *fp, ogg_sync_state *oy, ogg_stream_state *os,
+ ogg_int64_t *final_granulepos, ogg_int64_t *bits)
{
int eos = 0;
ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
@@ -340,15 +241,116 @@
}
}
if(!eos){
- buffer=ogg_sync_buffer(oy,4096);
- bytes=fread(buffer,1,4096,fp);
+ buffer = ogg_sync_buffer(oy,4096);
+ bytes = fread(buffer,1,4096,fp);
+ *bits += 8 * bytes;
ogg_sync_wrote(oy,bytes);
- if(bytes==0)eos=1;
+ if(bytes == 0)
+ eos = 1;
}
}
+ *final_granulepos = ogg_page_granulepos(&og);
+
/* Make sure that the last page is marked as the end-of-stream */
return ogg_page_eos(&og);
}
+
+
+/* Tests the integrity of a vorbis stream. Returns 1 if the header is good
+ (but not necessarily the rest of the stream) and 0 otherwise.
+
+ Huge chunks of this function are from decoder_example.c (Copyright
+ 1994-2001 Xiphophorus Company). */
+int dointegritycheck(char *filename)
+{
+ int header_state = -1; /* Assume the worst */
+ int stream_state = -1;
+
+ ogg_sync_state oy; /* sync and verify incoming physical bitstream */
+ ogg_stream_state os; /* take physical pages, weld into a logical
+ stream of packets */
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream
+ settings */
+ vorbis_comment vc; /* struct that stores all the bitstream user comments */
+
+ FILE *fp;
+ int eof = 0;
+ long serialno;
+ ogg_int64_t bits, final_granulepos;
+ double playtime, total_playtime = 0.0;
+ long total_playmin, total_playsec;
+
+ /********** Decode setup ************/
+
+ fp = fopen(filename,"rb");
+ if (!fp) {
+ fprintf(stderr,"Unable to open \"%s\": %s\n",
+ filename,
+ strerror(errno));
+ return 0;
+ }
+
+ ogg_sync_init(&oy); /* Now we can read pages */
+
+ while (!eof) {
+ bits = 0;
+
+ if ( (header_state = test_header(fp, &oy, &os, &vi, &vc,
+ &serialno)) == 1 ) {
+ stream_state = test_stream(fp, &oy, &os, &final_granulepos,
+ &bits);
+ }
+
+ /* Output test results */
+ if (header_state == 1) {
+ printf("\nserial=%d\n", serialno);
+ printf("header_integrity=pass\n");
+ print_header_info(&vc, &vi);
+ } else
+ printf("header_integrity=fail\n");
+
+ if (stream_state >= 0) {
+ playtime = (double) final_granulepos / vi.rate;
+ total_playtime += playtime;
+ printf("stream_integrity=pass\n");
+ print_stream_info(playtime, bits);
+ } else
+ printf("stream_integrity=fail\n");
+
+ if (stream_state > 0)
+ printf("stream_truncated=false\n");
+ else
+ printf("stream_truncated=true\n");
+
+ /* clean up this logical bitstream; before exit we see if we're
+ followed by another [chained] */
+ eof = feof(fp);
+ }
+
+ calc_playtime(total_playtime, &total_playmin, &total_playsec);
+ printf("\ntotal_length=%f\n", total_playtime);
+ printf("total_playtime=%ld:%02ld\n", total_playmin, total_playsec);
+
+ if (header_state >= 0) {
+
+ /* We got far enough to initialize these structures */
+ ogg_stream_clear(&os);
+
+ /* ogg_page and ogg_packet structs always point to storage in
+ libvorbis. They're never freed or manipulated directly */
+
+ vorbis_comment_clear(&vc);
+ vorbis_info_clear(&vi); /* must be called last */
+ }
+
+ /* OK, clean up the framer */
+ ogg_sync_clear(&oy);
+
+ fclose(fp);
+
+ return header_state > 0 ? 1 : 0;
+}
+
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list