/** \fn getFrame \brief Get a processed frame */ bool unstackFieldFilter::getNextFrame(uint32_t *fn,ADMImage *image) { // since we do nothing, just get the output of previous filter if(false==previousFilter->getNextFrame(fn,current)) { ADM_warning("unstackField : Cannot get frame\n"); return false; } // do in place flip image->copyInfo(current); for(int i=PLANAR_Y;i<PLANAR_LAST;i++) { ADM_PLANE plane=(ADM_PLANE)i; uint32_t srcPitch=current->GetPitch(plane); uint32_t dstPitch=image->GetPitch(plane); uint8_t *src=current->GetReadPtr(plane); uint8_t *dst=image->GetWritePtr(plane); uint32_t w=info.width; uint32_t h=info.height; if(plane) { w>>=1; h>>=1; } // Even BitBlit(dst, dstPitch*2,src,srcPitch,w,h/2); BitBlit(dst+dstPitch, dstPitch*2,src+(srcPitch*h)/2,srcPitch,w,h/2); } return true; }
/** \fn getFrame \brief Get a processed frame */ bool lavDeint::getNextFrame(uint32_t *fn,ADMImage *image) { // since we do nothing, just get the output of previous filter if(false==previousFilter->getNextFrame(fn,src)) { ADM_warning("rotate : Cannot get frame\n"); return false; } // const uint8_t *iBuff[3]; uint8_t *oBuff[3]; int strideIn[3],strideOut[3]; uint32_t stride[3]; image->GetWritePlanes(oBuff); src->GetReadPlanes((uint8_t **)iBuff); image->GetPitches(stride); for(int i=0;i<3;i++) strideOut[i]=stride[i]; src->GetPitches(stride); for(int i=0;i<3;i++) strideIn[i]=stride[i]; int type; if(src->flags&AVI_KEY_FRAME) type=1; else if(src->flags & AVI_B_FRAME) type=3; else type=2; pp_postprocess( iBuff, strideIn, oBuff, strideOut, info.width, info.height, NULL, 0, ppmode, ppcontext, type); // I ? image->copyInfo(src); return true; }
/** * \fn getNextFrame * @param fn * @param image * @return */ bool AVDM_FadeTo::getNextFrame(uint32_t *fn,ADMImage *image) { *fn=nextFrame; ADMImage *next= vidCache->getImage(nextFrame); if(!next) { ADM_info("[Fade] Cant get imageĀ \n"); return false; } image->Pts=next->Pts; uint64_t absPts=next->Pts+getAbsoluteStartTime(); bool out_of_scope=false; if(absPts<param.startFade*1000LL) out_of_scope=true; if(absPts>param.endFade*1000LL) out_of_scope=true; if(!out_of_scope && !first) { first=new ADMImageDefault(next->GetWidth (PLANAR_Y),next->GetHeight(PLANAR_Y)); first->duplicateFull (next); } if( out_of_scope || !first) { image->duplicate(next); nextFrame++; vidCache->unlockAll(); return true; } double scope=1000LL*(param.endFade-param.startFade); double in; if(!scope) { scope=1; in=1; }else { in=absPts-param.startFade*1000LL; } in=in/scope; in*=255; uint32_t offset=(uint32_t)floor(in+0.4); // normalized to 0--255, begin -- end process(first,next,image,offset); vidCache->unlockAll(); nextFrame++; return 1; }
/** \fn getNextFrame \brief */ bool ADMVideoHue::getNextFrame(uint32_t *fn,ADMImage *image) { ADMImage *src; src=vidCache->getImage(nextFrame); if(!src) return false; // EOF *fn=nextFrame++; image->copyInfo(src); image->copyPlane(src,image,PLANAR_Y); // Luma is untouched HueProcess_C(image->GetWritePtr(PLANAR_V), image->GetWritePtr(PLANAR_U), src->GetReadPtr(PLANAR_V), src->GetReadPtr(PLANAR_U), image->GetPitch(PLANAR_U),src->GetPitch(PLANAR_U), // assume u&v pitches are = info.width>>1,info.height>>1, _hue, _saturation); vidCache->unlockAll(); return 1; }
/** \fn getFrame \brief Get a processed frame */ bool swScaleResizeFilter::getNextFrame(uint32_t *fn,ADMImage *image) { // since we do nothing, just get the output of previous filter if(false==previousFilter->getNextFrame(fn,original)) { ADM_warning("swResize : Cannot get frame\n"); return false; } uint8_t *src[3]; uint8_t *dst[3]; uint32_t ssrc[3]; uint32_t ddst[3]; original->GetReadPlanes(src); image->GetWritePlanes(dst); original->GetPitches(ssrc); image->GetPitches(ddst); resizer->convertPlanes(ssrc,ddst,src,dst); image->copyInfo(original); // Fixme change A/R ? return true; }
/** \fn getFrame \brief Get a processed frame */ bool addLogopFilter::getNextFrame(uint32_t *fn,ADMImage *image) { // since we do nothing, just get the output of previous filter if(false==previousFilter->getNextFrame(fn,image)) { ADM_warning("logoFilter : Cannot get frame\n"); return false; } // do in place flip #if 1 if(myImage) myImage->copyToAlpha(image,configuration.x,configuration.y,configuration.alpha); #endif return true; }
void Msharpen::blur_plane(ADMImage *src, ADMImage *blur, int plane) { /* uint64_t mask1 = 0x00001C711C711C71LL; uint64_t mask2 = 0x1C711C711C710000LL; uint64_t mask3 = 0x0000200000002000LL; uint64_t mask4 = 0x0000000000ff0000LL; const unsigned char *srcp = src->GetReadPtr(plane); const unsigned char *srcp_saved = srcp; unsigned char *blurp_saved = blurp; int src_pitch = src->GetPitch(plane); int blur_pitch = blur->GetPitch(plane); int h = src->GetHeight(plane); int w = src->GetRowSize(plane); */ const unsigned char *srcp,*srcpn,*srcpp; const unsigned char *srcp_saved ; unsigned char *wk,*wk_saved; unsigned char *blurp_saved,*blurp ; int src_pitch; int blur_pitch; int work_pitch; int h; int w ; int wh ,ww,hh; blurp_saved=blurp=blur->GetWritePtr((ADM_PLANE)plane); srcp_saved=srcp=src->GetReadPtr((ADM_PLANE)plane); wk_saved=wk=work->GetWritePtr((ADM_PLANE)plane); ww=src->GetWidth((ADM_PLANE)plane); hh=src->GetHeight((ADM_PLANE)plane); src_pitch=src->GetPitch((ADM_PLANE)plane); blur_pitch=blur->GetPitch((ADM_PLANE)plane); work_pitch=work->GetPitch((ADM_PLANE)plane); w=ww; h=hh; wk+=work_pitch; srcpp=srcp; srcp+=src_pitch, srcpn=srcp+src_pitch; int val; // Vertical only for now #ifdef ADM_CPU_X86 if(CpuCaps::hasMMX()) { int off; #ifdef GCC_2_95_X __asm__( ADM_ASM_ALIGN16 "pxor %mm7,%mm7\n" : : ); #else __asm__( ADM_ASM_ALIGN16 "pxor %%mm7,%%mm7\n" : : ); #endif int wmod8=w>>3; for (int y=1; y<h-1 ;y++) { off=0; for (int x =0;x< wmod8; x++) { __asm__( ADM_ASM_ALIGN16 "movq (%0),%%mm0\n" "movq %%mm0,%%mm6\n" "punpckhbw %%mm7,%%mm0\n" // High part extended to 16 bits "punpcklbw %%mm7,%%mm6\n" // low part ditto "movq (%1),%%mm1\n" "movq %%mm1,%%mm5\n" "punpckhbw %%mm7,%%mm1\n" "punpcklbw %%mm7,%%mm5\n" "movq (%2),%%mm2\n" "movq %%mm2,%%mm4\n" "punpckhbw %%mm7,%%mm2\n" "punpcklbw %%mm7,%%mm4\n" "paddw %%mm1,%%mm0\n" "paddw %%mm5,%%mm6\n" "paddw %%mm1,%%mm2\n" "paddw %%mm5,%%mm4\n" "paddw %%mm0,%%mm2\n" "paddw %%mm6,%%mm4\n" "psrlw $2, %%mm4\n" "psrlw $2, %%mm2\n" "packuswb %%mm2,%%mm4\n" "movq %%mm4,(%3)\n" // : : "r" (srcpn+off), "r" (srcp+off), "r" (srcpp+off), "r" (wk+off) ); off+=8; } // mod 8 fix for(int x=wmod8*8;x<w;x++) { val=2*srcp[x]+srcpn[x]+srcpp[x]; wk[x]=(val)>>2; } srcp+=src_pitch; srcpp+=src_pitch; srcpn+=src_pitch; wk+=work_pitch; } __asm__("emms\n"); } else #endif { for (int y=1; y<h-1 ;y++)
/** \fn DecodePictureUpToIntra \brief Decode pictures from frameno, which must be an intra and on until the decoded frameno is popped by the decoder @param frame, framenumber relative to video ref (i.e. from its beginning) @param ref , video we are dealing with returns true on success fail on error */ bool ADM_Composer::DecodePictureUpToIntra(uint32_t ref,uint32_t frame) { uint8_t ret = 0; EditorCache *cache; ADMImage *result; uint32_t flags,flagsNext=0; ADMCompressedImage img; // PlaceHolder... img.data=compBuffer; img.cleanup(frame); ADM_info(" DecodeUpToInta %u ref:%u\n",frame,ref); _VIDEOS *vid=_segments.getRefVideo(ref); vidHeader *demuxer=vid->_aviheader; cache=vid->_videoCache; ADM_assert(cache); // Make sure frame is an intra, or the next field is intra demuxer->getFlags(frame,&flags); demuxer->getFlags(frame+1,&flagsNext); // in case of field encoding, only the 2nd field might be // flagged as intra uint32_t twoFlags=flags | flagsNext; ADM_assert(twoFlags&AVI_KEY_FRAME); bool found=false; vid->lastSentFrame=frame; uint32_t nbFrames=vid->_nb_video_frames; aprintf("[EditorRender] DecodeUpToIntra flushing cache & codec\n"); cache->flush(); vid->decoder->flush(); // The PTS associated with our frame is the one we are looking for uint64_t wantedPts=demuxer->estimatePts(frame); uint32_t tries=15+7; // Max Ref frames for H264 + MaxRecovery , let's say 7 is ok for recovery bool syncFound=false; while(found==false && tries--) { // Last frame ? if so repeat if(vid->lastSentFrame>=nbFrames-1) vid->lastSentFrame=nbFrames-1; // Fetch frame aprintf("[Editor] Decoding frame %u\n",vid->lastSentFrame); if (!demuxer->getFrame (vid->lastSentFrame,&img)) { ADM_warning(" getFrame failed for frame %"PRIu32"\n",vid->lastSentFrame); //cache->flush(); return false; } // Now uncompress it... result=cache->getFreeImage(); if(frame==0) // out first frame, make sure it starts black to avoid the all green effect { result->blacken(); } if(!result) { ADM_warning(" Cache full for frame %"PRIu32"\n",vid->lastSentFrame); return false; } aprintf("[Decoder] Demuxer Frame %"PRIu32" pts=%"PRIu64" ms, %"PRIu64" us\n",vid->lastSentFrame,img.demuxerPts/1000, img.demuxerPts); if(!decompressImage(result,&img,ref)) { ADM_info(" decode error for frame %"PRIu32", not necessarily a problem\n",vid->lastSentFrame); //cache->dump(); cache->invalidate(result); //cache->dump(); vid->lastSentFrame++; continue; }else { uint64_t pts=result->Pts; aprintf("[Decoder] Decoder Frame %"PRIu32" pts=%"PRIu64" ms, %"PRIu64" us\n",vid->lastSentFrame, result->Pts/1000,result->Pts); if(pts==ADM_COMPRESSED_NO_PTS) // No PTS available ? { if(false==syncFound) { aprintf("[DecodePictureUpToIntra] No time stamp yet, dropping picture\n"); cache->invalidate(result); }else { // increment it using average fps vid->lastDecodedPts+=vid->timeIncrementInUs; result->Pts=vid->lastDecodedPts; } }else { if(false==syncFound) { aprintf("[DecodePictureUpToIntra] Sync found\n"); syncFound=true; } vid->lastDecodedPts=pts; } cache->validate(result); } // Found our image ? if(result->Pts==wantedPts) found=true; else vid->lastSentFrame++; } if(found==false) { ADM_warning(" Could not find decoded frame, wanted PTS :%"PRIu32" PTS=%"PRIu64" ms, %"PRIu64" us\n",frame,wantedPts/1000,wantedPts); cache->dump(); return false; } vid->lastReadPts=wantedPts; currentFrame=frame; return true; }