[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[OpenDivX] Tagging in CVS? (or 'This is getting painful').



Hi,

After much struggling to build a (new) working decore and get XMPS to work
with it, I'm close to my wits end.  For all of my efforts, I cannot get the
xmps-opendivx-plugin to work with new versions of decore.  It seems that
decore is changing rapidly and I can't keep up.  I'm now not sure if my test
videos can even be decoded by the latest version of decore.

TEST SCENARIO (WHICH FAILS)
To try to limit the number of variables, I'm now using a modified version of
Christoph Lambert's (http://www.math.chalmers.se/~lampert/)  simpledivx
test_enc and test_dec programs.  I have a working test_enc encoder test
application and a (sort-of) working test_dec program.

I'm running the following simple test sequence (which fails):

 1) cat raw-24bpp-frame | test_enc > divx_frame
 2) cat divx_frame | test_dec > divx_output_frame
 3) Use gimp to visually inspect divx_output_frame and compare it to the
input image.

test_dec segfaults when it calls YV12toRGB24(...) with "Illegal instruction
(core dumped)".

The fault might be that encore is producing a compressed file that decore
doesn't understand.  Or it might be something else, like the way I
initialise decore...?

Christoph Lambert has kindly suggested that I don't use the latest code from
CVS as the decore interface appears to change daily.

What I need is a version of divxcore where encore produces output that
decore can understand.  I would also appreciate it if someone (anyone) could
tell me what is wrong with my test_dec application.

TAGGING IN CVS
Has anyone thought to tag the divxcore code each time a "stable" point is
reached.  Looking at the tags in the divxcore module this doesn't seem to be
the case.

If you want a flourishing open-source project, this is advisable.

Below, I have included the source for (slightly modified versions) Christoph
Lambert's test_enc and test_dec programs.

Regards,
Stuart.

============================================================================
===============
TEST_ENC:

/************************************************************************
 *                                                                      *
 *  test_enc.c    Test opendivx encoding by compressing one frame       *
 *                                                                      *
 *  Christoph Lampert, 2001/05/22                                       *
 *                                                                      *
 *  compile with:   cc test_enc.c rgb2yuv.c -o test_enc -lencore        *
 *                                                                      *
 ************************************************************************/

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#include "encore.h"
#include "rgb2yuv.h"

#define MY_APP_ID 0x0815	// doesn't matter

#define XDIM 640
#define YDIM 480
#define BUFFERSIZE 512000	// This should be more than enough for 1 frame

double msecond();

int main()
{
  char *in_buffer[3];
  char *bmp_buffer;
  char *divx_buffer;
  char *yuv_buffer;

  int status;
  int frame_size;

  int filenr;
  char filename[20];
  FILE* outfile;

  ENC_PARAM enc_param;
  ENC_FRAME enc_frame;
  ENC_RESULT enc_result;

  frame_size = XDIM*YDIM + XDIM/2*YDIM/2 + XDIM/2*YDIM/2;	// full Y,
subsamples U,V

  /* ...skip check for malloc failure... don't do that in application!!! */
  yuv_buffer=(char*) malloc(frame_size);
  bmp_buffer=(char*) malloc(3*XDIM*YDIM);
  divx_buffer=(char*) malloc(BUFFERSIZE);

  /*********************************************************************/
  /*                            DIVX PART  Start                       */
  /*********************************************************************/
  /* Init the encoder */
  enc_param.x_dim = XDIM;
  enc_param.y_dim = YDIM;
  enc_param.framerate = 24.0;
  enc_param.bitrate = 900000;
  enc_param.rc_period = 300;

  enc_param.rc_period = 2000;
  enc_param.rc_reaction_period = 10;
  enc_param.rc_reaction_ratio = 20;
  enc_param.search_range = 128;

  enc_param.max_quantizer = 15;
  enc_param.min_quantizer = 1;    // these setting are not
					    // important for a single file

  status = encore(MY_APP_ID, ENC_OPT_INIT, &enc_param, NULL);
  fprintf(stderr,"Encore INIT return %d\n",status);

  /*********************************************************************/
  /*                            Main Part                              */
  /*********************************************************************/
  /* read raw RGB from stdin */
  fread(bmp_buffer,XDIM,3*YDIM,stdin);

  /* convert raw RGB to YUV 4:2:0, that encore()-input format */
  in_buffer[0]=yuv_buffer;
  in_buffer[1]=yuv_buffer + XDIM*YDIM;
  in_buffer[2]=yuv_buffer + XDIM*YDIM + XDIM/2*YDIM/2;
  fread(bmp_buffer,XDIM,3*YDIM,stdin);

  RGB2YUV(XDIM, YDIM, bmp_buffer, in_buffer[0], in_buffer[1], in_buffer[2])
;

  /* Encode one frame */
  enc_frame.image       = (void *) yuv_buffer;
  enc_frame.bitstream   = (void *) divx_buffer;
  enc_frame.length      = 0;				// will be filled by routine

  status = encore(MY_APP_ID, ENC_OPT_WRITE, &enc_frame, &enc_result);

  fprintf(stderr,"Encore ENCODE return %d, divx-stream length=%ld
bytes\n",status,enc_frame.length);
  fprintf(stderr,"Encore RESULT IsKeyFrame=%d\n",enc_result.isKeyFrame);

  /* Write encoded data to stdout */

  fwrite(divx_buffer,1,enc_frame.length,stdout);

  /*********************************************************************/
  /*                            DIVX PART  Stop                        */
  /*********************************************************************/
  /* Stop the encoder */
  status = encore(MY_APP_ID, ENC_OPT_RELEASE, &enc_frame, NULL); // END
Encoding
  fprintf(stderr,"Encore RELEASE return %d\n",status);

  free(divx_buffer);
  free(bmp_buffer);
  free(yuv_buffer);

  return 0;
}

============================================================================
===============
TEST_DEC:

/************************************************************************
 *                                                                      *
 *  test_dec.c    Test opendivx decoding by decompressing one frame     *
 *                                                                      *
 *  Christoph Lampert, 2001/05/22                                       *
 *                                                                      *
 *  compile with:   cc -o test_dec  test_dec.c -DLINUX -ldivxdecore -lm *
 *                                                                      *
 ************************************************************************/

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include "decore.h"

#define MY_APP_ID 0x0815

#define XDIM 640
#define YDIM 480
#define BUFFERSIZE 100000

void init_yuv2rgb();

void YV12toRGB24(unsigned char *puc_y, int stride_y,
		 unsigned char *puc_u, unsigned char *puc_v, int stride_uv,
		 unsigned char *puc_out,
		 int width_y, int height_y,
		 unsigned int stride_out);

int main(int argc, char **argv)
{
  unsigned char *yuv_buffer;
  unsigned char *bmp_buffer;
  unsigned char *divx_buffer;
  int status;
  int divx_size;
  int a;
  char bufa[100], bufb[100];

  DEC_MEM_REQS dec_memreqs;
  DEC_PARAM dec_param;
  DEC_SET   dec_set;
  DEC_FRAME dec_frame;

  /* ...skip check for malloc failure... don't do this in applications! */
  yuv_buffer=(unsigned char*) memalign(8,XDIM*YDIM*3/2); // Y is full-res, U
and V subsampled
  bmp_buffer=(unsigned char*) memalign(8,3*XDIM*YDIM);	 // RGB is in
full-res
  divx_buffer=(unsigned char*) memalign(8,BUFFERSIZE);

  /*********************************************************************/
  /*                            DIVX PART  Start                       */
  /*********************************************************************/
  /* Init the decoder, this has become a little complicated... */
  dec_param.x_dim = XDIM;
  dec_param.y_dim = YDIM;
  dec_param.output_format=1; //DEC_YUV2; // output color format
  dec_param.time_incr=0;

  status = decore(MY_APP_ID, DEC_OPT_MEMORY_REQS, &dec_param, &dec_memreqs);
  fprintf(stderr,"Decore MEM_REQS return %d\n",status);

  dec_param.buffers.mp4_edged_ref_buffers = memalign(8,
dec_memreqs.mp4_edged_ref_buffers_size);
  dec_param.buffers.mp4_edged_for_buffers = memalign(8,
dec_memreqs.mp4_edged_for_buffers_size);
  dec_param.buffers.mp4_display_buffers   = memalign(8,
dec_memreqs.mp4_display_buffers_size);
  dec_param.buffers.mp4_state = memalign(8, dec_memreqs.mp4_state_size);
  dec_param.buffers.mp4_tables = memalign(8, dec_memreqs.mp4_tables_size);

  // Without the two lines below decore(DEC_OPT_INIT) dumps core.
  // Don't follow the stupid documentation, because its WRONG.
  dec_param.buffers.mp4_reference = memalign(8,
dec_memreqs.mp4_reference_size);
  memset(dec_param.buffers.mp4_reference, 0,
dec_memreqs.mp4_reference_size);

  dec_param.buffers.mp4_stream = memalign(8,dec_memreqs.mp4_stream_size);
  memset(dec_param.buffers.mp4_stream, 0, dec_memreqs.mp4_stream_size);
  memset(dec_param.buffers.mp4_state, 0, dec_memreqs.mp4_state_size);
  memset(dec_param.buffers.mp4_tables, 0,dec_memreqs.mp4_tables_size);

  printf("Calling decore - INIT\n");
  status = decore(MY_APP_ID, DEC_OPT_INIT, &dec_param, NULL);
  fprintf(stderr,"Decore INIT return %d\n",status);

  status = decore(MY_APP_ID, DEC_OPT_SETOUT, &dec_param,NULL);
  fprintf(stderr,"Decore SETOUT return %d\n",status);

  /* Set the postprocessing level:  0 = no PP */
  dec_set.postproc_level = 50;
  status = decore(MY_APP_ID, DEC_OPT_SETPP, &dec_set, NULL);
  fprintf(stderr,"Decore POSTPROC %d return
%d\n",dec_set.postproc_level,status);

  /*********************************************************************/
  /*                            Main Part                              */
  /*********************************************************************/
  /* read opendivx-encoded stream from stdin */
  /* here only 1 Frame, so don't analyze any structure */
  divx_size=fread(divx_buffer, 1, BUFFERSIZE, stdin);
  fprintf(stderr, "Framelength is %d\n",divx_size);

  /* Decode one frame */
  dec_frame.length      = divx_size;
  dec_frame.bitstream   = divx_buffer;
  dec_frame.bmp         = (void *) yuv_buffer;
  dec_frame.render_flag = 1;
  dec_frame.stride      = XDIM;

  fprintf(stderr,"Decore FRAME start\n");
  status = decore(MY_APP_ID, 0, &dec_frame, NULL);
  fprintf(stderr,"Decore FRAME return %d\n",status);

  /* convert YUV 4:2:0 (back) to RGB, for output and viewing */
  /*  void YV12toRGB24_generic(uint8_t *puc_y, int stride_y,
			   uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
			   uint8_t *puc_out, int width_y, int height_y,
			   unsigned int _stride_out) */
  init_yuv2rgb();   // has to be called once for conversion later
  YV12toRGB24(yuv_buffer,
	      XDIM,
	      yuv_buffer+XDIM*YDIM,
	      yuv_buffer+XDIM*YDIM+XDIM/2*YDIM/2,
	      (XDIM/2),
	      bmp_buffer,
	      XDIM, YDIM,
	      XDIM*3);

  /* write PPM-file output, that is just header + RGB data  */
  // Write the output bitmap to stdout
  fprintf(stdout,"P6\n%3d %3d\n255\n",XDIM,YDIM); // remove this to get RAW
RGB out
  fwrite(bmp_buffer,XDIM,YDIM*3,stdout);

  /* Stop the decoder */
  status = decore(MY_APP_ID, DEC_OPT_RELEASE, NULL, NULL);
  fprintf(stderr,"Decore RELEASE return %d\n",status);

  /*********************************************************************/
  /*                            DIVX PART  End                         */
  /*********************************************************************/
  free(dec_param.buffers.mp4_edged_ref_buffers);
  free(dec_param.buffers.mp4_edged_for_buffers);
  free(dec_param.buffers.mp4_display_buffers);
  free(dec_param.buffers.mp4_state);
  free(dec_param.buffers.mp4_tables);
  free(dec_param.buffers.mp4_stream);
  free(dec_param.buffers.mp4_reference);

  free(divx_buffer);
  free(yuv_buffer);
  free(bmp_buffer);

  return 0;
}



_______________________________________________
OpenDivX mailing list
[email protected]
http://lists.projectmayo.com/mailman/listinfo/opendivx


Reply To Poster

Local References / HOW-TO / FAQs