void MainWindow::compatiblePortalFound(bool found, video* portal) { disableDownloadUi(true); ui.downloadComboQuality->clear();; if (found == true) { ui.downloadLineEdit->setReadOnly(true); ui.downloadInfoBox->setText(tr("Please wait while ClipGrab is loading information about the video ...")); if (currentVideo) { currentVideo->deleteLater();; } currentVideo = portal->createNewInstance(); currentVideo->setUrl(ui.downloadLineEdit->text()); connect(currentVideo, SIGNAL(error(QString,video*)), cg, SLOT(errorHandler(QString,video*))); connect(currentVideo, SIGNAL(analysingFinished()), this, SLOT(updateVideoInfo())); currentVideo->analyse(); } else { if (ui.downloadLineEdit->text() == "") { ui.downloadInfoBox->setText(tr("Please enter the link to the video you want to download in the field below.")); } else if (ui.downloadLineEdit->text().startsWith("http://") || ui.downloadLineEdit->text().startsWith("https://")) { ui.downloadLineEdit->setReadOnly(true); ui.downloadInfoBox->setText(tr("The link you have entered seems to not be recognised by any of the supported portals.<br/>Now ClipGrab will check if it can download a video from that site anyway.")); if (currentVideo) { currentVideo->deleteLater();; } currentVideo = cg->heuristic->createNewInstance(); currentVideo->setUrl(ui.downloadLineEdit->text()); connect(currentVideo, SIGNAL(error(QString,video*)), cg, SLOT(errorHandler(QString,video*))); connect(currentVideo, SIGNAL(analysingFinished()), this, SLOT(updateVideoInfo())); currentVideo->analyse(); } } }
/** Load or append a file. The file type is determined automatically and the ad-hoc video decoder is spawned */ uint8_t ADM_Composer::addFile (char *name, uint8_t mode) { uint8_t ret = 0; aviInfo info; WAVHeader * _wavinfo; // aviHeader * tmp; fileType type = Unknown_FileType; UNUSED_ARG(mode); _haveMarkers=0; // by default no markers are present assert (_nb_segment < MAX_SEG); assert (_nb_video < MAX_VIDEO); if (!identify (name, &type)) return 0; #define OPEN_AS(x,y) case x:\ _videos[_nb_video]._aviheader=new y; \ ret = _videos[_nb_video]._aviheader->open(name); \ break; switch (type) { case VCodec_FileType: loadVideoCodecConf(name); return ADM_IGN; // we do it but it wil fail, no problem with that break; OPEN_AS (Mp4_FileType, mp4Header); OPEN_AS (H263_FileType, h263Header); // For AVI we first try top open it as openDML case AVI_FileType: _videos[_nb_video]._aviheader=new OpenDMLHeader; ret = _videos[_nb_video]._aviheader->open(name); break; OPEN_AS (Nuppel_FileType, nuvHeader); OPEN_AS (BMP_FileType, picHeader); OPEN_AS (MpegIdx_FileType, mpeg2decHeader); OPEN_AS (_3GPP_FileType, _3GPHeader); OPEN_AS (Ogg_FileType, oggHeader); case Mpeg_FileType: // look if the idx exists char tmpname[256]; assert(strlen(name)+5<256);; strcpy(tmpname,name); strcat(tmpname,".idx"); if(addFile(tmpname)) return 1; // then propose to index it if (GUI_Question ("This looks like mpeg\n Do you want to index it?")) { char * idx, * mname; int track; DIA_indexerPrefill(name); if (DIA_mpegIndexer (&mname, &idx, &track, 1)) { if ((mname == NULL) || (idx == NULL)) { GUI_Alert ("Select files!"); return 0; } printf ("\n indexing :%s to \n%s\n", mname, idx); if (indexMpeg (mname, idx, (uint8_t) track)) { printf("\n re-opening %s\n", idx); return addFile (idx, 0); } return 0; } } return 0; break; case WorkBench_FileType: return loadWorbench(name); default: if (type == Unknown_FileType) { printf ("\n not identified ...\n"); } else printf ("\n successfully identified but no loader support detected...\n"); return 0; } // check opening was successful if (ret == 0) { printf ("\n Attempt to open %s failed!\n", name); delete _videos[_nb_video]. _aviheader;; return 0; } // else update info _videos[_nb_video]._aviheader->getVideoInfo (&info); _videos[_nb_video]._aviheader->setMyName (name); // fourCC::print( info.fcc ); _total_frames += info.nb_frames; _videos[_nb_video]._nb_video_frames = info.nb_frames; // and update audio info //_________________________ _wavinfo = _videos[_nb_video]._aviheader->getAudioInfo (); //wavinfo); // will be null if no audio if (!_wavinfo) { printf ("\n *** NO AUDIO ***\n"); _videos[_nb_video]._audiostream = NULL; } else { _videos[_nb_video]._aviheader->getAudioStream (&_videos[_nb_video]. _audiostream); _videos[_nb_video]._audio_size = _videos[_nb_video]._audiostream->getLength (); // For mpeg2, try to guess if it is pulldowned material double duration_a, duration_v; double rdirect, rpulldown; duration_a=_videos[_nb_video]._audio_size; duration_a/=_wavinfo->byterate; // now we got duration in seconds // ditto for video duration_v= _videos[_nb_video]._nb_video_frames; duration_v/=info.fps1000; duration_v*=1000; printf("Audio : %f video : %f\n",duration_a,duration_v); if(MpegIdx_FileType==type && info.fps1000>29000 && info.fps1000<30000 && duration_a>1 && duration_v>1) { rdirect=(duration_a-duration_v)/duration_v; if(rdirect<0) rdirect=-rdirect; rpulldown=((duration_a*0.8)-duration_v)/duration_v; if(rpulldown<0) rpulldown=-rpulldown; printf("Direct : %f pd : %f\n",rdirect,rpulldown); if( rdirect*2> rpulldown) { printf("Probably pulldowned, switching to 23.976 \n"); AVIStreamHeader *ily = _videos[_nb_video]._aviheader-> getVideoStreamHeader (); ily->dwRate = 23976; ily->dwScale = 1000; } } } printf ("\n Decoder FCC: "); fourCC::print (info.fcc); // ugly hack if (info.fps1000 > 2000 * 1000) { printf (" FPS too high, switching to 25 fps hardcoded\n"); info.fps1000 = 25 * 1000; updateVideoInfo (&info); } uint32_t l; uint8_t * d; _videos[_nb_video]._aviheader->getExtraHeaderData (&l, &d); _videos[_nb_video].decoder = getDecoder (info.fcc, info.width, info.height, l, d); // // And automatically create the segment // _segments[_nb_segment]._reference = _nb_video; _segments[_nb_segment]._audio_size = _videos[_nb_video]._audio_size; _segments[_nb_segment]._audio_start = 0; _segments[_nb_segment]._start_frame = 0; _segments[_nb_segment]._nb_frames = _videos[_nb_video]._nb_video_frames ; _videos[_nb_video]._isAudioVbr=0; // next one please _nb_video++; _nb_segment++; //______________________________________ // 1- check for B _ frame existence // 2- check for consistency with reported flags //______________________________________ uint8_t count=0; TryAgain: _VIDEOS *vid; uint32_t err=0; vid= &(_videos[_nb_video-1]); vid->_forwardReference=0xFFFFFFF; vid->_forwardFrame= NULL; vid->_reorderReady=0; // we only try if we got everything needed... if(!vid->decoder) { printf("\n no decoder to check for B- frame\n"); return 1; } if(!vid->decoder->bFramePossible()) { printf("\n no B- frame with that codec \n"); return 1; } printf("\n checking for B-Frames...\n"); if( vid->_nb_video_frames >15) // 12 { uint8_t *buffer,*bufferin; uint32_t len,flags,flag2; uint8_t bframe=0, bconsistency=1; buffer=new uint8_t [info.width* info.height*2]; bufferin=new uint8_t [info.width* info.height*2]; // we decode 5 frames..should be enough to get an opinion for(uint32_t i=0;i<13;i++) //10 { flags=flag2=0; vid->_aviheader->getFrameNoAlloc (i, bufferin, &len, &flags); if(!vid->decoder->uncompress( (uint8_t *)bufferin,(uint8_t *)buffer,len,&flag2 )) { err++; printf("\n ***oops***\n"); } if(i<5) continue; // ignore the first frames // check if it is a b-frame //printf(" %lu : %lu \n",i,flag2); if(flag2 & AVI_B_FRAME) { printf(" %lu is a b frame\n",i); bframe=1; vid->_aviheader->getFlags(i,&flags); if(!(flags & AVI_B_FRAME)) bconsistency=0; else printf("\n and flags is ok\n"); } } delete [] buffer; delete [] bufferin; if(bframe) { printf("\n Mmm this appear to have b-frame...\n"); if(bconsistency) { printf("\n And the index is ok\n"); vid->_forwardFrame=new uint8_t [720*576*3]; vid->_reorderReady=vid->_aviheader->reorder(); if(vid->_reorderReady) { printf("\n Frames re-ordered, B-frame friendly now :)\n"); aprintf(" we had :%lu",info.nb_frames); // update nb frame in case we dropped some _total_frames -= info.nb_frames; _videos[_nb_video-1]._aviheader->getVideoInfo (&info); aprintf(" we have now :%lu",info.nb_frames); _total_frames += info.nb_frames; _videos[_nb_video-1]._nb_video_frames = info.nb_frames; } else { printf("\n Frames not re-ordered, expect problem with b-frames\n"); } } else { printf("\n But the index is not up to date \n"); uint32_t ispacked=0; // If it is Divx 5.0.xxx use divx decoder if(fourCC::check(info.fcc,(uint8_t *)"DX50") || fourCC::check(info.fcc,(uint8_t *)"XVID" )) { //if(vid->decoder->isDivxPacked()) if(vid->decoder->isDivxPacked()) { // can only unpack avi if(!count && type==AVI_FileType) { if(GUI_Question("It looks like Vop packed divx.\nDo you want me to unpack it ?")) { OpenDMLHeader *dml=NULL; count++; dml=(OpenDMLHeader *)vid->_aviheader; // Can we repack it ? if(dml->unpackPacked()) goto TryAgain; GUI_Alert("Could not unpack it\n, using backup decoder= not frame accurate."); } } #if 1 //def USE_DIVX printf("\n Switching codec...\n"); delete vid->decoder; vid->decoder=getDecoderVopPacked(info.fcc, info.width, info.height,0,NULL); ispacked=1; #else GUI_Alert("Troubles ahead : This a vop packed avi.."); #endif } } // else warn user if(!ispacked) GUI_Alert("\n Please used Misc->Rebuild frame for BFrames!"); } } else { printf("Seems it does not contain B-frames...\n"); } printf(" End of B-frame check\n"); } return 1; }