diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index d25fe69..4d11b8a 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -316,22 +316,19 @@ Bool VideoSubWindow::loadFile( QString cFilename, Bool bForceDialog ) } } - try - { - m_pCurrStream->open( cFilename.toStdString(), Width, Height, InputFormat, BitsPel, Endianness, FrameRate, true ); - } - catch( ... ) - { - if( formatDialog.runConfigureFormatDialog( QFileInfo( cFilename ).fileName(), Width, Height, - InputFormat, BitsPel, Endianness, - FrameRate ) == QDialog::Rejected ) - { - return false; - } - m_pCurrStream->open( cFilename.toStdString(), Width, Height, InputFormat, BitsPel, - Endianness, - FrameRate, true ); - } + try + { + m_pCurrStream->open( cFilename.toStdString(), Width, Height, InputFormat, BitsPel, Endianness, FrameRate, true ); + } + catch( ... ) + { + if( formatDialog.runConfigureFormatDialog( QFileInfo( cFilename ).fileName(), Width, Height, InputFormat, BitsPel, Endianness, FrameRate ) == + QDialog::Rejected ) + { + return false; + } + m_pCurrStream->open( cFilename.toStdString(), Width, Height, InputFormat, BitsPel, Endianness, FrameRate, true ); + } m_sStreamInfo.m_cFilename = cFilename; m_sStreamInfo.m_uiWidth = Width; @@ -433,7 +430,8 @@ Bool VideoSubWindow::guessFormat( QString filename, UInt& rWidth, UInt& rHeight, { return false; } - if( !fileExtension.compare( "yuv", Qt::CaseInsensitive ) || !fileExtension.compare( "rgb", Qt::CaseInsensitive ) || !fileExtension.compare( "gray", Qt::CaseInsensitive ) ) + if( !fileExtension.compare( "yuv", Qt::CaseInsensitive ) || !fileExtension.compare( "rgb", Qt::CaseInsensitive ) || + !fileExtension.compare( "gray", Qt::CaseInsensitive ) ) { bGuessed = false; // Guess pixel format diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 99da94a..63be184 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -273,14 +273,15 @@ Bool PlaYUVerStream::open( String filename, UInt width, UInt height, Int input_f if( !m_pcHandler->openHandler( m_cFilename, m_bIsInput ) ) { close(); - throw PlaYUVerFailure( "PlaYUVerStream", "Cannot open file " + m_cFilename ); + throw PlaYUVerFailure( "PlaYUVerStream", + "Cannot open stream " + m_cFilename + " with the " + String( m_pcHandler->m_pchHandlerName ) + " handler" ); return m_bInit; } if( m_pcHandler->m_uiWidth <= 0 || m_pcHandler->m_uiHeight <= 0 || m_pcHandler->m_iPixelFormat < 0 ) { close(); - throw PlaYUVerFailure( "PlaYUVerStream", "Incorrect configuration" ); + throw PlaYUVerFailure( "PlaYUVerStream", "Incorrect configuration: width, height or pixel format" ); return m_bInit; } @@ -314,7 +315,7 @@ Bool PlaYUVerStream::open( String filename, UInt width, UInt height, Int input_f if( !m_pcHandler->configureBuffer( m_frameBuffer->current() ) ) { close(); - throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated memory" ); + throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated buffers" ); return m_bInit; } @@ -332,7 +333,8 @@ Bool PlaYUVerStream::reload() m_pcHandler->closeHandler(); if( !m_pcHandler->openHandler( m_cFilename, m_bIsInput ) ) { - throw PlaYUVerFailure( "PlaYUVerStream", "Cannot open file" ); + throw PlaYUVerFailure( "PlaYUVerStream", + "Cannot open stream " + m_cFilename + " with the " + String( m_pcHandler->m_pchHandlerName ) + " handler" ); } m_pcHandler->setBytesPerFrame( m_frameBuffer->current()->getBytesPerFrame() ); m_uiTotalFrameNum = m_pcHandler->calculateFrameNumber(); @@ -431,7 +433,7 @@ Void PlaYUVerStream::loadAll() catch( PlaYUVerFailure& e ) { close(); - throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated frame buffer" ); + throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated frame buffer for the whole stream" ); } seekInput( 0 ); @@ -476,7 +478,7 @@ Bool PlaYUVerStream::readFrame( PlaYUVerFrame* frame ) if( !m_pcHandler->read( frame ) ) { - throw PlaYUVerFailure( "PlaYUVerStream", "Cannot read file" ); + throw PlaYUVerFailure( "PlaYUVerStream", "Cannot read frame from stream" ); return false; } return true; @@ -491,7 +493,7 @@ Void PlaYUVerStream::writeFrame( PlaYUVerFrame* pcFrame ) { if( !m_pcHandler->write( pcFrame ) ) { - throw PlaYUVerFailure( "PlaYUVerStream", "Cannot write into the file" ); + throw PlaYUVerFailure( "PlaYUVerStream", "Cannot write frame into the stream" ); } return; } diff --git a/lib/PlaYUVerStreamHandlerIf.h b/lib/PlaYUVerStreamHandlerIf.h index 7b06e94..5ed8489 100644 --- a/lib/PlaYUVerStreamHandlerIf.h +++ b/lib/PlaYUVerStreamHandlerIf.h @@ -98,6 +98,7 @@ public: String getCodecName() { return m_strCodecName; } protected: + const Char* m_pchHandlerName; Bool m_bIsInput; UInt64 m_uiCurrFrameFileIdx; String m_cFilename; diff --git a/lib/StreamHandlerLibav.cpp b/lib/StreamHandlerLibav.cpp index b1a19d2..25e15cc 100644 --- a/lib/StreamHandlerLibav.cpp +++ b/lib/StreamHandlerLibav.cpp @@ -54,7 +54,10 @@ std::vector StreamHandlerLibav::supportedWriteFormats() END_REGIST_PLAYUVER_SUPPORTED_FMT; } -StreamHandlerLibav::StreamHandlerLibav() {} +StreamHandlerLibav::StreamHandlerLibav() +{ + m_pchHandlerName = "FFmpeg"; +} Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput ) { @@ -69,20 +72,17 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput ) AVDictionary* format_opts = NULL; - // if( width > 0 && height > 0 ) - // { - // Char aux_string[10]; - // sprintf( aux_string, "%dx%d", width, height ); - // av_dict_set( &format_opts, "video_size", aux_string, 0 ); - // } - - // Int ffmpeg_pel_format = - // g_PlaYUVerPixFmtDescriptorsList[pixel_format].ffmpegPelFormat; - // if( ffmpeg_pel_format >= 0 ) - // { - // av_dict_set( &format_opts, "pixel_format", av_get_pix_fmt_name( - // AVPixelFormat( ffmpeg_pel_format ) ), 0 ); - // } + // if( m_uiWidth > 0 && m_uiHeight > 0 ) + // { + // Char aux_string[10]; + // sprintf( aux_string, "%dx%d", m_uiWidth, m_uiHeight ); + // av_dict_set( &format_opts, "video_size", aux_string, 0 ); + // } + // Int ffmpeg_pel_format = g_PlaYUVerPixFmtDescriptorsList[m_iPixelFormat].ffmpegPelFormat; + // if( ffmpeg_pel_format >= 0 ) + // { + // av_dict_set( &format_opts, "pix_fmt", av_get_pix_fmt_name( AVPixelFormat( ffmpeg_pel_format ) ), 0 ); + // } // Register all components of FFmpeg av_register_all(); @@ -125,7 +125,7 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput ) m_cCodedCtx = avcodec_alloc_context3( dec ); - if( avcodec_open2( m_cCodedCtx, dec, NULL ) < 0 ) + if( avcodec_open2( m_cCodedCtx, dec, &format_opts ) < 0 ) { printf( "Failed to open %s codec\n", av_get_media_type_string( AVMEDIA_TYPE_VIDEO ) ); return false; @@ -218,8 +218,8 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput ) // m_pcPacket = av_packet_alloc(); /* initialize packet, set data to NULL, let the demuxer fill it */ av_init_packet( &m_cPacket ); - m_cPacket.data = NULL; - m_cPacket.size = 0; + // m_cPacket.data = NULL; + // m_cPacket.size = 0; m_bHasStream = true; return true; @@ -272,56 +272,42 @@ UInt64 StreamHandlerLibav::calculateFrameNumber() return num_frames; } -Int StreamHandlerLibav::decodeVideoPkt( Bool& bGotFrame ) -{ - Int iRet; - - iRet = avcodec_send_packet( m_cCodedCtx, &m_cPacket ); - if( iRet < 0 ) - { - return iRet; - } - - while( iRet >= 0 ) - { - iRet = avcodec_receive_frame( m_cCodedCtx, m_cFrame ); - if( iRet == AVERROR( EAGAIN ) || iRet == AVERROR_EOF ) - return 0; - else if( iRet < 0 ) - return iRet; - } - return 0; -} - Bool StreamHandlerLibav::read( PlaYUVerFrame* pcFrame ) { Bool bGotFrame = false; + Bool bErrors = false; + Bool bReadPkt = false; Int iRet; - decodeVideoPkt( bGotFrame ); - - /* read frames from the file */ - while( !bGotFrame && ( av_read_frame( m_cFmtCtx, &m_cPacket ) >= 0 ) ) + while( !bGotFrame && !bErrors ) { - AVPacket orig_pkt = m_cPacket; - do + iRet = avcodec_receive_frame( m_cCodedCtx, m_cFrame ); + if( iRet > 0 ) { - iRet = decodeVideoPkt( bGotFrame ); - if( iRet < 0 ) - break; + bGotFrame = true; + break; + } + else if( iRet == AVERROR( EAGAIN ) || iRet == AVERROR_EOF ) + bReadPkt = true; + else if( iRet < 0 ) + return false; - m_cPacket.data += iRet; - m_cPacket.size -= iRet; - } while( m_cPacket.size > 0 ); - av_packet_unref( &orig_pkt ); - } - - if( !bGotFrame ) - { - do + if( iRet > 0 ) { - iRet = decodeVideoPkt( bGotFrame ); - } while( iRet >= 0 && !bGotFrame ); + bGotFrame = true; + break; + } + if( bReadPkt ) + { + bReadPkt = false; + av_packet_unref( &m_cPacket ); + if( ( iRet = av_read_frame( m_cFmtCtx, &m_cPacket ) ) < 0 ) + return false; + if( m_cPacket.stream_index == m_iStreamIdx ) + // iRet = avcodec_send_packet( m_cCodedCtx, &m_cPacket ); + if( ( iRet = avcodec_send_packet( m_cCodedCtx, &m_cPacket ) ) < 0 ) + return iRet; + } } if( bGotFrame ) diff --git a/lib/StreamHandlerLibav.h b/lib/StreamHandlerLibav.h index 06753be..3a2c15f 100644 --- a/lib/StreamHandlerLibav.h +++ b/lib/StreamHandlerLibav.h @@ -87,8 +87,6 @@ private: UInt64 m_uiSecs; UInt64 m_uiMicroSec; - - Int decodeVideoPkt( Bool& gotFrame ); }; #endif // __STREAMHANDLERLIBAV_H__ diff --git a/lib/StreamHandlerOpenCV.cpp b/lib/StreamHandlerOpenCV.cpp index 01317f4..0a23977 100644 --- a/lib/StreamHandlerOpenCV.cpp +++ b/lib/StreamHandlerOpenCV.cpp @@ -58,6 +58,7 @@ std::vector StreamHandlerOpenCV::supportedWriteFormats( StreamHandlerOpenCV::StreamHandlerOpenCV() { + m_pchHandlerName = "OpenCV"; pcVideoCapture = NULL; } diff --git a/lib/StreamHandlerPortableMap.h b/lib/StreamHandlerPortableMap.h index ec1e711..628a88a 100644 --- a/lib/StreamHandlerPortableMap.h +++ b/lib/StreamHandlerPortableMap.h @@ -35,7 +35,7 @@ class StreamHandlerPortableMap : public PlaYUVerStreamHandlerIf REGISTER_STREAM_HANDLER( StreamHandlerPortableMap ) public: - StreamHandlerPortableMap() {} + StreamHandlerPortableMap() { m_pchHandlerName = "PortableMaps"; } ~StreamHandlerPortableMap() {} Bool openHandler( String strFilename, Bool bInput ); Void closeHandler(); diff --git a/lib/StreamHandlerRaw.h b/lib/StreamHandlerRaw.h index c098aa6..5ccc928 100644 --- a/lib/StreamHandlerRaw.h +++ b/lib/StreamHandlerRaw.h @@ -40,7 +40,7 @@ private: FILE* m_pFile; /**< The input file pointer >*/ public: - StreamHandlerRaw() {} + StreamHandlerRaw() { m_pchHandlerName = "RawVideo"; } ~StreamHandlerRaw() {} Bool openHandler( String strFilename, Bool bInput ); Void closeHandler();