示例#1
0
static int nuv_decode_video(TCModuleInstance *self,
                            vframe_list_t *inframe, vframe_list_t *outframe)
{
    PrivateData *pd;
    uint8_t comptype, *encoded_frame;
    int in_framesize, out_framesize;
    int free_frame = 0;  // set to 1 if we need to free the decompress buffer

    TC_MODULE_SELF_CHECK(self, "decode_video");
    TC_MODULE_SELF_CHECK(inframe, "decode_video");
    TC_MODULE_SELF_CHECK(outframe, "decode_video");

    pd = self->userdata;

    if (!pd->dec_initted) {
        pd->width  = inframe->video_buf[0]<<8 | inframe->video_buf[1];
        pd->height = inframe->video_buf[2]<<8 | inframe->video_buf[3];
        RTjpeg_init_decompress((uint32_t *)(inframe->video_buf+5),
                               pd->width, pd->height);
        pd->dec_initted = 1;
    }

    comptype = inframe->video_buf[4];
    encoded_frame = inframe->video_buf+5+sizeof(pd->cdata);
    in_framesize = inframe->video_size-5-sizeof(pd->cdata);
    out_framesize = pd->width*pd->height + (pd->width/2)*(pd->height/2)*2;

    if (comptype == '2' || comptype == '3') {
        /* Undo LZO compression */
        uint8_t *decompressed_frame;
        lzo_uint len;
        decompressed_frame = tc_malloc(out_framesize);
        if (!decompressed_frame) {
            tc_log_error(MOD_NAME, "No memory for decompressed frame!");
            return TC_ERROR;
        }
        if (lzo1x_decompress(encoded_frame, in_framesize,
                             decompressed_frame, &len, NULL) == LZO_E_OK) {
            encoded_frame = decompressed_frame;
            in_framesize = len;
            free_frame = 1;
        } else {
            tc_log_warn(MOD_NAME, "Unable to decompress video frame");
            tc_free(decompressed_frame);
            /* And try it as raw, just like rtjpeg_vid_plugin */
        }
        /* Convert 2 -> 1, 3 -> 0 */
        comptype ^= 3;
    }

    switch (comptype) {

      case '0':  // Uncompressed YUV
        if (in_framesize > out_framesize)
            in_framesize = out_framesize;
        ac_memcpy(outframe->video_buf, encoded_frame, in_framesize);
        break;

      case '1':  // RTjpeg-compressed data
        RTjpeg_decompressYUV420((int8_t *)encoded_frame, outframe->video_buf);
        break;

      case 'N':  // Black frame
        memset(outframe->video_buf, 0, pd->width*pd->height);
        memset(outframe->video_buf + pd->width*pd->height, 128,
               (pd->width/2)*(pd->height/2)*2);
        break;

      case 'L':  // Repeat last frame--leave videobuf alone
        // Should have been handled by demux!
        tc_log_warn(MOD_NAME, "BUG: 'L' frame not handled!");
        break;

      default:
        tc_log_warn(MOD_NAME, "Unknown video compression type %c (%02X)",
                    comptype >= ' ' && comptype <= '=' ? comptype : '?',
                    comptype);
        break;

    }  // switch (comptype)

    if (free_frame)
        tc_free(encoded_frame);
    outframe->video_size = out_framesize;
    return TC_OK;
}
示例#2
0
int main( int argc, char** argv )
{
  unsigned int w, h;
  int tmp;
  FILE* f;
  struct stat st;
  struct rtj_header hdr;
  __u8 *source;
  __u8 *target;
  
  if ( argc != 2 ) {
    print_help();
    exit(0);
  }

  if ( stat( argv[1], &st ) != 0 ) {
    perror( "stat:" );
    exit(1);
  }
  
  f = fopen( argv[1] , "r" );
  
  if ( !rtj_read_header(&hdr,f) ) {
    fprintf( stderr, "This doesn't seem to be a RTJPEG header.\n" );
    return 1;
  }


  w = hdr.width;
  h = hdr.height;
  
  source = malloc( w*h*3 ); /* size of YUV picture info */
  
  assert( source != NULL ); 
  
  tmp = fread( source, 1, w*h*3, f );

  /*  assert( tmp == w*h*3  ); */
  
  fprintf( stderr, "Read %i bytes from file.\n", tmp );
  
  RTjpeg_init_decompress( hdr.tbls, w, h );
  target = malloc( w*h*3 );
  
  RTjpeg_decompressYUV420( source, target );
  
  
  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    perror( "SDL_init:" );
    exit(1);
  }    
  
  /* setup signal handlers */
  signal(SIGINT,sig_handler);
  atexit( SDL_Quit );
  
  screen = SDL_SetVideoMode( w, h, 24, SDL_HWSURFACE );
  SDL_EventState(SDL_KEYDOWN, SDL_ENABLE);
  SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
  SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);

  assert( screen != NULL );
  
  if ( SDL_MUSTLOCK( screen ) ) {
    if ( SDL_LockSurface(screen) < 0 ) {
      assert(0);
      exit(1);
    }
  }
  
  /* copy image to screen and convert to RGB32 */
  RTjpeg_yuvrgb24( target, screen->pixels, w*3 );   
  
  if ( SDL_MUSTLOCK( screen ) ) {
    SDL_UnlockSurface(screen);
  }

  SDL_UpdateRect(screen, 0, 0, w, h);

  pause();
  
  return 0;
}
示例#3
0
void decode_nuv( unsigned char *encoded, int encoded_size,
		unsigned char *decoded, int width, int height)
{
	int r;
	unsigned int out_len = width * height + ( width * height ) / 2;
	struct rtframeheader *encodedh = ( struct rtframeheader* ) encoded;
	static unsigned char *buffer = 0; /* for RTJpeg with LZO decompress */
#ifdef KEEP_BUFFER
	static unsigned char *previous_buffer = 0; /* to support Last-frame-copy */
#endif

//	printf("frametype: %c, comtype: %c, encoded_size: %d, width: %d, height: %d\n",
//	    encodedh->frametype, encodedh->comptype, encoded_size, width, height);

	le2me_rtframeheader(encodedh);
	switch(encodedh->frametype)
	{
	    case 'D':	/* additional data for compressors */
	    {
		/* tables are in encoded */
		if (encodedh->comptype == 'R')
		{
		    RTjpeg_init_decompress ( (unsigned long *)(encoded+12), width, height );
		    mp_msg(MSGT_DECVIDEO, MSGL_V, "Found RTjpeg tables (size: %d, width: %d, height: %d)\n",
			encoded_size-12, width, height);
		}
		break;
	    }
	    case 'V':
	    {
		int in_len = encodedh->packetlength;
#ifdef KEEP_BUFFER		
		if (!previous_buffer) 
			previous_buffer = ( unsigned char * ) malloc ( out_len + LZO_OUTPUT_PADDING );
#endif

		switch(encodedh->comptype)
		{
		    case '0': /* raw YUV420 */
			memcpy(decoded, encoded + 12, out_len);
			break;
		    case '1': /* RTJpeg */
			RTjpeg_decompressYUV420 ( ( __s8 * ) encoded + 12, decoded );
			break;
		    case '2': /* RTJpeg with LZO */
			if (!buffer) 
			    buffer = ( unsigned char * ) malloc ( out_len + LZO_OUTPUT_PADDING );
			if (!buffer)
			{
			    mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Nuppelvideo: error decompressing\n");
			    break;
			}
			r = lzo1x_decode ( buffer, &out_len, encoded + 12, &in_len );
			if ( r ) 
			{
			    mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Nuppelvideo: error decompressing\n");
			    break;
			}
			RTjpeg_decompressYUV420 ( ( __s8 * ) buffer, decoded );
			break;
		    case '3': /* raw YUV420 with LZO */
			r = lzo1x_decode ( decoded, &out_len, encoded + 12, &in_len );
			if ( r ) 
			{
			    mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Nuppelvideo: error decompressing\n");
			    break;
			}
			break;
		    case 'N': /* black frame */
			memset ( decoded, 0,  width * height );
			memset ( decoded + width * height, 127, width * height / 2);
			break;
		    case 'L': /* copy last frame */
#ifdef KEEP_BUFFER
			memcpy ( decoded, previous_buffer, width*height*3/2);
#endif
			break;
		}

#ifdef KEEP_BUFFER
		memcpy(previous_buffer, decoded, width*height*3/2);
#endif
		break;
	    }
	    default:
		mp_msg(MSGT_DECVIDEO, MSGL_V, "Nuppelvideo: unknwon frametype: %c\n",
		    encodedh->frametype);
	}
}