Exemplo n.º 1
0
// dump accumulated statistics and reset accumulated values
const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
  int number_of_frames;
  int i, j;
  uint32_t bytes_total = 0;
  double scale[COMPONENTS];
  double psnr[COMPONENTS];
  double mse[COMPONENTS];
  double y_scale;

  SvcInternal *const si = get_svc_internal(svc_ctx);
  if (svc_ctx == NULL || si == NULL) return NULL;

  svc_log_reset(svc_ctx);

  number_of_frames = si->psnr_pkt_received;
  if (number_of_frames <= 0) return vpx_svc_get_message(svc_ctx);

  svc_log(svc_ctx, SVC_LOG_INFO, "\n");
  for (i = 0; i < svc_ctx->spatial_layers; ++i) {

    svc_log(svc_ctx, SVC_LOG_INFO,
            "Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n",
            i, (double)si->psnr_sum[i][0] / number_of_frames,
            (double)si->psnr_sum[i][1] / number_of_frames,
            (double)si->psnr_sum[i][2] / number_of_frames,
            (double)si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]);
    // the following psnr calculation is deduced from ffmpeg.c#print_report
    y_scale = si->width * si->height * 255.0 * 255.0 * number_of_frames;
    scale[1] = y_scale;
    scale[2] = scale[3] = y_scale / 4;  // U or V
    scale[0] = y_scale * 1.5;           // total

    for (j = 0; j < COMPONENTS; j++) {
      psnr[j] = calc_psnr(si->sse_sum[i][j] / scale[j]);
      mse[j] = si->sse_sum[i][j] * 255.0 * 255.0 / scale[j];
    }
    svc_log(svc_ctx, SVC_LOG_INFO,
            "Layer %d Overall PSNR=[%2.3f, %2.3f, %2.3f, %2.3f]\n", i, psnr[0],
            psnr[1], psnr[2], psnr[3]);
    svc_log(svc_ctx, SVC_LOG_INFO,
            "Layer %d Overall MSE=[%2.3f, %2.3f, %2.3f, %2.3f]\n", i, mse[0],
            mse[1], mse[2], mse[3]);

    bytes_total += si->bytes_sum[i];
    // clear sums for next time
    si->bytes_sum[i] = 0;
    for (j = 0; j < COMPONENTS; ++j) {
      si->psnr_sum[i][j] = 0;
      si->sse_sum[i][j] = 0;
    }
  }

  // only display statistics once
  si->psnr_pkt_received = 0;

  svc_log(svc_ctx, SVC_LOG_INFO, "Total Bytes=[%u]\n", bytes_total);
  return vpx_svc_get_message(svc_ctx);
}
Exemplo n.º 2
0
Uint32 diff_mode(void)
{
    FILE* fd_tmp;
    Uint8* y_tmp;

    /* Perhaps a bit ugly but it seams to work...
     * 1. read frame from fd
     * 2. store data away
     * 3. read frame from P.fd2
     * 4. calculate diff
     * 5. place result in P.raw or P.y_data depending on FORMAT
     * 6. diff works on luma data so clear P.cb_data and P.cr_data
     * Fiddle with the file descriptors so that we read
     * from correct file.
     */

    if (!(*reader[FORMAT])()) {
        return 0;
    }

    y_tmp = malloc(sizeof(Uint8) * P.y_size);

    if (!y_tmp) {
        fprintf(stderr, "Error allocating memory...\n");
        return 0;
    }

    for (Uint32 i = 0; i < P.y_size; i++) {
        y_tmp[i] = P.y_data[i];
    }

    fd_tmp = fd;
    fd = P.fd2;

    if (!(*reader[FORMAT])()) {
        free(y_tmp);
        fd = fd_tmp;
        return 0;
    }

    /* restore file descriptor */
    fd = fd_tmp;

    /* now, P.y_data contains luminance data for fd2 and
     * y_tmp contains luma data for fd.
     * Calculate diff and place result where it belongs
     * Clear croma data */

    calc_psnr(y_tmp, P.y_data);

    if (FORMAT == YV12 || FORMAT == IYUV) {
        for (Uint32 i = 0; i < P.y_size; i++) {
            P.y_data[i] = 0x80 - (y_tmp[i] - P.y_data[i]);
        }
        for (Uint32 i = 0; i < P.cb_size; i++) P.cb_data[i] = 0x80;
        for (Uint32 i = 0; i < P.cr_size; i++) P.cr_data[i] = 0x80;
    } else {
        Uint32 j = 0;
        for (Uint32 i = P.y_start_pos; i < P.frame_size; i += 2) {
            P.raw[i] = 0x80 - (y_tmp[j] - P.y_data[j]);
            j++;
        }
        for (Uint32 i = P.cb_start_pos; i < P.frame_size; i += 4)  P.raw[i] = 0x80;
        for (Uint32 i = P.cr_start_pos; i < P.frame_size; i += 4)  P.raw[i] = 0x80;
    }

    free(y_tmp);

    return 1;
}
Exemplo n.º 3
0
static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
	mlt_frame b_frame = mlt_frame_pop_frame( a_frame );
	mlt_properties properties = MLT_FRAME_PROPERTIES( a_frame );
	mlt_transition transition = MLT_TRANSITION( mlt_frame_pop_service( a_frame ) );
	uint8_t *b_image;
	int window_size = mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( transition ), "window_size" );
	double psnr[3], ssim[3];

	*format = mlt_image_yuv422;
	mlt_frame_get_image( b_frame, &b_image, format, width, height, writable );
	mlt_frame_get_image( a_frame, image, format, width, height, writable );

	psnr[0] = calc_psnr( *image, b_image, *width * *height, 2 );
	psnr[1] = calc_psnr( *image + 1, b_image + 1, *width * *height / 2, 4 );
	psnr[2] = calc_psnr( *image + 3, b_image + 3, *width * *height / 2, 4 );
	ssim[0] = calc_ssim( *image, b_image, *width, *height, window_size, 2 );
	ssim[1] = calc_ssim( *image + 1, b_image + 1, *width / 2, *height, window_size, 4 );
	ssim[2] = calc_ssim( *image + 3, b_image + 3, *width / 2, *height, window_size, 4 );
	mlt_properties_set_double( properties, "meta.vqm.psnr.y", psnr[0] );
	mlt_properties_set_double( properties, "meta.vqm.psnr.cb", psnr[1] );
	mlt_properties_set_double( properties, "meta.vqm.psnr.cr", psnr[2] );
	mlt_properties_set_double( properties, "meta.vqm.ssim.y", ssim[0] );
	mlt_properties_set_double( properties, "meta.vqm.ssim.cb", ssim[1] );
	mlt_properties_set_double( properties, "meta.vqm.ssim.cr", ssim[2] );
	printf( "%05d %05.2f %05.2f %05.2f %5.3f %5.3f %5.3f\n",
			mlt_frame_get_position( a_frame ), psnr[0], psnr[1], psnr[2],
			ssim[0], ssim[1], ssim[2] );

	// copy the B frame to the bottom of the A frame for comparison
	window_size = mlt_image_format_size( *format, *width, *height, NULL ) / 2;
	memcpy( *image + window_size, b_image + window_size, window_size );

	if ( !mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( transition ), "render" ) )
		return 0;

	// get RGBA image for Qt drawing
	*format = mlt_image_rgb24a;
	mlt_frame_get_image( a_frame, image, format, width, height, 1 );

	// convert mlt image to qimage
	QImage img( *width, *height, QImage::Format_ARGB32 );
	int y = *height + 1;
	uint8_t *src = *image;
	while ( --y )
	{
		QRgb *dst = (QRgb*) img.scanLine( *height - y );
		int x = *width + 1;
		while ( --x )
		{
			*dst++ = qRgba( src[0], src[1], src[2], 255 );
			src += 4;
		}
	}

	// setup Qt drawing
	QPainter painter;
	painter.begin( &img );
	painter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing );

	// draw some stuff with Qt
	QPalette palette;
	QFont font;
	QString s;
	font.setBold( true );
	font.setPointSize( 30 * *height / 1080 );
	painter.setPen( QColor("black") );
	painter.drawLine( 0, *height/2 + 1, *width, *height/2 );
	painter.setPen( QColor("white") );
	painter.drawLine( 0, *height/2 - 1, *width, *height/2 );
	painter.setFont( font );
	s.sprintf( "Frame: %05d\nPSNR:   %05.2f (Y) %05.2f (Cb) %05.2f (Cr)\nSSIM:    %5.3f (Y) %5.3f (Cb) %5.3f (Cr)",
			  mlt_frame_get_position( a_frame ), psnr[0], psnr[1], psnr[2],
			  ssim[0], ssim[1], ssim[2] );
	painter.setPen( QColor("black") );
	painter.drawText( 52, *height * 8 / 10 + 2, *width, *height, 0, s );
	painter.setPen( QColor("white") );
	painter.drawText( 50, *height * 8 / 10, *width, *height, 0, s );

	// finish Qt drawing
	painter.end();
	window_size = mlt_image_format_size( *format, *width, *height, NULL );
	uint8_t *dst = (uint8_t *) mlt_pool_alloc( window_size );
	mlt_properties_set_data( MLT_FRAME_PROPERTIES(a_frame), "image", dst, window_size, mlt_pool_release, NULL );
	*image = dst;

	// convert qimage to mlt
	y = *height + 1;
	while ( --y )
	{
		QRgb *src = (QRgb*) img.scanLine( *height - y );
		int x = *width + 1;
		while ( --x )
		{
			*dst++ = qRed( *src );
			*dst++ = qGreen( *src );
			*dst++ = qBlue( *src );
			*dst++ = qAlpha( *src );
			src++;
		}
	}

	return 0;
}