void DeleteXVIDDec(GF_BaseDecoder *ifcg) { XVIDCTX(); if (ctx->base_codec) xvid_decore(ctx->base_codec, XVID_DEC_DESTROY, NULL, NULL); if (ctx->depth_codec) xvid_decore(ctx->depth_codec, XVID_DEC_DESTROY, NULL, NULL); gf_free(ctx); gf_free(ifcg); }
static int init_xvid() { int ret; xvid_gbl_init_t xvid_gbl_init; xvid_dec_create_t xvid_dec_create; /* Reset the structure with zeros */ memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t)); memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t)); /* Version */ xvid_gbl_init.version = XVID_VERSION; xvid_gbl_init.cpu_flags = 0; xvid_gbl_init.debug = 0; xvid_global(NULL, 0, &xvid_gbl_init, NULL); /* Version */ xvid_dec_create.version = XVID_VERSION; /* * Image dimensions -- set to 0, xvidcore will resize when ever it is * needed */ xvid_dec_create.width = 0; xvid_dec_create.height = 0; ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL); g_ogm.xvid_dec_handle = xvid_dec_create.handle; return(ret); }
static void gst_xviddec_unset (GstXvidDec * dec) { /* release XviD decoder */ xvid_decore (dec->handle, XVID_DEC_DESTROY, NULL, NULL); dec->handle = NULL; }
static int dec_xvid(unsigned char *input, int input_size) { int ret; xvid_dec_frame_t xvid_dec_frame; /* Reset all structures */ memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t)); memset(&g_ogm.xvid_dec_stats, 0, sizeof(xvid_dec_stats_t)); /* Set version */ xvid_dec_frame.version = XVID_VERSION; g_ogm.xvid_dec_stats.version = XVID_VERSION; /* No general flags to set */ xvid_dec_frame.general = XVID_LOWDELAY;//0; /* Input stream */ xvid_dec_frame.bitstream = input; xvid_dec_frame.length = input_size; /* Output frame structure */ xvid_dec_frame.output.plane[0] = g_ogm.outputBuffer; xvid_dec_frame.output.stride[0] = g_ogm.outputWidht*BPP; if(g_ogm.outputBuffer==NULL) xvid_dec_frame.output.csp = XVID_CSP_NULL; else xvid_dec_frame.output.csp = XVID_CSP_RGBA; // example was with XVID_CSP_I420 ret = xvid_decore(g_ogm.xvid_dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, &g_ogm.xvid_dec_stats); return(ret); }
static void mpeg4_stop( struct mpeg4_decoder *en ) { spook_log( SL_DEBUG, "mpeg4: destroying mpeg4 decoder" ); xvid_decore( en->xvid_handle, XVID_DEC_DESTROY, NULL, NULL ); en->xvid_handle = NULL; }
/* decode one frame */ int XviDDec::dec_main(BYTE *istream, BYTE *ostream, int istream_size, xvid_dec_stats_t *xvid_dec_stats, DWORD pitch) { xvid_dec_frame_t xvid_dec_frame; /* Set version */ xvid_dec_frame.version = XVID_VERSION; xvid_dec_stats->version = XVID_VERSION; /* No general flags to set */ xvid_dec_frame.general = 0; // xvid_dec_frame.general = XVID_LOWDELAY; /* force low_delay_default mode */ /* Input stream */ xvid_dec_frame.bitstream = istream; xvid_dec_frame.length = istream_size; /* Output frame structure */ xvid_dec_frame.output.plane[0] = ostream; xvid_dec_frame.output.stride[0] = pitch; xvid_dec_frame.output.csp = colorspace; if(forceSkip)xvid_dec_frame.output.csp = XVID_CSP_NULL; return xvid_decore(dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, xvid_dec_stats); }
static int CIN_XVID_Decode (cinematic_t* cin, unsigned char* input, int inputSize) { int ret; xvid_dec_frame_t xvid_dec_frame; /* Reset all structures */ OBJZERO(xvid_dec_frame); OBJZERO(OGMCIN.xvidDecodeStats); /* Set version */ xvid_dec_frame.version = XVID_VERSION; OGMCIN.xvidDecodeStats.version = XVID_VERSION; /* No general flags to set */ xvid_dec_frame.general = XVID_LOWDELAY; /* Input stream */ xvid_dec_frame.bitstream = input; xvid_dec_frame.length = inputSize; /* Output frame structure */ xvid_dec_frame.output.plane[0] = OGMCIN.outputBuffer; xvid_dec_frame.output.stride[0] = OGMCIN.outputWidth * sizeof(*OGMCIN.outputBuffer); if (OGMCIN.outputBuffer == nullptr) xvid_dec_frame.output.csp = XVID_CSP_NULL; else xvid_dec_frame.output.csp = XVID_CSP_RGBA; ret = xvid_decore(OGMCIN.xvidDecodeHandle, XVID_DEC_DECODE, &xvid_dec_frame, &OGMCIN.xvidDecodeStats); return ret; }
static int CIN_XVID_Init (cinematic_t* cin) { int ret; xvid_gbl_init_t xvid_gbl_init; xvid_dec_create_t xvid_dec_create; /* Reset the structure with zeros */ OBJZERO(xvid_gbl_init); OBJZERO(xvid_dec_create); /* Version */ xvid_gbl_init.version = XVID_VERSION; xvid_gbl_init.cpu_flags = 0; xvid_gbl_init.debug = 0; xvid_global(nullptr, 0, &xvid_gbl_init, nullptr); /* Version */ xvid_dec_create.version = XVID_VERSION; /* Image dimensions -- set to 0, xvidcore will resize when ever it is needed */ xvid_dec_create.width = 0; xvid_dec_create.height = 0; ret = xvid_decore(nullptr, XVID_DEC_CREATE, &xvid_dec_create, nullptr); OGMCIN.xvidDecodeHandle = xvid_dec_create.handle; return ret; }
static void uninit(sh_video_t *sh){ priv_t* p = sh->context; if(!p) return; xvid_decore(p->hdl,XVID_DEC_DESTROY, NULL, NULL); free(p); }
static gboolean gst_xviddec_setup (GstXvidDec * dec) { xvid_dec_create_t xdec; gint ret; /* initialise parameters, see xvid documentation */ gst_xvid_init_struct (xdec); /* let the decoder handle this, don't trust the container */ xdec.width = 0; xdec.height = 0; xdec.handle = NULL; GST_DEBUG_OBJECT (dec, "Initializing xvid decoder with parameters " "%dx%d@%d", dec->width, dec->height, dec->csp); if ((ret = xvid_decore (NULL, XVID_DEC_CREATE, &xdec, NULL)) < 0) { GST_WARNING_OBJECT (dec, "Initializing xvid decoder failed: %s (%d)", gst_xvid_error (ret), ret); return FALSE; } dec->handle = xdec.handle; return TRUE; }
static void *mpeg4_loop( void *d ) { struct mpeg4_decoder *en = (struct mpeg4_decoder *)d; xvid_dec_frame_t xvid_dec_frame; xvid_dec_stats_t xvid_dec_stats; struct frame *out, *input; int used, pos; for(;;) { input = get_next_frame( en->ex, 1 ); if( en->reset_pending && en->xvid_handle ) mpeg4_stop( en ); if( ! en->xvid_handle ) mpeg4_start( en, input ); out = new_frame(); out->width = en->width; out->height = en->height; pos = 0; while( input->length - pos > 0 ) { memset( &xvid_dec_frame, 0, sizeof( xvid_dec_frame ) ); xvid_dec_frame.version = XVID_VERSION; xvid_dec_frame.general = 0; xvid_dec_frame.bitstream = input->d + pos; xvid_dec_frame.length = input->length - pos; xvid_dec_frame.output.plane[0] = out->d; xvid_dec_frame.output.stride[0] = 2 * out->width; xvid_dec_frame.output.csp = XVID_CSP_UYVY; xvid_dec_stats.version = XVID_VERSION; used = xvid_decore( en->xvid_handle, XVID_DEC_DECODE, &xvid_dec_frame, &xvid_dec_stats ); if( used < 0 ) { out->length = 0; spook_log( SL_WARN, "mpeg4: XviD decoding failed!" ); } if( xvid_dec_stats.type == XVID_TYPE_VOL ) { out->width = en->width = xvid_dec_stats.data.vol.width; out->height = en->height = xvid_dec_stats.data.vol.height; } pos += used; } out->format = FORMAT_RAW_UYVY; out->length = 2 * out->width * out->height; out->key = 1; deliver_frame( en->ex, out ); unref_frame( input ); } return NULL; }
static int shutdown_xvid() { int ret=0; if(g_ogm.xvid_dec_handle) ret = xvid_decore(g_ogm.xvid_dec_handle, XVID_DEC_DESTROY, NULL, NULL); return(ret); }
static int CIN_XVID_Shutdown (cinematic_t* cin) { int ret = 0; if (OGMCIN.xvidDecodeHandle) ret = xvid_decore(OGMCIN.xvidDecodeHandle, XVID_DEC_DESTROY, nullptr, nullptr); return ret; }
static GF_Err XVID_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) { XVIDCTX(); if (ctx->base_ES_ID == ES_ID) { if (ctx->base_codec) xvid_decore(ctx->base_codec, XVID_DEC_DESTROY, NULL, NULL); ctx->base_codec = NULL; ctx->base_ES_ID = 0; ctx->width = ctx->height = ctx->out_size = 0; } else if (ctx->depth_ES_ID == ES_ID) { if (ctx->depth_codec) xvid_decore(ctx->depth_codec, XVID_DEC_DESTROY, NULL, NULL); ctx->depth_codec = NULL; ctx->depth_ES_ID = 0; if (ctx->temp_uv) gf_free(ctx->temp_uv); ctx->temp_uv = NULL; } return GF_OK; }
/* close decoder to release resources */ int dec_stop() { int ret; ret=0; if(dec_handle) { ret = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL, 0); dec_handle=NULL; } return(ret); }
/* init decoder before first run */ int dec_init(int use_assembler, int debug_level) { int ret; xvid_gbl_init_t xvid_gbl_init; xvid_dec_create_t xvid_dec_create; /* Reset the structure with zeros */ memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t)); memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t)); dec_handle=NULL; XDIM=0; YDIM=0; /*------------------------------------------------------------------------ * XviD core initialization *----------------------------------------------------------------------*/ /* Version */ xvid_gbl_init.version = XVID_VERSION; xvid_gbl_init.cpu_flags = XVID_CPU_FORCE; xvid_gbl_init.debug = debug_level; xvid_global(NULL, 0, &xvid_gbl_init, NULL); /*------------------------------------------------------------------------ * XviD encoder initialization *----------------------------------------------------------------------*/ /* Version */ xvid_dec_create.version = XVID_VERSION; /* * Image dimensions -- set to 0, xvidcore will resize when ever it is * needed */ xvid_dec_create.width = 0; xvid_dec_create.height = 0; ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL, 0); if(ret!=0) return ret; dec_handle = xvid_dec_create.handle; return(ret); }
H263Codec::H263Codec(uint32 width, uint32 height) : _width(width), _height(height) { xvid_gbl_init_t xvid_gbl_init; memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t)); xvid_gbl_init.version = XVID_VERSION; xvid_gbl_init.debug = 0;//XVID_DEBUG_ERROR | XVID_DEBUG_HEADER | XVID_DEBUG_STARTCODE; xvid_global(0, XVID_GBL_INIT, &xvid_gbl_init, 0); xvid_dec_create_t xvid_dec_create; memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t)); xvid_dec_create.version = XVID_VERSION; xvid_dec_create.width = width; xvid_dec_create.height = height; if (xvid_decore(0, XVID_DEC_CREATE, &xvid_dec_create, 0) != 0) error("Could not initialize xvid decoder"); _decHandle = xvid_dec_create.handle; }
BOOL XviDDec::Start_XviD(int Xsize,int Ysize,int csp) { /***************************************************************************** * Memory allocation ****************************************************************************/ Clear_XviD(); width = Xsize; height = Ysize; colorspace = csp; filenr = 0; totalsize = 0; forceSkip = FALSE; buffer_size = 2*width*height; xvid_gbl_init_t xvid_gbl_init; xvid_dec_create_t xvid_dec_create; /*------------------------------------------------------------------------ * XviD core initialization *----------------------------------------------------------------------*/ /* Version */ xvid_gbl_init.version = XVID_VERSION; #ifndef _DEBUG xvid_gbl_init.cpu_flags = 0; #else xvid_gbl_init.cpu_flags = XVID_CPU_FORCE; #endif xvid_global(NULL, 0, &xvid_gbl_init, NULL); /*------------------------------------------------------------------------ * XviD encoder initialization *----------------------------------------------------------------------*/ /* Version */ xvid_dec_create.version = XVID_VERSION; /* * Image dimensions -- set to 0, xvidcore will resize when ever it is * needed */ xvid_dec_create.width = width; xvid_dec_create.height = height; int ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL); dec_handle = xvid_dec_create.handle; if(ret) return FALSE; bInit = TRUE; bContinue = FALSE; return TRUE; }
static void mpeg4_start( struct mpeg4_decoder *en, struct frame *f ) { xvid_dec_create_t xvid_dec_create; en->reset_pending = 0; memset( &xvid_dec_create, 0, sizeof( xvid_dec_create ) ); xvid_dec_create.version = XVID_VERSION; xvid_dec_create.width = 0; xvid_dec_create.height = 0; if( xvid_decore( NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL ) ) { spook_log( SL_ERR, "mpeg4: unable to start XviD!" ); return; } en->xvid_handle = xvid_dec_create.handle; }
VideoFrame *XVIDVideoCodec::decompressFrame(unsigned char *vbuf, int buflen) { xvid_dec_frame_t xvid_dec_frame; xvid_dec_stats_t xvid_dec_stats; int total = buflen; int ret; unsigned char *buffer_cur = vbuf; do { /* Reset all structures */ memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t)); memset(&xvid_dec_stats, 0, sizeof(xvid_dec_stats_t)); /* Set version */ xvid_dec_frame.version = XVID_VERSION; xvid_dec_stats.version = XVID_VERSION; /* No general flags to set */ xvid_dec_frame.general = 0; /* Input stream */ xvid_dec_frame.bitstream = buffer_cur; xvid_dec_frame.length = total; /* Output frame structure */ xvid_dec_frame.output.plane[0] = out_buffer; xvid_dec_frame.output.stride[0] = m_width*3; xvid_dec_frame.output.csp = XVID_CSP_BGR; ret = xvid_decore(dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, &xvid_dec_stats); total -= ret; buffer_cur += ret; } while( (total > 0) && (ret > 0)); IplImage *decoded = cvCreateImage(cvSize(m_width, m_height), IPL_DEPTH_8U, 3); memcpy(decoded->imageData, out_buffer, decoded->imageSize); VideoFrame *frame = new VideoFrame(decoded); return frame; }
void H263Codec::decodeFrame(Graphics::Surface &surface, Common::SeekableReadStream &dataStream) { // NOTE: When asking libxvidcore to decode the video into BGRA, it fills the alpha // values with 0x00, rendering the output invisible (!). // Since we, surprise, actually want to see the video, we would have to pass // over the whole video data and fix-up the alpha values ourselves. Or // alternatively do the YUV->BGRA conversion ourselves. We chose the latter. int dataSize = dataStream.size(); byte *data = new byte[dataSize]; dataStream.read(data, dataSize); xvid_dec_frame_t xvid_dec_frame; memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t)); xvid_dec_frame.version = XVID_VERSION; xvid_dec_frame.general = XVID_DEBLOCKY | XVID_DEBLOCKUV | XVID_DERINGY | XVID_DERINGUV; xvid_dec_frame.bitstream = data; xvid_dec_frame.length = dataSize; xvid_dec_frame.output.csp = XVID_CSP_INTERNAL; xvid_dec_stats_t xvid_dec_stats; memset(&xvid_dec_stats, 0, sizeof(xvid_dec_stats_t)); xvid_dec_stats.version = XVID_VERSION; int c = xvid_decore(_decHandle, XVID_DEC_DECODE, &xvid_dec_frame, &xvid_dec_stats); if ((dataSize - c) > 1) warning("H263Codec::decodeFrame(): %d bytes left in frame", dataSize - c); delete[] data; if (xvid_dec_frame.output.plane[0] && xvid_dec_frame.output.plane[1] && xvid_dec_frame.output.plane[2]) YUVToRGBMan.convert420(Graphics::YUVToRGBManager::kScaleFull, surface.getData(), surface.getWidth() * 4, (const byte *) xvid_dec_frame.output.plane[0], (const byte *) xvid_dec_frame.output.plane[1], (const byte *) xvid_dec_frame.output.plane[2], _width, _height, xvid_dec_frame.output.stride[0], xvid_dec_frame.output.stride[1]); }
void xvid_clean_up (xvid_codec_t *xvid) { if (xvid->m_xvid_handle != NULL) { xvid_decore(xvid->m_xvid_handle, XVID_DEC_DESTROY, NULL, NULL); xvid->m_xvid_handle = NULL; } if (xvid->m_ifile != NULL) { fclose(xvid->m_ifile); xvid->m_ifile = NULL; } if (xvid->m_buffer != NULL) { free(xvid->m_buffer); xvid->m_buffer = NULL; } if (xvid->m_fpos != NULL) { delete xvid->m_fpos; xvid->m_fpos = NULL; } free(xvid); }
static GF_Err XVID_ProcessData(GF_MediaDecoder *ifcg, char *inBuffer, u32 inBufferLength, u16 ES_ID, char *outBuffer, u32 *outBufferLength, u8 PaddingBits, u32 mmlevel) { #ifdef XVID_USE_OLD_API XVID_DEC_FRAME frame; #else xvid_dec_frame_t frame; #endif void *codec; s32 postproc, res; XVIDCTX(); if (!ES_ID) { *outBufferLength = 0; return GF_OK; } if (ES_ID == ctx->depth_ES_ID) { codec = ctx->depth_codec; } else { codec = ctx->base_codec; } if (!codec) return GF_OK; if (*outBufferLength < ctx->out_size) { *outBufferLength = ctx->out_size; return GF_BUFFER_TOO_SMALL; } memset(&frame, 0, sizeof(frame)); frame.bitstream = (void *) (inBuffer + ctx->offset); frame.length = inBufferLength - ctx->offset; ctx->offset = 0; #ifdef XVID_USE_OLD_API frame.colorspace = XVID_CSP_I420; frame.stride = ctx->width; frame.image = (void *) outBuffer; #else frame.version = XVID_VERSION; if (ES_ID == ctx->depth_ES_ID) { frame.output.csp = XVID_CSP_PLANAR; frame.output.stride[0] = ctx->width; frame.output.plane[0] = (void *) (outBuffer + ctx->yuv_size); frame.output.stride[1] = ctx->width/4; frame.output.plane[1] = (void *) ctx->temp_uv; frame.output.stride[2] = ctx->width/4; frame.output.plane[2] = (void *) ctx->temp_uv; } else { frame.output.csp = XVID_CSP_I420; frame.output.stride[0] = ctx->width; frame.output.plane[0] = (void *) outBuffer; } #endif /*to check, not convinced yet by results...*/ postproc = ctx->base_filters; switch (mmlevel) { case GF_CODEC_LEVEL_SEEK: case GF_CODEC_LEVEL_DROP: /*turn off all post-proc*/ #ifdef XVID_USE_OLD_API postproc &= ~XVID_DEC_DEBLOCKY; postproc &= ~XVID_DEC_DEBLOCKUV; #else postproc &= ~XVID_DEBLOCKY; postproc &= ~XVID_DEBLOCKUV; postproc &= ~XVID_FILMEFFECT; #endif break; case GF_CODEC_LEVEL_VERY_LATE: /*turn off post-proc*/ #ifdef XVID_USE_OLD_API postproc &= ~XVID_DEC_DEBLOCKY; #else postproc &= ~XVID_FILMEFFECT; postproc &= ~XVID_DEBLOCKY; #endif break; case GF_CODEC_LEVEL_LATE: #ifdef XVID_USE_OLD_API postproc &= ~XVID_DEC_DEBLOCKUV; #else postproc &= ~XVID_DEBLOCKUV; postproc &= ~XVID_FILMEFFECT; #endif break; } postproc = 0; /*xvid may keep the first I frame and force a 1-frame delay, so we simply trick it*/ if (ctx->first_frame) { outBuffer[0] = 'v'; outBuffer[1] = 'o'; outBuffer[2] = 'i'; outBuffer[3] = 'd'; } res = xvid_decore(codec, XVID_DEC_DECODE, &frame, NULL); if (res < 0) { *outBufferLength = 0; return GF_NON_COMPLIANT_BITSTREAM; } if (0 && res <= 6) { *outBufferLength = 0; return GF_OK; } /*dispatch nothing if seeking or droping*/ switch (mmlevel) { case GF_CODEC_LEVEL_SEEK: case GF_CODEC_LEVEL_DROP: if (ES_ID == ctx->base_ES_ID) *outBufferLength = 0; break; default: *outBufferLength = ctx->out_size; if (ctx->first_frame) { ctx->first_frame = 0; if ((outBuffer[0] == 'v') && (outBuffer[1] == 'o') && (outBuffer[2] == 'i') && (outBuffer[3] == 'd')) { *outBufferLength = 0; return GF_OK; } } if (res + 6 < frame.length) { ctx->offset = res; return GF_PACKED_FRAMES; } break; } return GF_OK; }
XVIDVideoCodec::XVIDVideoCodec() { m_width = 160; m_height = 120; /* encoder init */ in_buffer = (unsigned char *) malloc(m_width * m_height * 3); mp4_buffer = (unsigned char *) malloc(m_width * m_height * 3); ARG_FRAMERATE = 2.0f; /*25.00f;*/ ARG_QUALITY = ME_ELEMENTS - 1; static void *enc_handle = NULL; int result = enc_init(); if (result) { wxMessageBox("Could not initialize XVid CODEC", _T("Error"), wxICON_ERROR | wxOK); exit(0); } /* decoder init */ xvid_gbl_init_t xvid_gbl_init; xvid_dec_create_t xvid_dec_create; /* Reset the structure with zeros */ memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t)); memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t)); /* Version */ xvid_gbl_init.version = XVID_VERSION; /* Assembly setting */ #ifdef ARCH_IS_IA64 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64; #else xvid_gbl_init.cpu_flags = 0; #endif xvid_gbl_init.debug = 0/*debug_level*/; xvid_global(NULL, 0, &xvid_gbl_init, NULL); xvid_dec_create.version = XVID_VERSION; xvid_dec_create.width = m_width; xvid_dec_create.height = m_height; int ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL); if (ret) { wxMessageBox("Could not initialize XVid CODEC", _T("Error"), wxICON_ERROR | wxOK); exit(0); } dec_handle = xvid_dec_create.handle; out_buffer = (unsigned char*)malloc(m_width*m_height*4); memset(out_buffer, 0x00, m_width*m_height*4); }
static int init(sh_video_t *sh) { xvid_gbl_info_t xvid_gbl_info; xvid_gbl_init_t xvid_ini; xvid_dec_create_t dec_p; priv_t* p; int cs; memset(&xvid_gbl_info, 0, sizeof(xvid_gbl_info_t)); xvid_gbl_info.version = XVID_VERSION; memset(&xvid_ini, 0, sizeof(xvid_gbl_init_t)); xvid_ini.version = XVID_VERSION; memset(&dec_p, 0, sizeof(xvid_dec_create_t)); dec_p.version = XVID_VERSION; switch(sh->codec->outfmt[sh->outfmtidx]){ case IMGFMT_YV12: /* We will use our own buffers, this speeds decoding avoiding * frame memcpy's overhead */ cs = (do_dr2)?XVID_CSP_INTERNAL:XVID_CSP_USER; break; case IMGFMT_YUY2: cs = XVID_CSP_YUY2; break; case IMGFMT_UYVY: cs = XVID_CSP_UYVY; break; case IMGFMT_I420: case IMGFMT_IYUV: /* We will use our own buffers, this speeds decoding avoiding * frame memcpy's overhead */ cs = (do_dr2)?XVID_CSP_INTERNAL:XVID_CSP_USER; break; case IMGFMT_BGR15: cs = XVID_CSP_RGB555; break; case IMGFMT_BGR16: cs = XVID_CSP_RGB565; break; case IMGFMT_BGR32: cs = XVID_CSP_BGRA; break; case IMGFMT_YVYU: cs = XVID_CSP_YVYU; break; default: mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Unsupported out_fmt: 0x%X\n", sh->codec->outfmt[sh->outfmtidx]); return 0; } /* Gather some information about the host library */ if(xvid_global(NULL, XVID_GBL_INFO, &xvid_gbl_info, NULL) < 0) { mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: could not get information about the library\n"); } else { mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: using library version %d.%d.%d (build %s)\n", XVID_VERSION_MAJOR(xvid_gbl_info.actual_version), XVID_VERSION_MINOR(xvid_gbl_info.actual_version), XVID_VERSION_PATCH(xvid_gbl_info.actual_version), xvid_gbl_info.build); } /* Initialize the xvidcore library */ if(xvid_global(NULL, XVID_GBL_INIT, &xvid_ini, NULL)) return 0; /* We use 0 width and height so xvidcore will resize its buffers * if required. That allows this vd plugin to do resize on first * VOL encountered (don't trust containers' width and height) */ dec_p.width = 0; dec_p.height = 0; /* Get a decoder instance */ if(xvid_decore(0, XVID_DEC_CREATE, &dec_p, NULL)<0) { mp_msg(MSGT_DECVIDEO, MSGL_ERR, "XviD init failed\n"); return 0; } p = malloc(sizeof(priv_t)); p->cs = cs; p->hdl = dec_p.handle; p->vo_initialized = 0; sh->context = p; switch(cs) { case XVID_CSP_INTERNAL: p->img_type = MP_IMGTYPE_EXPORT; break; case XVID_CSP_USER: p->img_type = MP_IMGTYPE_STATIC; break; default: p->img_type = MP_IMGTYPE_TEMP; break; } return 1; }
static mp_image_t* decode(sh_video_t *sh, void* data, int len, int flags) { xvid_dec_frame_t dec; xvid_dec_stats_t stats; mp_image_t* mpi = NULL; priv_t* p = sh->context; if(!data || len <= 0) return NULL; memset(&dec,0,sizeof(xvid_dec_frame_t)); memset(&stats, 0, sizeof(xvid_dec_stats_t)); dec.version = XVID_VERSION; stats.version = XVID_VERSION; dec.bitstream = data; dec.length = len; dec.general |= XVID_LOWDELAY /* XXX: if lowdelay is unset, and xvidcore internal buffers are * used => crash. MUST FIX */ | (filmeffect ? XVID_FILMEFFECT : 0 ) | (lumadeblock ? XVID_DEBLOCKY : 0 ) | (chromadeblock ? XVID_DEBLOCKUV : 0 ); #if XVID_API >= XVID_MAKE_API(4,1) dec.general |= (lumadering ? XVID_DEBLOCKY|XVID_DERINGY : 0 ); dec.general |= (chromadering ? XVID_DEBLOCKUV|XVID_DERINGUV : 0 ); #endif dec.output.csp = p->cs; /* Decoding loop because xvidcore may return VOL information for * on the fly buffer resizing. In that case we must decode VOL, * init VO, then decode the frame */ do { int consumed; /* If we don't know frame size yet, don't even try to request * a buffer, we must loop until we find a VOL, so VO plugin * is initialized and we can obviously output something */ if (p->vo_initialized) { mpi = mpcodecs_get_image(sh, p->img_type, MP_IMGFLAG_ACCEPT_STRIDE, sh->disp_w, sh->disp_h); if (!mpi) return NULL; if(p->cs != XVID_CSP_INTERNAL) { dec.output.plane[0] = mpi->planes[0]; dec.output.plane[1] = mpi->planes[1]; dec.output.plane[2] = mpi->planes[2]; dec.output.stride[0] = mpi->stride[0]; dec.output.stride[1] = mpi->stride[1]; dec.output.stride[2] = mpi->stride[2]; } } /* Decode data */ consumed = xvid_decore(p->hdl, XVID_DEC_DECODE, &dec, &stats); if (consumed < 0) { mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Decoding error\n"); return NULL; } /* Found a VOL information stats, if VO plugin is not initialized * yet then do it now */ if (stats.type == XVID_TYPE_VOL && !p->vo_initialized) { sh->original_aspect = stats2aspect(&stats); if(!mpcodecs_config_vo(sh, stats.data.vol.width, stats.data.vol.height, IMGFMT_YV12)) return NULL; /* Don't take this path twice */ p->vo_initialized = !p->vo_initialized; } /* Don't forget to update buffer position and buffer length */ dec.bitstream += consumed; dec.length -= consumed; } while ((stats.type == XVID_TYPE_VOL || stats.type == XVID_TYPE_NOTHING) && dec.length > 0); /* There are two ways to get out of the decoding loop: * - a frame has been returned * - no more data in buffer and no frames returned */ /* If mpi is NULL, it proves nothing has been returned by the decoder * so don't try to display internal buffers. */ if (mpi != NULL && p->cs == XVID_CSP_INTERNAL) { mpi->planes[0] = dec.output.plane[0]; mpi->planes[1] = dec.output.plane[1]; mpi->planes[2] = dec.output.plane[2]; mpi->stride[0] = dec.output.stride[0]; mpi->stride[1] = dec.output.stride[1]; mpi->stride[2] = dec.output.stride[2]; } /* If we got out the decoding loop because the buffer was empty and there was nothing * to output yet, then just return NULL */ return (stats.type == XVID_TYPE_NOTHING) ? NULL : mpi; }
H263Codec::~H263Codec() { xvid_decore(_decHandle, XVID_DEC_DESTROY, 0, 0); }
/* close decoder to release resources */ void XviDDec::Clear_XviD() { if(NULL==dec_handle)return; xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL); dec_handle = NULL; }
static GF_Err XVID_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) { GF_M4VDecSpecInfo dsi; GF_Err e; void **codec; #ifdef XVID_USE_OLD_API XVID_DEC_FRAME frame; XVID_DEC_PARAM par; #else xvid_dec_frame_t frame; xvid_dec_create_t par; #endif XVIDCTX(); if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->data) return GF_NON_COMPLIANT_BITSTREAM; /*locate any auxiliary video data descriptor on this stream*/ if (esd->dependsOnESID) { u32 i = 0; GF_Descriptor *d = NULL; if (esd->dependsOnESID != ctx->base_ES_ID) return GF_NOT_SUPPORTED; #ifdef XVID_USE_OLD_API return GF_NOT_SUPPORTED; #endif while ((d = gf_list_enum(esd->extensionDescriptors, &i))) { if (d->tag == GF_ODF_AUX_VIDEO_DATA) break; } if (!d) return GF_NOT_SUPPORTED; codec = &ctx->depth_codec; ctx->depth_ES_ID = esd->ESID; } else { if (ctx->base_ES_ID && ctx->base_ES_ID!=esd->ESID) return GF_NOT_SUPPORTED; codec = &ctx->base_codec; ctx->base_ES_ID = esd->ESID; } if (*codec) xvid_decore(*codec, XVID_DEC_DESTROY, NULL, NULL); /*decode DSI*/ e = gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); if (e) return e; if (!dsi.width || !dsi.height) return GF_NON_COMPLIANT_BITSTREAM; memset(&par, 0, sizeof(par)); par.width = dsi.width; par.height = dsi.height; /*note that this may be irrelevant when used through systems (FPS is driven by systems CTS)*/ ctx->FPS = dsi.clock_rate; ctx->FPS /= 1000; if (!ctx->FPS) ctx->FPS = 30.0f; ctx->pixel_ar = (dsi.par_num<<16) | dsi.par_den; #ifndef XVID_USE_OLD_API par.version = XVID_VERSION; #endif if (xvid_decore(NULL, XVID_DEC_CREATE, &par, NULL) < 0) return GF_NON_COMPLIANT_BITSTREAM; ctx->width = par.width; ctx->height = par.height; *codec = par.handle; /*init decoder*/ memset(&frame, 0, sizeof(frame)); frame.bitstream = (void *) esd->decoderConfig->decoderSpecificInfo->data; frame.length = esd->decoderConfig->decoderSpecificInfo->dataLength; #ifndef XVID_USE_OLD_API frame.version = XVID_VERSION; xvid_decore(*codec, XVID_DEC_DECODE, &frame, NULL); #else /*don't perform error check, XviD doesn't like DSI only frame ...*/ xvid_decore(*codec, XVID_DEC_DECODE, &frame, NULL); #endif ctx->first_frame = 1; /*output in YV12 only - let the player handle conversion*/ if (ctx->depth_codec) { ctx->out_size = ctx->width * ctx->height * 5 / 2; ctx->temp_uv = gf_malloc(sizeof(char)*ctx->width * ctx->height / 2); } else { ctx->yuv_size = ctx->out_size = ctx->width * ctx->height * 3 / 2; } return GF_OK; }
static GstFlowReturn gst_xviddec_chain (GstPad * pad, GstBuffer * buf) { GstXvidDec *dec; GstBuffer *outbuf = NULL; xvid_dec_frame_t xframe; xvid_dec_stats_t xstats; gint ret; guint8 *data, *dupe = NULL; guint size; GstFlowReturn fret; dec = GST_XVIDDEC (GST_OBJECT_PARENT (pad)); if (!dec->handle) goto not_negotiated; fret = GST_FLOW_OK; GST_LOG_OBJECT (dec, "Received buffer of time %" GST_TIME_FORMAT " duration %" GST_TIME_FORMAT ", size %d", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_SIZE (buf)); if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) { /* FIXME: should we do anything here, like flush the decoder? */ } data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); /* xvidcore overreads the input buffer, we need to alloc some extra padding * to make things work reliably */ #define EXTRA_PADDING 16 if (EXTRA_PADDING > 0) { dupe = g_malloc (size + EXTRA_PADDING); memcpy (dupe, data, size); memset (dupe + size, 0, EXTRA_PADDING); data = dupe; } do { /* loop needed because xvidcore may return vol information */ /* decode and so ... */ gst_xvid_init_struct (xframe); xframe.general = XVID_LOWDELAY; xframe.bitstream = (void *) data; xframe.length = size; gst_xvid_init_struct (xstats); if (outbuf == NULL) { fret = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE, dec->outbuf_size, GST_PAD_CAPS (dec->srcpad), &outbuf); if (fret != GST_FLOW_OK) goto done; } gst_xvid_image_fill (&xframe.output, GST_BUFFER_DATA (outbuf), dec->csp, dec->width, dec->height); ret = xvid_decore (dec->handle, XVID_DEC_DECODE, &xframe, &xstats); if (ret < 0) goto decode_error; GST_LOG_OBJECT (dec, "xvid produced output, type %d, consumed %d", xstats.type, ret); if (xstats.type == XVID_TYPE_VOL) gst_xviddec_negotiate (dec, &xstats); data += ret; size -= ret; } while (xstats.type <= 0 && size > 0); /* 1 byte is frequently left over */ if (size > 1) { GST_WARNING_OBJECT (dec, "decoder did not consume all input"); } /* FIXME, reflow the multiple return exit points */ if (xstats.type > 0) { /* some real output was produced */ if (G_UNLIKELY (dec->waiting_for_key)) { if (xstats.type != XVID_TYPE_IVOP) goto dropping; dec->waiting_for_key = FALSE; } /* bframes can cause a delay in frames being returned non keyframe timestamps can permute a bit between encode and display order, but should match for keyframes */ if (dec->have_ts) { GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts; GST_BUFFER_DURATION (outbuf) = dec->next_dur; dec->next_ts = GST_BUFFER_TIMESTAMP (buf); dec->next_dur = GST_BUFFER_DURATION (buf); } else { GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf); } gst_buffer_set_caps (outbuf, GST_PAD_CAPS (dec->srcpad)); GST_LOG_OBJECT (dec, "pushing buffer with pts %" GST_TIME_FORMAT " duration %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf))); fret = gst_pad_push (dec->srcpad, outbuf); } else { /* no real output yet, delay in frames being returned */ if (G_UNLIKELY (dec->have_ts)) { GST_WARNING_OBJECT (dec, "xvid decoder produced no output, but timestamp %" GST_TIME_FORMAT " already queued", GST_TIME_ARGS (dec->next_ts)); } else { dec->have_ts = TRUE; dec->next_ts = GST_BUFFER_TIMESTAMP (buf); dec->next_dur = GST_BUFFER_DURATION (buf); } gst_buffer_unref (outbuf); } done: g_free (dupe); gst_buffer_unref (buf); return fret; /* ERRORS */ not_negotiated: { GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL), ("format wasn't negotiated before chain function")); fret = GST_FLOW_NOT_NEGOTIATED; goto done; } decode_error: { /* FIXME: shouldn't error out fatally/properly after N decoding errors? */ GST_ELEMENT_WARNING (dec, STREAM, DECODE, (NULL), ("Error decoding xvid frame: %s (%d)", gst_xvid_error (ret), ret)); if (outbuf) gst_buffer_unref (outbuf); goto done; } dropping: { GST_WARNING_OBJECT (dec, "Dropping non-keyframe (seek/init)"); if (outbuf) gst_buffer_unref (outbuf); goto done; } }