
#include "config.h"

#include <stdio.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include <stdlib.h>
#include <unistd.h>

#include "mp_msg.h"
#include "help_mp.h"

#include "osdep/timer.h"
#include "osdep/shmem.h"

#include "stream.h"
#include "demuxer.h"
#include "parse_es.h"

#include "codec-cfg.h"

#include "libvo/video_out.h"

#include "stheader.h"
#include "vd.h"
#include "vf.h"

#include "dec_video.h"

#ifdef DYNAMIC_PLUGINS
#include <dlfcn.h>
#endif


#include "libvo/fastmemcpy.h"
mp_image_t *smpi=NULL;

extern double video_time_usage;
extern double vout_time_usage;

extern vd_functions_t* mpvdec; // FIXME!

#include "cpudetect.h"

void clearsmpi(void) {smpi=NULL;}

int vd_mpeg2_reset(sh_video_t *sh_video, int full_reset)
{
#ifdef USE_MPDVDNAV
if (!mpvdec) return 0;
if (!sh_video->enable_mpeg2_reset) return 0;
mpvdec->control(sh_video, VDCTRL_RESET, &full_reset);
return 1;
#else
return 0;
#endif
}


int decode_video_still(sh_video_t *sh_video,unsigned char *start,int in_size,int drop_frame,int enable_still){
vf_instance_t* vf;
mp_image_t *mpi=NULL;
unsigned int t=GetTimer();
unsigned int t2;
double tt;
int ret;

if (in_size>=0 || !enable_still) 
    //if(!(sh_video->ds->flags&1) || sh_video->ds->pack_no<5)
    mpi=mpvdec->decode(sh_video, start, in_size, drop_frame);
//------------------------ frame decoded. --------------------

#ifdef ARCH_X86
	// some codecs are broken, and doesn't restore MMX state :(
	// it happens usually with broken/damaged files.
    if(gCpuCaps.has3DNow){
	__asm __volatile ("femms\n\t":::"memory");
    }
    else if(gCpuCaps.hasMMX){
	__asm __volatile ("emms\n\t":::"memory");
    }
#endif

if (in_size>=0 && mpi && enable_still) 
  {
  smpi=mpi;		/* It will use copy_mpi() or other solution? */
  }
if (in_size<0 && enable_still && smpi) 
  {
  mpi=smpi;
  }


t2=GetTimer();t=t2-t;
tt = t*0.000001f;
video_time_usage+=tt;

if(!mpi || drop_frame) return 0; // error / skipped frame
//vo_draw_image(video_out,mpi);
vf=sh_video->vfilter;
ret = vf->put_image(vf,mpi); // apply video filters and call the leaf vo/ve
if(ret>0) vf->control(vf,VFCTRL_DRAW_OSD,NULL);

    t2=GetTimer()-t2;
    tt=t2*0.000001f;
    vout_time_usage+=tt;

return ret;
}
