Refactor and add new support in LibAvHandler

Refactor list of pixel formats
Add support for custom pixel formats by converting it to YUV444p
This commit is contained in:
jfmcarreira committed 2018-02-03 02:12:39 +00:00
1 parent 0b1e4574e6
commit 5b91c91b90
6 files changed
+170 -100

No files matched your search

+8 -8
View File
@@ -51,7 +51,7 @@ std::vector<String> PlaYUVerFrame::supportedPixelFormatListNames()
std::vector<String> formatsList;
for( Int i = 0; i < NUMBER_PEL_FORMATS; i++ )
{
formatsList.push_back( g_PlaYUVerPixFmtDescriptorsList[i].name );
formatsList.push_back( g_PlaYUVerPixFmtDescriptorsMap.at( i ).name );
}
return formatsList;
}
@@ -61,8 +61,8 @@ std::vector<String> PlaYUVerFrame::supportedPixelFormatListNames( Int colorSpace
std::vector<String> formatsList;
for( Int i = 0; i < NUMBER_PEL_FORMATS; i++ )
{
if( g_PlaYUVerPixFmtDescriptorsList[i].colorSpace == colorSpace )
formatsList.push_back( g_PlaYUVerPixFmtDescriptorsList[i].name );
if( g_PlaYUVerPixFmtDescriptorsMap.at( i ).colorSpace == colorSpace )
formatsList.push_back( g_PlaYUVerPixFmtDescriptorsMap.at( i ).name );
}
return formatsList;
}
@@ -71,7 +71,7 @@ Int PlaYUVerFrame::findPixelFormat( const String& name )
{
for( Int i = 0; i < NUMBER_PEL_FORMATS; i++ )
{
if( g_PlaYUVerPixFmtDescriptorsList[i].name == name )
if( g_PlaYUVerPixFmtDescriptorsMap.at( i ).name == name )
return i;
}
return -1;
@@ -180,7 +180,7 @@ struct PlaYUVerFramePrivate
throw PlaYUVerFailure( "PlaYUVerFrame", "Cannot create a PlYUVerFrame of this type" );
}
m_pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[pel_format] );
m_pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsMap.at( pel_format ) );
m_bHasRGBPel = false;
if( m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_GRAY )
@@ -259,7 +259,7 @@ PlaYUVerFrame::PlaYUVerFrame( const PlaYUVerFrame* other )
PlaYUVerFrame::PlaYUVerFrame( const PlaYUVerFrame& other, UInt x, UInt y, UInt width, UInt height )
: d( new PlaYUVerFramePrivate )
{
const PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[other.getPelFormat()] );
const PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsMap.at( other.getPelFormat() ) );
if( pcPelFormat->log2ChromaWidth )
{
if( x % ( 1 << pcPelFormat->log2ChromaWidth ) )
@@ -287,7 +287,7 @@ PlaYUVerFrame::PlaYUVerFrame( const PlaYUVerFrame* other, UInt posX, UInt posY,
if( !other )
return;
const PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[other->getPelFormat()] );
const PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsMap.at( other->getPelFormat() ) );
if( pcPelFormat->log2ChromaWidth )
{
if( posX % ( 1 << pcPelFormat->log2ChromaWidth ) )
@@ -415,7 +415,7 @@ UInt64 PlaYUVerFrame::getBytesPerFrame()
UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelFormat, UInt bitsPixel )
{
const PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[iPixelFormat] );
const PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsMap.at( iPixelFormat ) );
UInt bytesPerPixel = ( bitsPixel - 1 ) / 8 + 1;
UInt64 numberBytes = uiWidth * uiHeight;
if( pcPelFormat->numberChannels > 1 )
+1 -1
View File
@@ -53,8 +53,8 @@ public:
{
NO_FMT = -1,
YUV420p = 0,
YUV444p,
YUV422p,
YUV444p,
YUYV422,
GRAY,
RGBp,
+105 -81
View File
@@ -198,113 +198,137 @@ Void fillARGB32bufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height, UI
}
#endif
const PlaYUVerPixFmtDescriptor g_PlaYUVerPixFmtDescriptorsList[PlaYUVerFrame::NUMBER_PEL_FORMATS] = {
const std::map<int, PlaYUVerPixFmtDescriptor> g_PlaYUVerPixFmtDescriptorsMap = {
{
"YUV420p",
PlaYUVerPixel::COLOR_YUV,
3,
3,
1,
1,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV420P ),
PlaYUVerFrame::YUV420p,
{
{0, 0, 1}, /* Y */
{1, 0, 1}, /* U */
{2, 0, 1}, /* V */
"YUV420p",
PlaYUVerPixel::COLOR_YUV,
3,
3,
1,
1,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV420P ),
{
{0, 0, 1}, /* Y */
{1, 0, 1}, /* U */
{2, 0, 1}, /* V */
},
},
},
{
"YUV422p",
PlaYUVerPixel::COLOR_YUV,
3,
3,
1,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV422P ),
PlaYUVerFrame::YUV422p,
{
{0, 0, 1}, /* Y */
{1, 0, 1}, /* U */
{2, 0, 1}, /* V */
"YUV422p",
PlaYUVerPixel::COLOR_YUV,
3,
3,
1,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV422P ),
{
{0, 0, 1}, /* Y */
{1, 0, 1}, /* U */
{2, 0, 1}, /* V */
},
},
},
{
"YUV444p",
PlaYUVerPixel::COLOR_YUV,
3,
3,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV444P ),
PlaYUVerFrame::YUV444p,
{
{0, 0, 1}, /* Y */
{1, 0, 1}, /* U */
{2, 0, 1}, /* V */
"YUV444p",
PlaYUVerPixel::COLOR_YUV,
3,
3,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV444P ),
{
{0, 0, 1}, /* Y */
{1, 0, 1}, /* U */
{2, 0, 1}, /* V */
},
},
},
{
"YUYV422",
PlaYUVerPixel::COLOR_YUV,
3,
1,
1,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUYV422 ),
PlaYUVerFrame::YUYV422,
{
{0, 1, 1}, /* Y */
{0, 3, 2}, /* U */
{0, 3, 4}, /* V */
"YUYV422",
PlaYUVerPixel::COLOR_YUV,
3,
1,
1,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUYV422 ),
{
{0, 1, 1}, /* Y */
{0, 3, 2}, /* U */
{0, 3, 4}, /* V */
},
},
},
{
"GRAY",
PlaYUVerPixel::COLOR_GRAY,
1,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_GRAY8 ),
{{0, 0, 1}}, /* Y */
},
{
"RGBp",
PlaYUVerPixel::COLOR_RGB,
3,
3,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_NONE ),
PlaYUVerFrame::GRAY,
{
{0, 0, 1}, /* R */
{1, 0, 1}, /* G */
{2, 0, 1}, /* B */
"GRAY",
PlaYUVerPixel::COLOR_GRAY,
1,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_GRAY8 ),
{{0, 0, 1}}, /* Y */
},
},
{
"RGB",
PlaYUVerPixel::COLOR_RGB,
3,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ),
PlaYUVerFrame::RGBp,
{
{0, 2, 1}, /* R */
{0, 2, 2}, /* G */
{0, 2, 3}, /* B */
"RGBp",
PlaYUVerPixel::COLOR_RGB,
3,
3,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_NONE ),
{
{0, 0, 1}, /* R */
{1, 0, 1}, /* G */
{2, 0, 1}, /* B */
},
},
},
{
"BGR",
PlaYUVerPixel::COLOR_RGB,
3,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ),
PlaYUVerFrame::RGB24,
{
{0, 2, 3}, /* B */
{0, 2, 1}, /* R */
{0, 2, 2}, /* G */
"RGB",
PlaYUVerPixel::COLOR_RGB,
3,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ),
{
{0, 2, 1}, /* R */
{0, 2, 2}, /* G */
{0, 2, 3}, /* B */
},
},
},
{
PlaYUVerFrame::BGR24,
{
"BGR",
PlaYUVerPixel::COLOR_RGB,
3,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ),
{
{0, 2, 3}, /* R */
{0, 2, 2}, /* G */
{0, 2, 1}, /* B */
},
},
},
};
+3 -1
View File
@@ -29,6 +29,8 @@
#include "PlaYUVerFrame.h"
#include "PlaYUVerPixel.h"
#include <map>
#define CHROMA_RESAMPLING( X ) ( ( ( X + 1 ) >> 1 ) << 1 )
#define CHROMARATIO( SIZE, RATIO ) ( RATIO > 1 ? ( ( SIZE + 1 ) / RATIO ) : SIZE )
@@ -109,6 +111,6 @@ typedef struct PlaYUVerPixFmtDescriptor
#define MAX_NUMBER_PLANES 3
extern const PlaYUVerPixFmtDescriptor g_PlaYUVerPixFmtDescriptorsList[];
extern const std::map<int, PlaYUVerPixFmtDescriptor> g_PlaYUVerPixFmtDescriptorsMap;
#endif // __PLAYUVERFRAMEPIXELFORMATS_H__
+47 -9
View File
@@ -164,8 +164,6 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput )
m_uiHeight = m_cStream->codec->height;
#endif
m_uiFrameBufferSize = av_image_get_buffer_size( AVPixelFormat( m_ffPixFmt ), m_uiWidth, m_uiHeight, 1 );
m_strFormatName = uppercase( strFilename.substr( strFilename.find_last_of( "." ) + 1 ) );
const char* name = avcodec_get_name( m_cCodedCtx->codec_id );
m_strCodecName = name;
@@ -174,8 +172,9 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput )
m_uiBitsPerPixel = 8;
/**
* Auxiliar conversation to re-use similar pixfmt
*/
* Auxiliar conversation to re-use similar pixfmt
*/
m_bRequiresConvertion = false;
Int auxPixFmt = m_ffPixFmt;
switch( m_ffPixFmt )
{
@@ -202,7 +201,7 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput )
m_iPixelFormat = PlaYUVerFrame::NO_FMT;
for( Int i = 0; i < PlaYUVerFrame::NUMBER_PEL_FORMATS; i++ )
{
if( g_PlaYUVerPixFmtDescriptorsList[i].ffmpegPelFormat == auxPixFmt )
if( g_PlaYUVerPixFmtDescriptorsMap.at( i ).ffmpegPelFormat == auxPixFmt )
{
m_iPixelFormat = i;
break;
@@ -210,8 +209,11 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput )
}
if( m_iPixelFormat == PlaYUVerFrame::NO_FMT )
{
throw PlaYUVerFailure( "Cannot open file using FFmpeg libs - unsupported pixel format" );
return false;
Int newPelFmt = PlaYUVerFrame::findPixelFormat( "YUV444p" );
m_iPixelFormat = newPelFmt;
m_bRequiresConvertion = true;
//throw PlaYUVerFailure( "StreamHandlerLibav", "Cannot open file using FFmpeg libs - unsupported pixel format" );
//return false;
}
Double fr = 30;
@@ -248,6 +250,34 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput )
return false;
}
if( m_bRequiresConvertion )
{
AVPixelFormat newAvFmt = AVPixelFormat( g_PlaYUVerPixFmtDescriptorsMap.at( m_iPixelFormat ).ffmpegPelFormat );
/* create scaling context */
m_ScalerCtx = sws_getContext( m_uiWidth, m_uiHeight, AVPixelFormat( m_ffPixFmt ),
m_uiWidth, m_uiHeight, newAvFmt,
SWS_BILINEAR, NULL, NULL, NULL );
m_cConvertedFrame = av_frame_alloc();
if( !m_cConvertedFrame )
{
closeHandler();
return false;
}
if( av_image_alloc( m_cConvertedFrame->data, m_cConvertedFrame->linesize,
m_uiWidth, m_uiHeight, newAvFmt, 1 ) < 0 )
{
closeHandler();
return false;
}
m_ffPixFmt = newAvFmt;
}
m_uiFrameBufferSize = av_image_get_buffer_size( AVPixelFormat( m_ffPixFmt ), m_uiWidth, m_uiHeight, 1 );
/* initialize packet, set data to NULL, let the demuxer fill it */
av_init_packet( &m_cPacket );
m_cPacket.data = NULL;
@@ -357,8 +387,16 @@ Bool StreamHandlerLibav::read( PlaYUVerFrame* pcFrame )
if( bGotFrame )
{
av_image_copy_to_buffer( m_pStreamBuffer, m_uiFrameBufferSize, m_cFrame->data, m_cFrame->linesize,
AVPixelFormat( m_ffPixFmt ), m_uiWidth, m_uiHeight, 1 );
AVFrame* decFrame = m_cFrame;
if( m_bRequiresConvertion )
{
sws_scale( m_ScalerCtx, (const uint8_t* const*)decFrame->data, decFrame->linesize, 0,
decFrame->height, (uint8_t* const*)m_cConvertedFrame->data, m_cConvertedFrame->linesize );
decFrame = m_cConvertedFrame;
}
av_image_copy_to_buffer( m_pStreamBuffer, m_uiFrameBufferSize, decFrame->data,
decFrame->linesize, AVPixelFormat( m_ffPixFmt ), m_uiWidth, m_uiHeight, 1 );
pcFrame->frameFromBuffer( m_pStreamBuffer, m_iEndianness );
m_uiCurrFrameFileIdx++;
+6
View File
@@ -42,6 +42,7 @@ extern "C" {
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
#include <libavutil/samplefmt.h>
#include <libswscale/swscale.h>
}
#include "PlaYUVerDefs.h"
@@ -78,6 +79,8 @@ private:
AVStream* m_cStream;
Int m_iStreamIdx;
struct SwsContext* m_ScalerCtx;
AVCodecContext* m_cCodedCtx;
Int m_ffPixFmt;
@@ -89,6 +92,9 @@ private:
UInt64 m_uiSecs;
UInt64 m_uiMicroSec;
Bool m_bRequiresConvertion;
AVFrame* m_cConvertedFrame;
};
#endif // __STREAMHANDLERLIBAV_H__