From ebd9fa46fe6c2ab3358cf4e2cb1c3f4b7b8e5175 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 23 Mar 2017 02:23:48 +0000 Subject: [PATCH] Changes in the libav handle --- lib/StreamHandlerLibav.cpp | 124 +++++++++++++++---------------------- lib/StreamHandlerLibav.h | 4 +- 2 files changed, 53 insertions(+), 75 deletions(-) diff --git a/lib/StreamHandlerLibav.cpp b/lib/StreamHandlerLibav.cpp index aa373b3..1da4b03 100644 --- a/lib/StreamHandlerLibav.cpp +++ b/lib/StreamHandlerLibav.cpp @@ -35,12 +35,12 @@ std::vector StreamHandlerLibav::supportedReadFormats() REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Joint Photographic Experts Group", "jpg" ); REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Windows Bitmap", "bmp" ); REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Tagged Image File Format", "tiff" ); - // REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Audio video interleaved", "avi" ); - // REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Windows media video", "wmv" ); - // REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "MPEG4", "mp4" ); - // REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Matroska Multimedia Container", "mkv" ); - // REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "H.264 streams", "h264" ); - // REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "HEVC streams", "hevc" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Audio video interleaved", "avi" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Windows media video", "wmv" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "MPEG4", "mp4" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Matroska Multimedia Container", "mkv" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "H.264 streams", "h264" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "HEVC streams", "hevc" ); END_REGIST_PLAYUVER_SUPPORTED_FMT; } @@ -50,49 +50,13 @@ std::vector StreamHandlerLibav::supportedWriteFormats() END_REGIST_PLAYUVER_SUPPORTED_FMT; } -static int open_codec_context( int* stream_idx, AVFormatContext* m_cFmtCtx, enum AVMediaType type ) -{ - int ret; - AVStream* st; - AVCodecContext* dec_ctx = NULL; - AVCodec* dec = NULL; - - ret = av_find_best_stream( m_cFmtCtx, type, -1, -1, NULL, 0 ); - if( ret < 0 ) - { - return ret; - } - else - { - *stream_idx = ret; - st = m_cFmtCtx->streams[*stream_idx]; - - /* find decoder for the stream */ - dec_ctx = st->codec; - dec = avcodec_find_decoder( dec_ctx->codec_id ); - if( !dec ) - { - printf( "Failed to find %s codec\n", av_get_media_type_string( type ) ); - return ret; - } - - if( ( ret = avcodec_open2( dec_ctx, dec, NULL ) ) < 0 ) - { - printf( "Failed to open %s codec\n", av_get_media_type_string( type ) ); - return ret; - } - } - - return 0; -} - Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput ) { const char* filename = strFilename.c_str(); m_cFmtCtx = NULL; - m_cCodecCtx = NULL; m_cStream = NULL; + // video_dst_data[0] = NULL; // video_dst_data[1] = NULL; // video_dst_data[2] = NULL; @@ -133,28 +97,42 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput ) return false; } - if( open_codec_context( &m_iStreamIdx, m_cFmtCtx, AVMEDIA_TYPE_VIDEO ) >= 0 ) + AVMediaType mediaType; + + int stream_idx = av_find_best_stream( m_cFmtCtx, mediaType, -1, -1, NULL, 0 ); + if( stream_idx < 0 ) { - m_cStream = m_cFmtCtx->streams[m_iStreamIdx]; - m_cCodecCtx = m_cStream->codec; - - // /* allocate image where the decoded image will be put */ - // ret = av_image_alloc( video_dst_data, video_dst_linesize, m_cCodecCtx->width, m_cCodecCtx->height, - // m_cCodecCtx->pix_fmt, 1 ); - // if( ret < 0 ) - // { - // //qDebug( ) << " Could not allocate raw video buffer !!!" << endl; - // closeAvFormat(); - // return false; - // } - // video_dst_bufsize = ret; - - m_uiFrameBufferSize = av_image_get_buffer_size( m_cCodecCtx->pix_fmt, m_cCodecCtx->width, m_cCodecCtx->height, 1 ); - getMem1D( &m_pchFrameBuffer, m_uiFrameBufferSize ); + return false; } + m_iStreamIdx = stream_idx; + + m_cStream = m_cFmtCtx->streams[m_iStreamIdx]; + + /* find decoder for the stream */ + AVCodecParameters* codec_param = m_cStream->codecpar; + + // dec = avcodec_find_decoder( dec_ctx->codec_id ); + AVCodec* dec = avcodec_find_decoder( codec_param->codec_id ); + if( !dec ) + { + printf( "Failed to find %s codec\n", av_get_media_type_string( mediaType ) ); + return false; + } + + m_cCodedCtx = avcodec_alloc_context3( dec ); + + if( avcodec_open2( m_cCodedCtx, dec, NULL ) < 0 ) + { + printf( "Failed to open %s codec\n", av_get_media_type_string( mediaType ) ); + return false; + } + + m_uiFrameBufferSize = av_image_get_buffer_size( AVPixelFormat( codec_param->format ), codec_param->width, codec_param->height, 1 ); + getMem1D( &m_pchFrameBuffer, m_uiFrameBufferSize ); + m_strFormatName = uppercase( strFilename.substr( strFilename.find_last_of( "." ) + 1 ) ); - const char* name = avcodec_get_name( m_cCodecCtx->codec_id ); + const char* name = avcodec_get_name( m_cStream->codecpar->codec_id ); // sprintf( m_acCodecName, "%s", name ); m_strCodecName = name; @@ -167,12 +145,12 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput ) #endif else if( m_cStream->time_base.den && m_cStream->time_base.num ) fr = 1 / av_q2d( m_cStream->time_base ); - else if( m_cStream->codec->time_base.den && m_cStream->codec->time_base.num ) - fr = 1 / av_q2d( m_cStream->codec->time_base ); + else if( m_cCodedCtx->time_base.den && m_cCodedCtx->time_base.num ) + fr = 1 / av_q2d( m_cCodedCtx->time_base ); m_dFrameRate = fr; - Int pix_fmt = m_cCodecCtx->pix_fmt; + Int pix_fmt = m_cStream->codecpar->format; // Set bits per pixel to default (8 bits) m_uiBitsPerPixel = 8; @@ -202,8 +180,8 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput ) pix_fmt = AV_PIX_FMT_GRAY8; } - m_uiWidth = m_cCodecCtx->width; - m_uiHeight = m_cCodecCtx->height; + m_uiWidth = m_cStream->codecpar->width; + m_uiHeight = m_cStream->codecpar->height; m_iPixelFormat = PlaYUVerFrame::NO_FMT; for( Int i = 0; i < PlaYUVerFrame::NUMBER_PEL_FORMATS; i++ ) @@ -254,8 +232,8 @@ Void StreamHandlerLibav::closeHandler() { if( m_bHasStream ) { - if( m_cCodecCtx ) - avcodec_close( m_cCodecCtx ); + if( m_cCodedCtx ) + avcodec_close( m_cCodedCtx ); if( m_cFmtCtx ) avformat_close_input( &m_cFmtCtx ); @@ -302,7 +280,7 @@ Bool StreamHandlerLibav::decodeVideoPkt() Int decResult; if( pkt.stream_index == m_iStreamIdx ) { - decResult = avcodec_decode_video2( m_cCodecCtx, m_cFrame, &got_frame, &pkt ); + decResult = avcodec_decode_video2( m_cCodedCtx, m_cFrame, &got_frame, &pkt ); if( decResult < 0 ) { fprintf( stderr, "Error decoding video frame\n" ); @@ -350,11 +328,9 @@ Bool StreamHandlerLibav::read( PlaYUVerFrame* pcFrame ) if( bGotFrame ) { - // av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, m_cFrame->data, m_cFrame->linesize, - // m_cCodecCtx->pix_fmt, m_cCodecCtx->width, - // m_cCodecCtx->height, 1 ); - av_image_copy_to_buffer( m_pStreamBuffer, m_uiFrameBufferSize, m_cFrame->data, m_cFrame->linesize, - m_cCodecCtx->pix_fmt, m_cCodecCtx->width, m_cCodecCtx->height, 1 ); + AVCodecParameters* codec_param = m_cStream->codecpar; + av_image_copy_to_buffer( m_pStreamBuffer, m_uiFrameBufferSize, m_cFrame->data, m_cFrame->linesize, AVPixelFormat( codec_param->format ), + codec_param->width, codec_param->height, 1 ); if( orig_pkt.size ) av_free_packet( &orig_pkt ); diff --git a/lib/StreamHandlerLibav.h b/lib/StreamHandlerLibav.h index 6e1934d..b94965e 100644 --- a/lib/StreamHandlerLibav.h +++ b/lib/StreamHandlerLibav.h @@ -78,9 +78,11 @@ class StreamHandlerLibav : public PlaYUVerStreamHandlerIf private: AVFormatContext* m_cFmtCtx; - AVCodecContext* m_cCodecCtx; AVStream* m_cStream; Int m_iStreamIdx; + + AVCodecContext* m_cCodedCtx; + AVFrame* m_cFrame; AVPacket pkt;