int TTCutListData::addItem(int cutInIndex, int cutOutIndex, TTAVData* avData) { TTVideoStream* mpegStream = avData->videoStream(); QTime cutInTime = mpegStream->frameTime(cutInIndex); QTime cutOutTime = mpegStream->frameTime(cutOutIndex); int numFrames = cutOutIndex-cutInIndex; if ( numFrames < 0 ) numFrames *= -1; QTime cutLengthTime = ttFramesToTime( numFrames, mpegStream->frameRate() ); qint64 lengthBytes = mpegStream->frameOffset(cutOutIndex) - mpegStream->frameOffset(cutInIndex); if ( lengthBytes < 0 ) lengthBytes *= -1; log->infoMsg(oName, "Insert cut position"); log->infoMsg(oName, "------------------------------------------"); log->infoMsg(oName, "Cut-In : %s (%d)", qPrintable(cutInTime.toString("hh:mm:ss.zzz")), cutInIndex); log->infoMsg(oName, "Cut-Out: %s (%d)", qPrintable(cutOutTime.toString("hh:mm:ss.zzz")), cutOutIndex); log->infoMsg(oName, "Length : %s (%lld)",qPrintable(cutLengthTime.toString("hh:mm:ss.zzz")), lengthBytes); log->infoMsg(oName, "------------------------------------------"); TTCutListDataItem item(cutInIndex, cutInTime, cutOutIndex, cutOutTime, cutLengthTime, lengthBytes, avData); item.cutInFrameType = mpegStream->frameType(cutInIndex); item.cutOutFrameType = mpegStream->frameType(cutOutIndex); data.append(item); // return current index return data.count()-1; }
//! Update an existing cut list data item int TTCutListData::updateItem( int index, int cutInIndex, int cutOutIndex) { TTVideoStream* mpegStream = data.at(index).getAVData()->videoStream(); QTime cutInTime = mpegStream->frameTime(cutInIndex); QTime cutOutTime = mpegStream->frameTime(cutOutIndex); int numFrames = cutOutIndex-cutInIndex; if ( numFrames < 0 ) numFrames *= -1; QTime cutLengthTime = ttFramesToTime( numFrames, mpegStream->frameRate() ); qint64 lengthBytes = mpegStream->frameOffset(cutOutIndex) - mpegStream->frameOffset(cutInIndex); if ( lengthBytes < 0 ) lengthBytes *= -1; //log->infoMsg(oName, "Update cut position at index: %d", index); //log->infoMsg(oName, "------------------------------------------"); //log->infoMsg(oName, "Cut-In : %s (%d)", qPrintable(cutInTime.toString("hh:mm:ss.zzz")), cutInIndex); //log->infoMsg(oName, "Cut-Out: %s (%d)", qPrintable(cutOutTime.toString("hh:mm:ss.zzz")), cutOutIndex); //log->infoMsg(oName, "Length : %s (%lld)",qPrintable(cutLengthTime.toString("hh:mm:ss.zzz")), lengthBytes); //log->infoMsg(oName, "------------------------------------------"); //TTCutListDataItem item = at(index); data[index].cutInIndex = cutInIndex; data[index].cutInTime = cutInTime; data[index].cutOutIndex = cutOutIndex; data[index].cutOutTime = cutOutTime; data[index].cutLengthTime = cutLengthTime; data[index].cutLengthBytes = lengthBytes; data[index].cutInFrameType = mpegStream->frameType(cutInIndex); data[index].cutOutFrameType = mpegStream->frameType(cutOutIndex); // return current item count return data.count(); }
/* //////////////////////////////////////////////////////////////////////////// * Update the current frame information */ void TTMpeg2MainWnd::updateFrameInfo(int indexPos) { totalTime = ttFramesToTime(videoIndexList->count(), 25.0); TTPicturesHeader* currentPicture = (TTPicturesHeader*)videoHeaderList->at( videoIndexList->headerListIndex(indexPos)); frameInfo->setFrameOffset(videoHeaderList->at( videoIndexList->headerListIndex(indexPos))->headerOffset()); frameInfo->setNumDisplayOrder(videoIndexList->displayOrder(indexPos), currentPicture->temporal_reference); frameInfo->setNumStreamOrder(videoIndexList->streamOrder(indexPos)); frameInfo->setFrameType(videoIndexList->videoIndexAt(indexPos)->picture_coding_type); frameInfo->setFrameTime(ttFramesToTime(videoIndexList->displayOrder(indexPos), 25.0), totalTime); frameInfo->setFrameSize((long)videoIndexList->frameSize(indexPos)); frameInfo->setGOPNumber(videoIndexList->gopNumber(indexPos), currentPicture->temporal_reference); }
void TTMpeg2MainWnd::showFrame( uint f_index ) { TTPicturesHeader* current_picture; TTSequenceHeader* current_sequence; try { frameInfo->setFrameOffset( header_list->at(index_list->headerListIndex(f_index))->headerOffset()); current_picture = (TTPicturesHeader*)header_list->at(index_list->headerListIndex(f_index)); //frameInfo->setNumDisplayOrder( index_list->displayOrder(f_index)); frameInfo->setNumDisplayOrder( index_list->displayOrder(f_index), current_picture->temporal_reference); frameInfo->setNumStreamOrder( index_list->streamOrder(f_index)); //frameInfo->setNumStreamOrder( index_list->streamOrder(f_index), // current_picture->temporal_reference); frameInfo->setFrameType( index_list->videoIndexAt(f_index)->picture_coding_type ); frameInfo->setFrameTime( ttFramesToTime(index_list->displayOrder(f_index),25.0), total_time); frameInfo->setFrameSize( (long)index_list->frameSize( f_index ) ); //frameInfo->setGOPNumber( index_list->gopNumber( f_index ) ); frameInfo->setGOPNumber( index_list->gopNumber( f_index ), current_picture->temporal_reference); //current_sequence = header_list->sequenceHeaderAt( index_list->sequenceIndex( f_index ) ); current_sequence = video_stream->currentSequenceHeader(); setBitrate( current_sequence->bit_rate_value ); setFramerate( current_sequence->frame_rate_code ); setPictureWidth( current_sequence->horizontal_size_value ); setPictureHeight( current_sequence->vertical_size_value ); mpeg2_window->moveToVideoFrame( f_index ); } catch(TTStreamEOFException) { qDebug("stream EOF exception..."); } catch(TTListIndexException) { qDebug("index list exception..."); } catch(...) { qDebug("unknown exception..."); } }
void TTVideoFileInfo::setVideoInfo( TTVideoStream* pVideoStream ) { QString szTemp; TTSequenceHeader* currentSequence = pVideoStream->currentSequenceHeader(); if (currentSequence == NULL) return; int idx = videoListData.indexOf(pVideoStream); if ( -1 == idx ) return; QTreeWidgetItem* treeItem = videoListView->topLevelItem( idx ); if ( 0 == treeItem ) return; // video file name treeItem->setText( 0, pVideoStream->fileName() ); // video length int numFrames = pVideoStream->frameCount(); QTime time = ttFramesToTime( numFrames, pVideoStream->frameRate() ); szTemp.sprintf("%s (%d)", qPrintable(time.toString("hh:mm:ss.zzz")), numFrames); treeItem->setText( 1, szTemp ); // set video resolution szTemp.sprintf("%dx%d",pVideoStream->currentSequenceHeader()->horizontalSize(), pVideoStream->currentSequenceHeader()->verticalSize()); treeItem->setText( 2, szTemp ); // set aspect treeItem->setText( 3, pVideoStream->currentSequenceHeader()->aspectRatioText() ); // set framerate treeItem->setText( 4, pVideoStream->currentSequenceHeader()->frameRateText() ); // set bitrate szTemp.sprintf("%4.1f kBit/s", pVideoStream->currentSequenceHeader()->bitRateKbit()); treeItem->setText( 5, szTemp ); // set VBV buffer size szTemp.sprintf("%d kWords", pVideoStream->currentSequenceHeader()->vbvBufferSize()); treeItem->setText( 6, szTemp ); }
/* //////////////////////////////////////////////////////////////////////////// * Update the video file information */ void TTMpeg2MainWnd::updateVideoFileInfo(TTMpeg2VideoStream* mpegStream) { videoFileInfo->setFileName(mpegStream->fileInfo()->fileName()); videoFileInfo->setLength( ttFramesToTime(mpegStream->frameCount(), mpegStream->frameRate()), mpegStream->frameCount()); videoFileInfo->setResolution( mpegStream->currentSequenceHeader()->horizontalSize(), mpegStream->currentSequenceHeader()->verticalSize()); videoFileInfo->setAspect( mpegStream->currentSequenceHeader()->aspectRatioText()); videoFileInfo->setFrameRate( mpegStream->currentSequenceHeader()->frameRateText()); videoFileInfo->setBitRate( mpegStream->currentSequenceHeader()->bitRateKbit()); videoFileInfo->setVBVBuffer( mpegStream->currentSequenceHeader()->vbvBufferSize()); }
void TTVideoFileInfo::setVideoInfo( TTMpeg2VideoStream* mpeg2Stream ) { QString szTemp; TTSequenceHeader* currentSequence = mpeg2Stream->currentSequenceHeader(); if (currentSequence == NULL) return; // video file name infoVideoFileName->setText(mpeg2Stream->fileName()); // video length int numFrames = mpeg2Stream->frameCount(); QTime time = ttFramesToTime( numFrames, mpeg2Stream->frameRate() ); szTemp.sprintf("%s (%d)", qPrintable(time.toString("hh:mm:ss.zzz")), numFrames); infoVideoLength->setText( szTemp ); // set video resolution szTemp.sprintf("%dx%d",mpeg2Stream->currentSequenceHeader()->horizontalSize(), mpeg2Stream->currentSequenceHeader()->verticalSize()); infoVideoResolution->setText( szTemp ); // set aspect infoVideoAspectRatio->setText(mpeg2Stream->currentSequenceHeader()->aspectRatioText()); // set framerate infoVideoFramerate->setText(mpeg2Stream->currentSequenceHeader()->frameRateText()); // set bitrate szTemp.sprintf("%4.1f kBit/s", mpeg2Stream->currentSequenceHeader()->bitRateKbit()); infoVideoBitrate->setText( szTemp ); // set VBV buffer size szTemp.sprintf("%d kWords", mpeg2Stream->currentSequenceHeader()->vbvBufferSize()); infoVideoBuffer->setText( szTemp ); }
void TTMpeg2MainWnd::analyzeMpegStream( ) { uint max_print_frames = 2500; uint i; long num_frames = 0; QString strHeaderType; QString strHeaderOffset; QString strPictureType; QString strTempRef; QString strDOrder; QString strSOrder; QString strTime; QString strOut; Q3ListViewItem* item; TTPicturesHeader* current_picture; uint num_index; double read_percent; // TODO: use QTime for timing purpose (have better resolution) time_t seconds_start; time_t seconds_end; num_frames = 0; // start time seconds_start = time( NULL ); // open the mpeg2 stream if ( !file_name.isEmpty() ) { // get the stream type and create according stream-object video_type = new TTVideoType( file_name ); // test audio_type = new TTAudioType( "rbb_test.mpa" ); if ( audio_type->avStreamType() == TTAVTypes::mpeg_audio ) { qDebug( "%sfound mpeg audio stream",cName ); TTMPEGAudioStream* audio_stream = (TTMPEGAudioStream*)audio_type->createAudioStream(); uint h_count = audio_stream->createHeaderList(); } if ( video_type->avStreamType() == TTAVTypes::mpeg2_demuxed_video ) video_stream = (TTMpeg2VideoStream*)video_type->createVideoStream(); else { qDebug("%swrong video type",cName); return; } progress_bar = new TTProgressBar( this ); video_stream->setProgressBar( progress_bar ); progress_bar->show(); qApp->processEvents(); // create header- and index-list video_stream->createHeaderList(); num_index = video_stream->createIndexList(); qDebug("%snum index: %d",cName,num_index); // get pointer to the lists index_list = video_stream->indexList(); header_list = video_stream->headerList(); // get pointer to stream mpeg2_stream = video_stream->streamBuffer(); // sort frame index list to display (decoder) order index_list->sortDisplayOrder(); // get end time seconds_end = time( NULL ); setReadTime( diffTime( seconds_start, seconds_end ) ); // print out statistic informations // get stream length and set label text setFileLength( mpeg2_stream->streamLength() ); read_percent = (double)mpeg2_stream->readCount()/(double)mpeg2_stream->streamLength()*100.0; setReadOps( mpeg2_stream->readCount(), read_percent ); setFillOps( mpeg2_stream->fillCount() ); // print out the number of frames in stream num_frames = index_list->count(); total_time = ttFramesToTime( num_frames, 25.0 ); setNumFramesTotal( num_frames ); setNumIFrames( index_list->numIFrames() ); setNumPFrames( index_list->numPFrames() ); setNumBFrames( index_list->numBFrames() ); setNumSequence( header_list->numSequenceHeader() ); setNumPicture( header_list->numPictureHeader() ); setNumGOP( header_list->numGopHeader() ); setNumSequenceEnd( header_list->numSequenceEndHeader() ); if ( video_stream->indexList()->count() < max_print_frames ) max_print_frames = video_stream->indexList()->count(); // print out the frame list; print maximal 1000 rows (!) for( i = 0; i < max_print_frames; i++ ) { item = new Q3ListViewItem( lvStreamInfo ); strDOrder.sprintf("%08ld",index_list->displayOrder(i)); strSOrder.sprintf("%08ld",index_list->streamOrder(i)); strHeaderType.sprintf("0x%02x",header_list->at(index_list->headerListIndex(i))->headerType()); strHeaderOffset.sprintf("%12ld",header_list->at(index_list->headerListIndex(i))->headerOffset()); current_picture = (TTPicturesHeader*)header_list->at(index_list->headerListIndex(i)); switch(index_list->videoIndexAt(i)->picture_coding_type) { case(1): strPictureType.sprintf("I-Frame"); strTempRef.sprintf("%04d",current_picture->temporal_reference); break; case(2): strPictureType.sprintf("P-Frame"); strTempRef.sprintf("%04d",current_picture->temporal_reference); break; case(3): strPictureType.sprintf("B-Frame"); strTempRef.sprintf("%04d",current_picture->temporal_reference); break; } num_frames++; item->setText( 0, strHeaderType ); item->setText( 1, strHeaderOffset ); item->setText( 2, strPictureType ); item->setText( 3, strTempRef ); item->setText( 4, strSOrder ); item->setText( 5, strDOrder ); strTime.sprintf("%s,%d",ttFramesToTime(index_list->displayOrder(i),25.0).toString().ascii(), ttFramesToTime(index_list->displayOrder(i),25.0).msec()); item->setText( 6, strTime ); } // delete the progress bar delete progress_bar; video_stream->setProgressBar( NULL ); sbFrames->setMinValue( 0 ); sbFrames->setMaxValue( index_list->count()-1 ); slider_update = false; sbFrames->setValue( 0 ); // show information about the first frame showFrame( 0 ); mpeg2_window->openVideoFile( file_name, index_list, header_list ); mpeg2_window->resize( 400, 350 ); mpeg2_window->moveToFirstFrame( true ); } }
/*! * cutLengthTime */ QTime TTCutItem::cutLengthTime() const { return (avDataItem()->videoStream() != 0) ? ttFramesToTime(cutLengthFrames(), avDataItem()->videoStream()->frameRate()) : QTime(); }
// ----------------------------------------------------------------------------- // Create the preview clips // ----------------------------------------------------------------------------- void TTCutPreview::createPreview( int c_index ) { int i, iPos; QString preview_video_name; QString preview_audio_name; QString preview_mplex_name; QFileInfo preview_video_info; QFileInfo preview_audio_info; QFileInfo preview_mplex_info; QString selectionString; QString mplex_command; QTime preview_time; uint preview_frames; uint start_index; uint end_index; TTCutListData* temp_cut_list; preview_time.setHMS(0,0,0); preview_time = preview_time.addSecs( TTCut::cutPreviewSeconds ); preview_frames = ttTimeToFrames( preview_time, video_stream->frameRate() ) / 2; //qDebug( "%s-----------------------------------------------",c_name ); //qDebug( "%s>>> create cut preview",c_name ); //qDebug( "%s-----------------------------------------------",c_name ); //qDebug( "%scut index : %d",c_name,c_index); // create the cut list for the preview clips createCutPreviewList(); // number of list entrys num_cut_list = preview_cut_list->count(); num_preview = num_cut_list/2+1; //qDebug( "%snum preview : %d",c_name,num_preview); // --------------------------------------------------------------------- // Create video and audio preview clips // --------------------------------------------------------------------- for ( i = 0; i < num_preview; i++ ) { //qDebug( "%s-----------------------------------------------",c_name ); //qDebug( "%scut index : %d / %d",c_name,i,cut_index); temp_cut_list = new TTCutListData(avcut_list->videoStream()); if ( c_index > 0 ) { preview_video_name.sprintf("preview_%03d.m2v",i+1-c_index); preview_audio_name.sprintf("preview_%03d.mpa",i+1-c_index); } else { preview_video_name.sprintf("preview_%03d.m2v",i+1); preview_audio_name.sprintf("preview_%03d.mpa",i+1); } // add temporary path information preview_video_info.setFile( QDir(TTCut::tempDirPath), preview_video_name ); preview_audio_info.setFile( QDir(TTCut::tempDirPath), preview_audio_name ); preview_video_name = preview_video_info.absoluteFilePath(); preview_audio_name = preview_audio_info.absoluteFilePath(); // first cut-in if ( i == 0 ) { //qDebug( "%s(A)first cut %d : %d",c_name,i,i); temp_cut_list->deleteAll(); temp_cut_list->addCutPosition( preview_cut_list->cutInPosAt(i), preview_cut_list->cutOutPosAt(i), i ); if ( c_index == i || c_index+1 == i || c_index < 0 ) { selectionString.sprintf( "Start: %s", qPrintable(ttFramesToTime(preview_cut_list->cutInPosAt(i), video_stream->frameRate()).toString("hh:mm:ss"))); cbCutPreview->addItem( selectionString ); } } // cut i-i if ( num_preview > 1 && i > 0 && i < num_preview-1 ) { iPos = (i-1)*2+1; //qDebug("%s(X)cut %d-%d, i pos : %d",c_name,i,i+1,iPos); temp_cut_list->deleteAll(); temp_cut_list->addCutPosition( preview_cut_list->cutInPosAt(iPos), preview_cut_list->cutOutPosAt(iPos), i ); temp_cut_list->addCutPosition( preview_cut_list->cutInPosAt(iPos+1), preview_cut_list->cutOutPosAt(iPos+1), i ); if ( c_index == i || c_index+1 == i || c_index < 0 ) { start_index = preview_cut_list->cutOutPosAt( iPos ); end_index = preview_cut_list->cutInPosAt( iPos+1 ); selectionString.sprintf( "Cut %d-%d: %s - %s",i,i+1, qPrintable(ttFramesToTime( start_index, video_stream->frameRate()).toString("hh:mm:ss")), qPrintable(ttFramesToTime( end_index, video_stream->frameRate()).toString("hh:mm:ss"))); cbCutPreview->addItem( selectionString ); } } //last cut out if ( i == num_preview-1 ) { iPos = (i-1)*2+1; //qDebug("%s(E)last cut, i pos : %d",c_name,iPos); temp_cut_list->deleteAll(); temp_cut_list->addCutPosition( preview_cut_list->cutInPosAt(iPos), preview_cut_list->cutOutPosAt(iPos), i ); if ( c_index == i || c_index+1 == i || c_index < 0 ) { selectionString.sprintf( "End: %s", qPrintable(ttFramesToTime(preview_cut_list->cutOutPosAt(iPos), video_stream->frameRate()).toString("hh:mm:ss"))); cbCutPreview->addItem( selectionString ); } } // create cut if ( c_index == i || c_index+1 == i || c_index < 0 ) { //qDebug( "%screate preview cut: %d - %s",c_name,i,preview_video_name.ascii()); progress_bar = new TTProgressBar( this ); progress_bar->show(); qApp->processEvents(); video_stream->setProgressBar( progress_bar ); video_cut_stream = new TTFileBuffer( qPrintable(preview_video_name), fm_open_write ); if ( TTCut::numAudioTracks > 0 ) { audio_stream->setProgressBar( progress_bar ); audio_cut_stream = new TTFileBuffer( qPrintable(preview_audio_name), fm_open_write ); } video_stream->cut( video_cut_stream, temp_cut_list ); if ( TTCut::numAudioTracks > 0 ) audio_stream->cut( audio_cut_stream, temp_cut_list ); delete progress_bar; delete video_cut_stream; if ( TTCut::numAudioTracks > 0 ) delete audio_cut_stream; } delete temp_cut_list; // next video preview clip } // end cut video/audio preview clips // multiplex video and audio files give a better result because // video and audio synchronisation is much better progress_bar = new TTProgressBar( this ); progress_bar->show(); progress_bar->setActionText( "Mplexing preview cuts..." ); progress_bar->setTotalSteps( num_preview, 1 ); for ( i = 0; i < num_preview; i++ ) { preview_video_name.sprintf("preview_%03d.m2v",i+1); preview_audio_name.sprintf("preview_%03d.mpa",i+1); preview_mplex_name.sprintf("preview_%03d.mpg",i+1); // add temporary path information preview_video_info.setFile( QDir(TTCut::tempDirPath), preview_video_name ); preview_audio_info.setFile( QDir(TTCut::tempDirPath), preview_audio_name ); preview_mplex_info.setFile( QDir(TTCut::tempDirPath), preview_mplex_name ); preview_video_name = preview_video_info.absoluteFilePath(); preview_audio_name = preview_audio_info.absoluteFilePath(); preview_mplex_name = preview_mplex_info.absoluteFilePath(); // have we audio tracks if ( TTCut::numAudioTracks > 0 ) { mplex_command = "mplex -f 8 -o "; mplex_command += preview_mplex_name; mplex_command += " "; mplex_command += preview_video_name; mplex_command += " "; mplex_command += preview_audio_name; mplex_command += " "; mplex_command += "2>/dev/null"; system( qPrintable(mplex_command) ); } else { mplex_command = "mv "; mplex_command += preview_video_name; mplex_command += " "; mplex_command += preview_mplex_name; mplex_command += " "; mplex_command += "2>/dev/null"; system( qPrintable(mplex_command) ); } log->infoMsg(c_name, "mplex command: %s", mplex_command.toLatin1().constData()); progress_bar->setProgress( i+1 ); } progress_bar->setComplete(); delete progress_bar; delete preview_cut_list; //qDebug( "%s-----------------------------------------------",c_name ); // set the current cut preview to the first cut clip preview_video_name.sprintf("preview_001.mpg"); preview_video_info.setFile( QDir(TTCut::tempDirPath), preview_video_name ); current_video_file = preview_video_info.absoluteFilePath(); }