⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fame_monitor.c

📁 一个很好用的MPEG1/4的开源编码器
💻 C
字号:
/*    libfame - Fast Assembly MPEG Encoder Library    Copyright (C) 2000-2001 Damien Vincent    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdio.h>#include <stdlib.h>#include "fame.h"#include "fame_malloc.h"#include "fame_monitor.h"#ifdef HAS_MMX#include "mad_mmx.h"#include "mae_mmx.h"#include "fetch_mmx.h"#else#include "mad_int.h"#include "mae_int.h"#include "fetch_float.h"#endif#define SCENE_CHANGE_THRESHOLD 10#define SCENE_CHANGE_MAXLENGTH 300static void monitor_init(fame_monitor_t *monitor,			 int (* retrieve_cb)(fame_frame_statistics_t *stats),			 unsigned int mb_width,			 unsigned int mb_height,			 unsigned int total_frames,			 unsigned int flags);static void monitor_close(fame_monitor_t *monitor);static void monitor_enter(fame_monitor_t *monitor,			  unsigned int frame_number,			  fame_yuv_t **ref,			  fame_yuv_t *frame,			  unsigned char *shape,			  char *coding);fame_frame_statistics_t * monitor_leave(fame_monitor_t *monitor,					unsigned int spent,					float quant_scale);FAME_CONSTRUCTOR(fame_monitor_t){  FAME_OBJECT(this)->name = "statistics monitoring";  FAME_MONITOR(this)->init = monitor_init;  FAME_MONITOR(this)->close = monitor_close;  FAME_MONITOR(this)->enter = monitor_enter;  FAME_MONITOR(this)->leave = monitor_leave;  FAME_MONITOR(this)->flags = 0;  return(this);}/* activity                                                                  *//*                                                                           *//* Description:                                                              *//*    returns the activity of the luminance component of the given frame     *//*                                                                           *//*                                                                           *//* Arguments:                                                                *//*    fame_yuv_t *frame: frame to compute activity for                       *//*    unsigned char *shape: shape of the given frame  (TODO)                 *//*    unsigned int mb_width, mb_height: macroblock's width and height        *//*                                                                           *//* Return value:                                                             *//*    activity of the frame.                                                 */unsigned int activity(fame_yuv_t *frame,		      unsigned char *shape,		      unsigned int mb_width,		      unsigned int mb_height){   int bx, by;  int a, p;  unsigned long m;  unsigned char *input;    a = 0;  p = frame->p;  input = frame->y;  for(by = 0; by < mb_height*2; by++) {    for(bx = 0; bx < mb_width*2; bx++) {      mad_withoutmask(input, p, &m);      a+=m;      input+=8;    }    input += (p << 3) - p;  }  return a;}unsigned int activity2(fame_yuv_t *ref,		       fame_yuv_t *frame,		       unsigned char *shape,		       unsigned int mb_width,		       unsigned int mb_height){   int bx, by;  int a, pi, pr;  unsigned long m;  unsigned char *input, *rref;    a = 0;  pi = frame->p;  pr = ref->p;  input = frame->y;  rref = ref->y;  for(by = 0; by < mb_height*2; by++) {    for(bx = 0; bx < mb_width*2; bx++) {      m = MAE8x8_withoutmask(rref, input, NULL, pi);      a+=m;      input+=8;      rref +=8;    }    input += (pi << 3) - (mb_width << 4);    rref  += (pr << 3) - (mb_width << 4);  }  return a;}/*  monitor_init                                                             *//*                                                                           *//*  Description:                                                             *//*    Initialise statistics monitor.                                         *//*                                                                           *//*  Arguments:                                                               *//*    fame_monitor_t *monitor: statistics monitoring                         *//*    store_cb: callback used to send statistics information out to the      *//*              program using libfame.                                       *//*    retrieve_cb: callback called to get initial statistics information     *//*                 from the program.                                         *//*    int flags: flags to setup monitoring.                                  *//*                                                                           *//*  Return value:                                                            *//*    None.                                                                  */static void monitor_init(fame_monitor_t *monitor,			 int (* retrieve_cb)(fame_frame_statistics_t *stats),			 unsigned int mb_width,			 unsigned int mb_height,			 unsigned int total_frames,			 unsigned int flags){  int i;  monitor->retrieve_stats_callback = retrieve_cb;  monitor->mb_width = mb_width;  monitor->mb_height = mb_height;  monitor->old_activity = 0;  monitor->keyframe = SCENE_CHANGE_MAXLENGTH;  monitor->flags = flags; if (monitor->retrieve_stats_callback)   monitor->flags |= FAME_MONITOR_LOAD_STATS;  if (monitor->flags & FAME_MONITOR_LOAD_STATS)     {      monitor->global_stats.total_frames = total_frames;      monitor->frame_stats_list = 	(fame_frame_statistics_t *) fame_malloc(total_frames*sizeof(fame_frame_statistics_t));      if (monitor->retrieve_stats_callback)	for (i=0; i<total_frames; i++) {	  monitor->retrieve_stats_callback(&(monitor->frame_stats_list[i]));	  monitor->global_stats.target_rate += 	    monitor->frame_stats_list[i].target_bits;	  monitor->global_stats.actual_rate +=	    monitor->frame_stats_list[i].actual_bits;	  monitor->global_stats.mean_spatial_activity +=	    monitor->frame_stats_list[i].spatial_activity;	}      monitor->current_frame_stats = monitor->frame_stats_list;    }  else    {      monitor->current_frame_stats = 	(fame_frame_statistics_t *) fame_malloc(sizeof(fame_frame_statistics_t));      monitor->global_stats.total_frames = 0;      monitor->frame_stats_list = NULL;    }}/*  monitor_close                                                            *//*                                                                           *//*  Description:                                                             *//*    Release statistics monitoring.                                         *//*                                                                           *//*  Arguments:                                                               *//*    fame_monitor_t *monitor: statistics monitoring                         *//*                                                                           *//*  Return value:                                                            *//*    None.                                                                  */static void monitor_close(fame_monitor_t *monitor){   if (monitor->flags && FAME_MONITOR_LOAD_STATS)     {      if (monitor->frame_stats_list) fame_free(monitor->frame_stats_list);    }  else    {      if (monitor->current_frame_stats) fame_free(monitor->current_frame_stats);    }}/*  monitor_enter                                                               *//*                                                                           *//*  Description:                                                             *//*    Prepare for a new frame.                                               *//*                                                                           *//*  Arguments:                                                               *//*    fame_monitor_t *monitor: statistics monitoring                         *//*    unsigned int frame_number: the current frame number                    *//*                                                                           *//*  Return value:                                                            *//*    None.                                                                  */static void monitor_enter(struct _fame_monitor_t_ *monitor,			  unsigned int frame_number,			  fame_yuv_t **ref,			  fame_yuv_t *frame,			  unsigned char *shape,			  char *coding){  int threshold;  if ((monitor->current_frame_stats)&&       !(monitor->flags & FAME_MONITOR_LOAD_STATS))  {    monitor->current_frame_stats->frame_number = frame_number;    monitor->current_frame_stats->spatial_activity =       activity2(ref[0],		frame, 		shape,		monitor->mb_width,		monitor->mb_height);      }    /* scene change detection */  /* the decay term (keyframe) is here to avoid very long sequences of inter */  /* frames that would result in artifacts due to the DCT/iDCT lack of       */  /* accuracy and that would also limit random access. */  threshold = monitor->keyframe*SCENE_CHANGE_THRESHOLD/SCENE_CHANGE_MAXLENGTH;  if ((frame_number == 0) || (monitor->current_frame_stats &&      monitor->current_frame_stats->spatial_activity >       (monitor->old_activity + threshold*monitor->mb_width*monitor->mb_height*256))) {    monitor->current_frame_stats->coding = 'I';  }  else monitor->current_frame_stats->coding = 'P';  if (monitor->current_frame_stats && *coding == 'A')    *coding = monitor->current_frame_stats->coding;  /* update inter frame counter */  if(*coding == 'I')    monitor->keyframe = SCENE_CHANGE_MAXLENGTH;  else    if(monitor->keyframe > 0) monitor->keyframe--;}/*  monitor_leave                                                               *//*                                                                           *//*  Description:                                                             *//*    Finish estimating a frame.                                             *//*                                                                           *//*  Arguments:                                                               *//*    fame_monitor_t *monitor: statistics monitoring                         *//*                                                                           *//*  Return value:                                                            *//*    None.                                                                  */fame_frame_statistics_t * monitor_leave(fame_monitor_t *monitor,                                        unsigned int spent,                                        float quant_scale){  fame_frame_statistics_t *current = NULL;#ifdef HAS_MMX  /* restore floating point context */  asm("emms");#endif  if (monitor->current_frame_stats) {    monitor->current_frame_stats->actual_bits = spent;    monitor->current_frame_stats->quant_scale = quant_scale;    monitor->old_activity = monitor->current_frame_stats->spatial_activity;    current = monitor->current_frame_stats;    if ((monitor->frame_stats_list) && 	(monitor->current_frame_stats->frame_number <= monitor->global_stats.total_frames)) {      /* TODO: update global_stats */      monitor->current_frame_stats++;    }  }  return current;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -