[xiph-cvs] cvs commit: theora/win32/experimental/dumpvid dumpvid.dsp

Mauricio Piacentini mauricio at xiph.org
Mon Jun 2 12:07:09 PDT 2003



mauricio    03/06/02 15:07:09

  Modified:    examples Makefile.am
               include/theora theora.h
  Added:       examples dump_video.c
               win32/experimental/dumpvid dumpvid.dsp
  Log:
  added missing theora_decode_tables to theora.h
  added dump_video example (dumps YUV decoded theora bitstreams, useful to compare output in different platforms)

Revision  Changes    Path
1.7       +7 -4      theora/examples/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/theora/examples/Makefile.am,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Makefile.am	25 Sep 2002 04:33:47 -0000	1.6
+++ Makefile.am	2 Jun 2003 19:07:08 -0000	1.7
@@ -10,13 +10,16 @@
 player_example = 
 endif
 
-noinst_PROGRAMS = encoder_example $(player_example)
+noinst_PROGRAMS = encoder_example dump_video $(player_example)
 
 LDFLAGS = -all-static 
-LDADD = ../lib/libtheora.la -logg -lvorbis -lm
+LDADD = ../lib/libtheora.la -logg -lm
+
+dump_video_SOURCES = dump_video.c
+dump_video_LDADD = $(LDADD)
 
 player_example_SOURCES = player_example.c
-player_example_LDADD = $(LDADD) $(SDL_LIBS) -lpthread
+player_example_LDADD = $(LDADD) $(SDL_LIBS)  -lvorbis -lpthread
 
 encoder_example_SOURCES = encoder_example.c
 encoder_example_LDADD = $(LDADD) -lvorbisenc
@@ -27,4 +30,4 @@
 profile:
         $(MAKE) all CFLAGS="@PROFILE@"
 
-EXTRA_DIST = $(player_example_SOURCES)
+EXTRA_DIST = $(encoder_example_SOURCES)

<p><p>1.1                  theora/examples/dump_video.c

Index: dump_video.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: example dumpvid application; dumps  Theora streams 
  last mod: $Id: dump_video.c,v 1.1 2003/06/02 19:07:08 mauricio Exp $

 ********************************************************************/

/* By Mauricio Piacentini (mauricio at xiph.org) */
/*  simply dump decoded YUV data, for verification of theora bitstream */

#define _GNU_SOURCE
#define _REENTRANT
#define _LARGEFILE_SOURCE 
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*#include <sys/time.h>*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
#include <signal.h>
#include "theora/theora.h"

<p><p>/* Helper; just grab some more compressed bitstream and sync it for
   page extraction */
int buffer_data(FILE *in,ogg_sync_state *oy){
  char *buffer=ogg_sync_buffer(oy,4096);
  int bytes=fread(buffer,1,4096,in);
  ogg_sync_wrote(oy,bytes);
  return(bytes);
}

/* never forget that globals are a one-way ticket to Hell */
/* Ogg and codec state for demux/decode */
ogg_sync_state   oy; 
ogg_page         og;
ogg_stream_state vo;
ogg_stream_state to;
theora_info      ti;
theora_comment   tc;
theora_state     td;

int              theora_p=0;
//int              vorbis_p=0;
int              stateflag=0;

/* single frame video buffering */
int          videobuf_ready=0;
ogg_int64_t  videobuf_granulepos=-1;
double       videobuf_time=0;

FILE* outfile = NULL;

int got_sigint=0;
static void sigint_handler (int signal) {
  got_sigint = 1;
}

tatic void open_video(void){

}

tatic void video_write(void){
  int i;
                
  yuv_buffer yuv;
  theora_decode_YUVout(&td,&yuv);

  for(i=0;i<yuv.y_height;i++)
    fwrite(yuv.y+yuv.y_stride*i, 1, yuv.y_width, outfile);
 for(i=0;i<yuv.uv_height;i++){
        fwrite(yuv.v+yuv.uv_stride*i, 1, yuv.uv_width, outfile);
        fwrite(yuv.u+yuv.uv_stride*i, 1, yuv.uv_width, outfile);
        }
  
}
/* dump the theora (or vorbis) comment header */
static int dump_comments(theora_comment *tc){
  int i, len;
  char *value;
  FILE *out=stdout;
  
  fprintf(out,"Encoded by %s\n",tc->vendor);
  if(tc->comments){
    fprintf(out, "theora comment header:\n");
    for(i=0;i<tc->comments;i++){
      if(tc->user_comments[i]){
        len=tc->comment_lengths[i];
              value=malloc(len+1);
              memcpy(value,tc->user_comments[i],len);
              value[len]='\0';
              fprintf(out, "\t%s\n", value);
              free(value);
      }
    }
  }
  return(0);
}

/* helper: push a page into the appropriate steam */
/* this can be done blindly; a stream won't accept a page
                that doesn't belong to it */
static int queue_page(ogg_page *page){
  if(theora_p)ogg_stream_pagein(&to,&og);
  return 0;
}                                   

tatic void usage(void){
  fprintf(stderr,
          "Usage: dumpvid <file.ogg> > outfile\n"
          "input is read from stdin if no file is passed on the command line\n"
          "\n"
  );
}

int main(int argc,char *argv[]){
  
  int i,j;
  ogg_packet op;
  
  FILE *infile = stdin;
  outfile = stdout;

#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
  /* Beware the evil ifdef. We avoid these where we can, but this one we 
     cannot. Don't add any more, you'll probably go to hell if you do. */
  _setmode( _fileno( stdin ), _O_BINARY );
  _setmode( _fileno( stdout ), _O_BINARY );
#endif

  /* open the input file if any */
  if(argc==2){
    infile=fopen(argv[1],"rb");
    if(infile==NULL){
      fprintf(stderr,"Unable to open '%s' for extraction.\n", argv[1]);
      exit(1);
    }
  }
  if(argc>2){
      usage();
      exit(1);
  }
  
  /* start up Ogg stream synchronization layer */
  ogg_sync_init(&oy);

  /* init supporting Vorbis structures needed in header parsing */
//  vorbis_info_init(&vi);
//  vorbis_comment_init(&vc);
  theora_comment_init(&tc);

  /* Ogg file open; parse the headers */
  /* Only interested in Vorbis/Theora streams */
  while(!stateflag){
    int ret=buffer_data(infile,&oy);
    if(ret==0)break;
    while(ogg_sync_pageout(&oy,&og)>0){
      ogg_stream_state test;
      
      /* is this a mandated initial header? If not, stop parsing */
      if(!ogg_page_bos(&og)){
        /* don't leak the page; get it into the appropriate stream */
        queue_page(&og);
        stateflag=1;
        break;
      }
      
      ogg_stream_init(&test,ogg_page_serialno(&og));
      ogg_stream_pagein(&test,&og);
      ogg_stream_packetout(&test,&op);
      
      /* identify the codec: try theora */
      if(!theora_p && theora_decode_header(&ti,&op)>=0){
        /* it is theora */
        memcpy(&to,&test,sizeof(test));
        theora_p=1;
      }else{
        /* whatever it is, we don't care about it */
        ogg_stream_clear(&test);
      }
    }
    /* fall through to non-bos page parsing */
  }
  
  /* we're expecting more header packets. */
  while(theora_p && theora_p<3){
    int ret;
    
    /* look for further theora headers */
    while(theora_p && (theora_p<3) && (ret=ogg_stream_packetout(&to,&op))){
      if(ret<0){
              fprintf(stderr,"Error parsing Theora stream headers; corrupt stream?\n");
              exit(1);
      }
      if(theora_p==1){
        if(theora_decode_comment(&tc,&op)){
          fprintf(stderr,"Error parsing Theora stream headers; corrupt stream?\n");
          exit(1);
        }else{
                  /*not interested in comments now*/
          /*dump_comments(&tc);*/
          theora_p++;
          continue;
        }
      }
      if(theora_p==2){
        if(theora_decode_tables(&ti,&op)){
          fprintf(stderr,"Error parsing Theora stream headers; corrupt stream?\n");
          exit(1);
        }
        theora_p++;
        /* fall through */
      }
      if(theora_p==3)break;
    }

    
    /* The header pages/packets will arrive before anything else we
       care about, or the stream is not obeying spec */
    
    if(ogg_sync_pageout(&oy,&og)>0){
      queue_page(&og); /* demux into the appropriate stream */
    }else{
      int ret=buffer_data(infile,&oy); /* someone needs more data */
      if(ret==0){
        fprintf(stderr,"End of file while searching for codec headers.\n");
        exit(1);
      }
    }
  }

  /* and now we have it all.  initialize decoders */
  if(theora_p){
    theora_decode_init(&td,&ti);
    fprintf(stderr,"Ogg logical stream %x is Theora %dx%d %.02f fps video.\n",
            to.serialno,ti.width,ti.height,
            (double)ti.fps_numerator/ti.fps_denominator);
  }
  

  /* open video */
  if(theora_p)open_video();

  /* install signal handler */
  signal (SIGINT, sigint_handler);

  /* on to the main decode loop.*/

  stateflag=0; /* playback has not begun */
  while(!got_sigint){
      
    while(theora_p && !videobuf_ready){
      /* theora is one in, one out... */
      if(ogg_stream_packetout(&to,&op)>0){
   
        theora_decode_packetin(&td,&op);
        videobuf_granulepos=td.granulepos;
        videobuf_time=theora_granule_time(&td,videobuf_granulepos);
        videobuf_ready=1;
                
      }else
        break;
    }
    
    if(!videobuf_ready  && feof(infile))break;
    
    if(!videobuf_ready ){
      /* no data yet for somebody.  Grab another page */
      int ret=buffer_data(infile,&oy);
      while(ogg_sync_pageout(&oy,&og)>0){
              queue_page(&og);
      }
    }

    /* dumpvideo frame, and get new one */
      video_write();
      videobuf_ready=0;
  }

  /* close everything */

  if(theora_p){
    ogg_stream_clear(&to);
    theora_clear(&td);
  }
  ogg_sync_clear(&oy);

  if(infile && infile!=stdin)fclose(infile);
  
  fprintf(stderr,
          "\r                                                              "
          "\nDone.\n");
  return(0);

}

<p><p>1.6       +2 -1      theora/include/theora/theora.h

Index: theora.h
===================================================================
RCS file: /usr/local/cvsroot/theora/include/theora/theora.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- theora.h	12 May 2003 00:20:05 -0000	1.5
+++ theora.h	2 Jun 2003 19:07:08 -0000	1.6
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: theora.h,v 1.5 2003/05/12 00:20:05 giles Exp $
+  last mod: $Id: theora.h,v 1.6 2003/06/02 19:07:08 mauricio Exp $
 
  ********************************************************************/
 
@@ -100,6 +100,7 @@
 extern int theora_encode_comment(theora_comment *tc, ogg_packet *op);
 extern int theora_decode_header(theora_info *c, ogg_packet *op);
 extern int theora_decode_comment(theora_comment *tc, ogg_packet *op); 
+extern int theora_decode_tables(theora_info *c, ogg_packet *op);
 extern int theora_decode_init(theora_state *th, theora_info *c);
 extern int theora_decode_packetin(theora_state *th,ogg_packet *op);
 extern int theora_decode_YUVout(theora_state *th,yuv_buffer *yuv);

<p><p>1.1                  theora/win32/experimental/dumpvid/dumpvid.dsp

Index: dumpvid.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="dumpvid" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=dumpvid - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "dumpvid.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "dumpvid.mak" CFG="dumpvid - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "dumpvid - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "dumpvid - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE 

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe

!IF  "$(CFG)" == "dumpvid - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\include" /I "..\..\..\..\ogg\include" /I "..\wincompat" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib theora_static.lib ogg_static.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBCMT" /out:"dump_vid.exe" /libpath:"..\..\Static_Release" /libpath:"..\..\..\..\ogg\win32\Static_Release" /libpath:"..\..\..\..\vorbis\win32\Vorbis_Static_Release" /libpath:"..\..\..\..\vorbis\win32\VorbisEnc_Static_Release"

!ELSEIF  "$(CFG)" == "dumpvid - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\include" /I "..\..\..\..\ogg\include" /I "..\wincompat" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib theora_static_d.lib ogg_static_d.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"LIBCD" /out:"dump_vid.exe" /pdbtype:sept /libpath:"..\..\Static_Debug" /libpath:"..\..\..\..\ogg\win32\Static_Debug" /libpath:"..\..\..\..\vorbis\win32\Vorbis_Static_Debug" /libpath:"..\..\..\..\vorbis\win32\VorbisEnc_Static_Debug"
# SUBTRACT LINK32 /nodefaultlib

!ENDIF 

# Begin Target

# Name "dumpvid - Win32 Release"
# Name "dumpvid - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=..\..\..\examples\dump_video.c
# End Source File
# Begin Source File

SOURCE=..\wincompat\getopt.c
# End Source File
# Begin Source File

SOURCE=..\wincompat\getopt_long.c
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"

# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# Begin Group "library"

# PROP Default_Filter ""
# End Group
# Begin Source File

SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

<p><p>--- >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