Move closer to OMXAudioCodecOMX from xbmc
This commit is contained in:
parent
320bf889fd
commit
eef8134986
3 changed files with 125 additions and 110 deletions
67
DllAvUtil.h
67
DllAvUtil.h
|
|
@ -73,6 +73,10 @@ extern "C" {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52,29,100)
|
||||
#define AVFRAME_IN_LAVU
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
|
@ -92,9 +96,12 @@ public:
|
|||
virtual void av_freep(void *ptr)=0;
|
||||
virtual int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding)=0;
|
||||
virtual int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)=0;
|
||||
virtual int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size)=0;
|
||||
virtual const AVCRC* av_crc_get_table(AVCRCId crc_id)=0;
|
||||
virtual uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)=0;
|
||||
virtual int av_opt_set(void *obj, const char *name, const char *val, int search_flags)=0;
|
||||
virtual int av_opt_set_double(void *obj, const char *name, double val, int search_flags)=0;
|
||||
virtual int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)=0;
|
||||
virtual AVFifoBuffer *av_fifo_alloc(unsigned int size) = 0;
|
||||
virtual void av_fifo_free(AVFifoBuffer *f) = 0;
|
||||
virtual void av_fifo_reset(AVFifoBuffer *f) = 0;
|
||||
|
|
@ -105,9 +112,21 @@ public:
|
|||
virtual int av_get_bytes_per_sample(enum AVSampleFormat p1) = 0;
|
||||
virtual AVDictionaryEntry *av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags) = 0;
|
||||
virtual int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)=0;
|
||||
virtual void av_dict_free(AVDictionary **pm) = 0;
|
||||
virtual int av_samples_get_buffer_size (int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) = 0;
|
||||
virtual int64_t av_get_default_channel_layout(int nb_channels)=0;
|
||||
virtual void av_log_set_level(int level) = 0;
|
||||
virtual int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) = 0;
|
||||
virtual int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt) = 0;
|
||||
virtual int av_get_channel_layout_channel_index (uint64_t channel_layout, uint64_t channel) = 0;
|
||||
virtual int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, const uint8_t *buf, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) = 0;
|
||||
virtual int av_samples_copy(uint8_t **dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt) = 0;
|
||||
#if defined(AVFRAME_IN_LAVU)
|
||||
virtual void av_frame_free(AVFrame **frame)=0;
|
||||
virtual AVFrame *av_frame_alloc(void)=0;
|
||||
virtual void av_frame_unref(AVFrame *frame)=0;
|
||||
virtual void av_frame_move_ref(AVFrame *dst, AVFrame *src)=0;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined (USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN)
|
||||
|
|
@ -125,9 +144,12 @@ public:
|
|||
virtual void av_freep(void *ptr) { ::av_freep(ptr); }
|
||||
virtual int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding d) { return ::av_rescale_rnd(a, b, c, d); }
|
||||
virtual int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) { return ::av_rescale_q(a, bq, cq); }
|
||||
virtual int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size) { return ::av_crc_init(ctx, le, bits, poly, ctx_size); }
|
||||
virtual const AVCRC* av_crc_get_table(AVCRCId crc_id) { return ::av_crc_get_table(crc_id); }
|
||||
virtual uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length) { return ::av_crc(ctx, crc, buffer, length); }
|
||||
virtual int av_opt_set(void *obj, const char *name, const char *val, int search_flags) { return ::av_opt_set(obj, name, val, search_flags); }
|
||||
virtual int av_opt_set_double(void *obj, const char *name, double val, int search_flags) { return ::av_opt_set_double(obj, name, val, search_flags); }
|
||||
virtual int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags) { return ::av_opt_set_int(obj, name, val, search_flags); }
|
||||
virtual AVFifoBuffer *av_fifo_alloc(unsigned int size) {return ::av_fifo_alloc(size); }
|
||||
virtual void av_fifo_free(AVFifoBuffer *f) { ::av_fifo_free(f); }
|
||||
virtual void av_fifo_reset(AVFifoBuffer *f) { ::av_fifo_reset(f); }
|
||||
|
|
@ -141,10 +163,25 @@ public:
|
|||
{ return ::av_get_bytes_per_sample(p1); }
|
||||
virtual AVDictionaryEntry *av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags){ return ::av_dict_get(m, key, prev, flags); }
|
||||
virtual int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags) { return ::av_dict_set(pm, key, value, flags); }
|
||||
virtual void av_dict_free(AVDictionary **pm) { ::av_dict_free(pm); }
|
||||
virtual int av_samples_get_buffer_size (int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
|
||||
{ return ::av_samples_get_buffer_size(linesize, nb_channels, nb_samples, sample_fmt, align); }
|
||||
virtual int64_t av_get_default_channel_layout(int nb_channels) { return ::av_get_default_channel_layout(nb_channels); }
|
||||
virtual void av_log_set_level(int level) { ::av_log_set_level(level); };
|
||||
virtual int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
|
||||
{ return ::av_samples_alloc(audio_data, linesize, nb_channels, nb_samples, sample_fmt, align); }
|
||||
virtual int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt) { return ::av_sample_fmt_is_planar(sample_fmt); }
|
||||
virtual int av_get_channel_layout_channel_index (uint64_t channel_layout, uint64_t channel) { return ::av_get_channel_layout_channel_index(channel_layout, channel); }
|
||||
virtual int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, const uint8_t *buf, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
|
||||
{ return ::av_samples_fill_arrays(audio_data, linesize, buf, nb_channels, nb_samples, sample_fmt, align); }
|
||||
virtual int av_samples_copy(uint8_t **dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
|
||||
{ return ::av_samples_copy(dst, src, dst_offset, src_offset, nb_samples, nb_channels, sample_fmt); }
|
||||
#if defined(AVFRAME_IN_LAVU)
|
||||
virtual void av_frame_free(AVFrame **frame) { return ::av_frame_free(frame); }
|
||||
virtual AVFrame *av_frame_alloc() { return ::av_frame_alloc(); }
|
||||
virtual void av_frame_unref(AVFrame *frame) { return ::av_frame_unref(frame); }
|
||||
virtual void av_frame_move_ref(AVFrame *dst, AVFrame *src) { return ::av_frame_move_ref(dst,src); }
|
||||
#endif
|
||||
|
||||
// DLL faking.
|
||||
virtual bool ResolveExports() { return true; }
|
||||
|
|
@ -172,8 +209,11 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface
|
|||
DEFINE_METHOD4(int64_t, av_rescale_rnd, (int64_t p1, int64_t p2, int64_t p3, enum AVRounding p4));
|
||||
DEFINE_METHOD3(int64_t, av_rescale_q, (int64_t p1, AVRational p2, AVRational p3));
|
||||
DEFINE_METHOD1(const AVCRC*, av_crc_get_table, (AVCRCId p1))
|
||||
DEFINE_METHOD5(int, av_crc_init, (AVCRC *p1, int p2, int p3, uint32_t p4, int p5));
|
||||
DEFINE_METHOD4(uint32_t, av_crc, (const AVCRC *p1, uint32_t p2, const uint8_t *p3, size_t p4));
|
||||
DEFINE_METHOD4(int, av_opt_set, (void *p1, const char *p2, const char *p3, int p4));
|
||||
DEFINE_METHOD4(int, av_opt_set_double, (void *p1, const char *p2, double p3, int p4))
|
||||
DEFINE_METHOD4(int, av_opt_set_int, (void *p1, const char *p2, int64_t p3, int p4))
|
||||
DEFINE_METHOD1(AVFifoBuffer*, av_fifo_alloc, (unsigned int p1))
|
||||
DEFINE_METHOD1(void, av_fifo_free, (AVFifoBuffer *p1))
|
||||
DEFINE_METHOD1(void, av_fifo_reset, (AVFifoBuffer *p1))
|
||||
|
|
@ -184,9 +224,21 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface
|
|||
DEFINE_METHOD1(int, av_get_bytes_per_sample, (enum AVSampleFormat p1))
|
||||
DEFINE_METHOD4(AVDictionaryEntry *, av_dict_get, (AVDictionary *p1, const char *p2, const AVDictionaryEntry *p3, int p4))
|
||||
DEFINE_METHOD4(int, av_dict_set, (AVDictionary **p1, const char *p2, const char *p3, int p4));
|
||||
DEFINE_METHOD1(void, av_dict_free, (AVDictionary **p1));
|
||||
DEFINE_METHOD5(int, av_samples_get_buffer_size, (int *p1, int p2, int p3, enum AVSampleFormat p4, int p5))
|
||||
DEFINE_METHOD1(int64_t, av_get_default_channel_layout, (int p1))
|
||||
DEFINE_METHOD1(void, av_log_set_level, (int p1))
|
||||
DEFINE_METHOD6(int, av_samples_alloc, (uint8_t **p1, int *p2, int p3, int p4, enum AVSampleFormat p5, int p6))
|
||||
DEFINE_METHOD1(int, av_sample_fmt_is_planar, (enum AVSampleFormat p1))
|
||||
DEFINE_METHOD2(int, av_get_channel_layout_channel_index, (uint64_t p1, uint64_t p2))
|
||||
DEFINE_METHOD7(int, av_samples_fill_arrays, (uint8_t **p1, int *p2, const uint8_t *p3, int p4, int p5, enum AVSampleFormat p6, int p7))
|
||||
DEFINE_METHOD7(int, av_samples_copy, (uint8_t **p1, uint8_t *const *p2, int p3, int p4, int p5, int p6, enum AVSampleFormat p7))
|
||||
#if defined(AVFRAME_IN_LAVU)
|
||||
DEFINE_METHOD1(void, av_frame_free, (AVFrame **p1))
|
||||
DEFINE_METHOD0(AVFrame *, av_frame_alloc)
|
||||
DEFINE_METHOD1(void, av_frame_unref, (AVFrame *p1))
|
||||
DEFINE_METHOD2(void, av_frame_move_ref, (AVFrame *p1, AVFrame* p2))
|
||||
#endif
|
||||
|
||||
public:
|
||||
BEGIN_METHOD_RESOLVE()
|
||||
|
|
@ -198,9 +250,12 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface
|
|||
RESOLVE_METHOD(av_freep)
|
||||
RESOLVE_METHOD(av_rescale_rnd)
|
||||
RESOLVE_METHOD(av_rescale_q)
|
||||
RESOLVE_METHOD(av_crc_init)
|
||||
RESOLVE_METHOD(av_crc_get_table)
|
||||
RESOLVE_METHOD(av_crc)
|
||||
RESOLVE_METHOD(av_opt_set)
|
||||
RESOLVE_METHOD(av_opt_set_double)
|
||||
RESOLVE_METHOD(av_opt_set_int)
|
||||
RESOLVE_METHOD(av_fifo_alloc)
|
||||
RESOLVE_METHOD(av_fifo_free)
|
||||
RESOLVE_METHOD(av_fifo_reset)
|
||||
|
|
@ -211,9 +266,21 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface
|
|||
RESOLVE_METHOD(av_get_bytes_per_sample)
|
||||
RESOLVE_METHOD(av_dict_get)
|
||||
RESOLVE_METHOD(av_dict_set)
|
||||
RESOLVE_METHOD(av_dict_free)
|
||||
RESOLVE_METHOD(av_samples_get_buffer_size)
|
||||
RESOLVE_METHOD(av_get_default_channel_layout)
|
||||
RESOLVE_METHOD(av_log_set_level)
|
||||
RESOLVE_METHOD(av_samples_alloc)
|
||||
RESOLVE_METHOD(av_sample_fmt_is_planar)
|
||||
RESOLVE_METHOD(av_get_channel_layout_channel_index)
|
||||
RESOLVE_METHOD(av_samples_fill_arrays)
|
||||
RESOLVE_METHOD(av_samples_copy)
|
||||
#if defined(AVFRAME_IN_LAVU)
|
||||
RESOLVE_METHOD(av_frame_free)
|
||||
RESOLVE_METHOD(av_frame_alloc)
|
||||
RESOLVE_METHOD(av_frame_unref)
|
||||
RESOLVE_METHOD(av_frame_move_ref)
|
||||
#endif
|
||||
END_METHOD_RESOLVE()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,22 +25,11 @@
|
|||
#endif
|
||||
#include "utils/log.h"
|
||||
|
||||
#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
|
||||
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
|
||||
#endif
|
||||
#define MAX_AUDIO_FRAME_SIZE (AVCODEC_MAX_AUDIO_FRAME_SIZE*2)
|
||||
|
||||
COMXAudioCodecOMX::COMXAudioCodecOMX()
|
||||
{
|
||||
m_iBufferSize2 = 0;
|
||||
m_pBuffer2 = (BYTE*)_aligned_malloc(MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE, 16);
|
||||
memset(m_pBuffer2, 0, MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
m_pBufferOutput = NULL;
|
||||
m_iBufferOutputAlloced = 0;
|
||||
|
||||
m_iBufferUpmixSize = 0;
|
||||
m_pBufferUpmix = (BYTE*)_aligned_malloc(MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE, 16);
|
||||
memset(m_pBufferUpmix, 0, MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
m_iBuffered = 0;
|
||||
m_pCodecContext = NULL;
|
||||
m_pConvert = NULL;
|
||||
m_bOpenedCodec = false;
|
||||
|
|
@ -49,15 +38,16 @@ COMXAudioCodecOMX::COMXAudioCodecOMX()
|
|||
m_channels = 0;
|
||||
m_layout = 0;
|
||||
m_pFrame1 = NULL;
|
||||
m_bGotFrame = false;
|
||||
m_iSampleFormat = AV_SAMPLE_FMT_NONE;
|
||||
m_desiredSampleFormat = AV_SAMPLE_FMT_NONE;
|
||||
m_iBufferSize1 = 0;
|
||||
}
|
||||
|
||||
COMXAudioCodecOMX::~COMXAudioCodecOMX()
|
||||
{
|
||||
_aligned_free(m_pBuffer2);
|
||||
_aligned_free(m_pBufferUpmix);
|
||||
m_dllAvUtil.av_free(m_pBufferOutput);
|
||||
m_pBufferOutput = NULL;
|
||||
m_iBufferOutputAlloced = 0;
|
||||
Dispose();
|
||||
}
|
||||
|
||||
|
|
@ -140,9 +130,7 @@ void COMXAudioCodecOMX::Dispose()
|
|||
m_dllAvUtil.Unload();
|
||||
m_dllSwResample.Unload();
|
||||
|
||||
m_iBufferSize1 = 0;
|
||||
m_iBufferSize2 = 0;
|
||||
m_iBuffered = 0;
|
||||
m_bGotFrame = false;
|
||||
}
|
||||
|
||||
int COMXAudioCodecOMX::Decode(BYTE* pData, int iSize)
|
||||
|
|
@ -150,9 +138,8 @@ int COMXAudioCodecOMX::Decode(BYTE* pData, int iSize)
|
|||
int iBytesUsed, got_frame;
|
||||
if (!m_pCodecContext) return -1;
|
||||
|
||||
m_iBufferSize2 = 0;
|
||||
|
||||
AVPacket avpkt;
|
||||
m_bGotFrame = false;
|
||||
m_dllAvCodec.av_init_packet(&avpkt);
|
||||
avpkt.data = pData;
|
||||
avpkt.size = iSize;
|
||||
|
|
@ -162,14 +149,8 @@ int COMXAudioCodecOMX::Decode(BYTE* pData, int iSize)
|
|||
, &avpkt);
|
||||
if (iBytesUsed < 0 || !got_frame)
|
||||
{
|
||||
m_iBufferSize1 = 0;
|
||||
m_iBufferSize2 = 0;
|
||||
return iBytesUsed;
|
||||
}
|
||||
int linesize1, linesize2;
|
||||
m_iBufferSize1 = m_dllAvUtil.av_samples_get_buffer_size(&linesize1, m_pCodecContext->channels, m_pFrame1->nb_samples, m_pCodecContext->sample_fmt, 1);
|
||||
m_iBufferSize2 = m_dllAvUtil.av_samples_get_buffer_size(&linesize2, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1);
|
||||
|
||||
/* some codecs will attempt to consume more data than what we gave */
|
||||
if (iBytesUsed > iSize)
|
||||
{
|
||||
|
|
@ -177,21 +158,40 @@ int COMXAudioCodecOMX::Decode(BYTE* pData, int iSize)
|
|||
iBytesUsed = iSize;
|
||||
}
|
||||
|
||||
if(m_iBufferSize1 == 0 && iBytesUsed >= 0)
|
||||
m_iBuffered += iBytesUsed;
|
||||
else
|
||||
m_iBuffered = 0;
|
||||
|
||||
if (m_bFirstFrame)
|
||||
{
|
||||
CLog::Log(LOGDEBUG, "COMXAudioCodecOMX::Decode(%p,%d) format=%d(%d) chan=%d samples=%d size=%d/%d,%d/%d,%d data=%p,%p,%p,%p,%p,%p,%p,%p",
|
||||
CLog::Log(LOGDEBUG, "COMXAudioCodecOMX::Decode(%p,%d) format=%d(%d) chan=%d samples=%d size=%d data=%p,%p,%p,%p,%p,%p,%p,%p",
|
||||
pData, iSize, m_pCodecContext->sample_fmt, m_desiredSampleFormat, m_pCodecContext->channels, m_pFrame1->nb_samples,
|
||||
m_iBufferSize1, m_iBufferSize2, linesize1, linesize2, m_pFrame1->linesize[0],
|
||||
m_pFrame1->linesize[0],
|
||||
m_pFrame1->data[0], m_pFrame1->data[1], m_pFrame1->data[2], m_pFrame1->data[3], m_pFrame1->data[4], m_pFrame1->data[5], m_pFrame1->data[6], m_pFrame1->data[7]
|
||||
);
|
||||
}
|
||||
|
||||
if(m_pCodecContext->sample_fmt != m_desiredSampleFormat && m_iBufferSize1 > 0)
|
||||
m_bGotFrame = true;
|
||||
return iBytesUsed;
|
||||
}
|
||||
|
||||
int COMXAudioCodecOMX::GetData(BYTE** dst)
|
||||
{
|
||||
if (!m_bGotFrame)
|
||||
return 0;
|
||||
int inLineSize, outLineSize;
|
||||
/* input audio is aligned */
|
||||
int inputSize = m_dllAvUtil.av_samples_get_buffer_size(&inLineSize, m_pCodecContext->channels, m_pFrame1->nb_samples, m_pCodecContext->sample_fmt, 0);
|
||||
/* output audio will be packed */
|
||||
int outputSize = m_dllAvUtil.av_samples_get_buffer_size(&outLineSize, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1);
|
||||
bool cont = !m_pFrame1->data[1] || (m_pFrame1->data[1] == m_pFrame1->data[0] + inLineSize && inLineSize == outLineSize && inLineSize * m_pCodecContext->channels == inputSize);
|
||||
|
||||
if (m_iBufferOutputAlloced < outputSize)
|
||||
{
|
||||
m_dllAvUtil.av_free(m_pBufferOutput);
|
||||
m_pBufferOutput = (BYTE*)m_dllAvUtil.av_malloc(outputSize + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
m_iBufferOutputAlloced = outputSize;
|
||||
}
|
||||
*dst = m_pBufferOutput;
|
||||
|
||||
/* need to convert format */
|
||||
if(m_pCodecContext->sample_fmt != m_desiredSampleFormat)
|
||||
{
|
||||
if(m_pConvert && (m_pCodecContext->sample_fmt != m_iSampleFormat || m_channels != m_pCodecContext->channels))
|
||||
m_dllSwResample.swr_free(&m_pConvert);
|
||||
|
|
@ -205,100 +205,53 @@ int COMXAudioCodecOMX::Decode(BYTE* pData, int iSize)
|
|||
m_dllAvUtil.av_get_default_channel_layout(m_pCodecContext->channels),
|
||||
m_pCodecContext->sample_fmt, m_pCodecContext->sample_rate,
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
if(!m_pConvert || m_dllSwResample.swr_init(m_pConvert) < 0)
|
||||
{
|
||||
CLog::Log(LOGERROR, "COMXAudioCodecOMX::Decode - Unable to convert %d to %d", m_pCodecContext->sample_fmt, m_desiredSampleFormat);
|
||||
m_iBufferSize1 = 0;
|
||||
m_iBufferSize2 = 0;
|
||||
return iBytesUsed;
|
||||
CLog::Log(LOGERROR, "COMXAudioCodecOMX::Decode - Unable to initialise convert format %d to %d", m_pCodecContext->sample_fmt, m_desiredSampleFormat);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
m_iBufferSize1 = 0;
|
||||
|
||||
BYTE *out_planes[] = {
|
||||
m_pBuffer2 + 0 * linesize2, m_pBuffer2 + 1 * linesize2, m_pBuffer2 + 2 * linesize2, m_pBuffer2 + 3 * linesize2,
|
||||
m_pBuffer2 + 4 * linesize2, m_pBuffer2 + 5 * linesize2, m_pBuffer2 + 6 * linesize2, m_pBuffer2 + 7 * linesize2,
|
||||
};
|
||||
|
||||
if(m_dllSwResample.swr_convert(m_pConvert, out_planes, m_pFrame1->nb_samples, (const uint8_t **)m_pFrame1->data, m_pFrame1->nb_samples) < 0)
|
||||
/* use unaligned flag to keep output packed */
|
||||
uint8_t *out_planes[m_pCodecContext->channels];
|
||||
if(m_dllAvUtil.av_samples_fill_arrays(out_planes, NULL, m_pBufferOutput, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1) < 0 ||
|
||||
m_dllSwResample.swr_convert(m_pConvert, out_planes, m_pFrame1->nb_samples, (const uint8_t **)m_pFrame1->data, m_pFrame1->nb_samples) < 0)
|
||||
{
|
||||
CLog::Log(LOGERROR, "COMXAudioCodecOMX::Decode - Unable to convert %d to %d", (int)m_pCodecContext->sample_fmt, m_desiredSampleFormat);
|
||||
m_iBufferSize1 = 0;
|
||||
m_iBufferSize2 = 0;
|
||||
return iBytesUsed;
|
||||
CLog::Log(LOGERROR, "COMXAudioCodecOMX::Decode - Unable to convert format %d to %d", (int)m_pCodecContext->sample_fmt, m_desiredSampleFormat);
|
||||
outputSize = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iBufferSize2 = 0;
|
||||
}
|
||||
|
||||
return iBytesUsed;
|
||||
}
|
||||
|
||||
int COMXAudioCodecOMX::GetData(BYTE** dst)
|
||||
{
|
||||
int size = 0;
|
||||
bool contiguous = true;
|
||||
|
||||
if(m_iBufferSize1)
|
||||
{
|
||||
int i;
|
||||
int linesize;
|
||||
BYTE *next = m_pFrame1->data[0];
|
||||
m_dllAvUtil.av_samples_get_buffer_size(&linesize, m_pCodecContext->channels, m_pFrame1->nb_samples, m_pCodecContext->sample_fmt, 1);
|
||||
for (i=0; i<m_pCodecContext->channels; i++)
|
||||
{
|
||||
if (!m_pFrame1->data[i])
|
||||
break;
|
||||
if (next != m_pFrame1->data[i])
|
||||
contiguous = false;
|
||||
next += linesize;
|
||||
size += linesize;
|
||||
}
|
||||
if (size != m_iBufferSize1)
|
||||
contiguous = false;
|
||||
|
||||
if (contiguous)
|
||||
/* if it is already contiguous, just return decoded frame */
|
||||
if (cont)
|
||||
{
|
||||
*dst = m_pFrame1->data[0];
|
||||
size = m_iBufferSize1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iBufferUpmixSize = 0;
|
||||
for (i=0; i<m_pCodecContext->channels; i++)
|
||||
/* copy to a contiguous buffer */
|
||||
uint8_t *out_planes[m_pCodecContext->channels];
|
||||
if (m_dllAvUtil.av_samples_fill_arrays(out_planes, NULL, m_pBufferOutput, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1) < 0 ||
|
||||
m_dllAvUtil.av_samples_copy(out_planes, m_pFrame1->data, 0, 0, m_pFrame1->nb_samples, m_pCodecContext->channels, m_desiredSampleFormat) < 0 )
|
||||
{
|
||||
if (m_iBufferUpmixSize + linesize <= MAX_AUDIO_FRAME_SIZE && m_pFrame1->data[i])
|
||||
{
|
||||
memcpy(m_pBufferUpmix + m_iBufferUpmixSize, m_pFrame1->data[i], linesize);
|
||||
m_iBufferUpmixSize += linesize;
|
||||
} else assert(0);
|
||||
}
|
||||
*dst = m_pBufferUpmix;
|
||||
size = m_iBufferUpmixSize;
|
||||
outputSize = 0;
|
||||
}
|
||||
}
|
||||
if(m_iBufferSize2)
|
||||
{
|
||||
*dst = m_pBuffer2;
|
||||
size = m_iBufferSize2;
|
||||
}
|
||||
if (m_bFirstFrame)
|
||||
{
|
||||
CLog::Log(LOGDEBUG, "COMXAudioCodecOMX::GetData size=%d/%d/%d cont=%d buf=%p", m_iBufferSize1, m_iBufferSize2, size, contiguous, *dst);
|
||||
m_bFirstFrame = false;
|
||||
CLog::Log(LOGDEBUG, "COMXAudioCodecOMX::GetData size=%d/%d line=%d/%d cont=%d buf=%p", inputSize, outputSize, inLineSize, outLineSize, cont, *dst);
|
||||
m_bFirstFrame = false;
|
||||
}
|
||||
return size;
|
||||
return outputSize;
|
||||
}
|
||||
|
||||
void COMXAudioCodecOMX::Reset()
|
||||
{
|
||||
if (m_pCodecContext) m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext);
|
||||
m_iBufferSize1 = 0;
|
||||
m_iBufferSize2 = 0;
|
||||
m_iBuffered = 0;
|
||||
m_bGotFrame = false;
|
||||
}
|
||||
|
||||
int COMXAudioCodecOMX::GetChannels()
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ public:
|
|||
int GetSampleRate();
|
||||
int GetBitsPerSample();
|
||||
static const char* GetName() { return "FFmpeg"; }
|
||||
int GetBufferSize() { return m_iBuffered; }
|
||||
int GetBitRate();
|
||||
|
||||
protected:
|
||||
|
|
@ -56,21 +55,17 @@ protected:
|
|||
enum PCMChannels m_channelMap[PCM_MAX_CH + 1];
|
||||
|
||||
AVFrame* m_pFrame1;
|
||||
int m_iBufferSize1;
|
||||
|
||||
BYTE *m_pBuffer2;
|
||||
int m_iBufferSize2;
|
||||
|
||||
BYTE *m_pBufferUpmix;
|
||||
int m_iBufferUpmixSize;
|
||||
BYTE *m_pBufferOutput;
|
||||
int m_iBufferOutputAlloced;
|
||||
|
||||
bool m_bOpenedCodec;
|
||||
int m_iBuffered;
|
||||
|
||||
int m_channels;
|
||||
uint64_t m_layout;
|
||||
|
||||
bool m_bFirstFrame;
|
||||
bool m_bGotFrame;
|
||||
DllAvCodec m_dllAvCodec;
|
||||
DllAvUtil m_dllAvUtil;
|
||||
DllSwResample m_dllSwResample;
|
||||
|
|
|
|||
Loading…
Reference in a new issue