Skip to content
GitLab
Explorer
Connexion
Navigation principale
Rechercher ou aller à…
Projet
Vivy
Gestion
Activité
Membres
Labels
Programmation
Tickets
Tableaux des tickets
Jalons
Wiki
Wiki externe
Code
Requêtes de fusion
Dépôt
Branches
Validations
Étiquettes
Graphe du dépôt
Comparer les révisions
Compilation
Pipelines
Jobs
Planifications de pipeline
Artéfacts
Aide
Aide
Support
Documentation de GitLab
Comparer les forfaits GitLab
Forum de la communauté GitLab
Contribuer à GitLab
Donner votre avis
Raccourcis clavier
?
Extraits de code
Groupes
Projets
Afficher davantage de fils d'Ariane
Elliu
Vivy
Validations
e345c748
Vérifiée
Valider
e345c748
rédigé
Il y a 4 ans
par
Kubat
Parcourir les fichiers
Options
Téléchargements
Correctifs
Plain Diff
AUDIO: Implements the AudioStreamCodec
parent
65d0fa34
Branches
Branches contenant la validation
Aucune étiquette associée trouvée
1 requête de fusion
!5
Add AudioContext to AudioSubDocument
Modifications
2
Afficher les modifications d'espaces
En ligne
Côte à côte
Affichage de
2 fichiers modifiés
src/Audio.cc
+165
-0
165 ajouts, 0 suppression
src/Audio.cc
src/Audio.hh
+20
-16
20 ajouts, 16 suppressions
src/Audio.hh
avec
185 ajouts
et
16 suppressions
src/Audio.cc
0 → 100644
+
165
−
0
Voir le fichier @
e345c748
#include
"Audio.hh"
using
namespace
Vivy
;
AudioStreamCodec
::
AudioStreamCodec
(
AVFormatContext
*
format
,
AVStream
*
stream
)
:
codecId
(
stream
->
codecpar
->
codec_id
)
,
codecParams
(
stream
->
codecpar
)
,
audioStream
(
stream
)
,
dataFormat
(
format
)
{
codec
=
avcodec_find_decoder
(
codecId
);
if
(
codec
==
nullptr
)
throw
std
::
runtime_error
(
"failed to find a decoder for stream"
);
codecContext
.
reset
(
avcodec_alloc_context3
(
codec
));
if
(
!
codecContext
)
throw
std
::
runtime_error
(
"failed to allocate codec context"
);
if
(
avcodec_parameters_to_context
(
codecContext
.
get
(),
codecParams
)
<
0
)
throw
std
::
runtime_error
(
"failed to copy parameters to codec context"
);
if
(
avcodec_open2
(
codecContext
.
get
(),
codec
,
nullptr
)
<
0
)
throw
std
::
runtime_error
(
"failed to open audio decoder for a stream"
);
SwrContext
*
s
=
dataSwrContext
.
get
();
av_opt_set_int
(
s
,
"in_channel_count"
,
codecContext
->
channels
,
0
);
av_opt_set_int
(
s
,
"out_channel_count"
,
1
,
0
);
av_opt_set_int
(
s
,
"in_channel_layout"
,
static_cast
<
int64_t
>
(
codecContext
->
channel_layout
),
0
);
av_opt_set_int
(
s
,
"out_channel_layout"
,
AV_CH_LAYOUT_MONO
,
0
);
av_opt_set_int
(
s
,
"in_sample_rate"
,
codecContext
->
sample_rate
,
0
);
av_opt_set_int
(
s
,
"out_sample_rate"
,
resamplerSampleRate
,
0
);
av_opt_set_sample_fmt
(
s
,
"in_sample_fmt"
,
codecContext
->
sample_fmt
,
0
);
av_opt_set_sample_fmt
(
s
,
"out_sample_fmt"
,
AV_SAMPLE_FMT_DBL
,
0
);
swr_init
(
s
);
if
(
!
swr_is_initialized
(
s
))
{
throw
std
::
runtime_error
(
"failed to initialize SwrContext resampler"
);
}
}
void
AudioStreamCodec
::
decodeData
()
{
if
(
isDecoded
())
throw
std
::
logic_error
(
"audio stream is already resampled"
);
AVPacket
packet
;
av_init_packet
(
&
packet
);
/* Iterate through frames */
while
(
av_read_frame
(
dataFormat
,
&
packet
)
>=
0
)
{
/* Decode one frame */
int
response
=
avcodec_send_packet
(
codecContext
.
get
(),
&
packet
);
if
(
response
<
0
)
[[
unlikely
]]
{
// av_err2str(response); <- Compound literals are a C99-specific feature
throw
std
::
runtime_error
(
"error while sending a packet to the decoder"
);
}
double
*
buffer
=
nullptr
;
int
old_frame_nb_samples
=
0
;
while
(
response
>=
0
)
{
response
=
avcodec_receive_frame
(
codecContext
.
get
(),
dataFrame
.
get
());
if
(
response
==
AVERROR
(
EAGAIN
)
||
response
==
AVERROR_EOF
)
[[
unlikely
]]
{
break
;
}
else
if
(
response
<
0
)
[[
unlikely
]]
{
// av_err2str(response)
;
<-
Compound
literals
are
a
C99
-
specific
feature
throw
std
::
runtime_error
(
"error while receiving a frame from the decoder"
);
}
/* Resample frames */
if
(
old_frame_nb_samples
<
dataFrame
->
nb_samples
)
{
if
(
nullptr
!=
buffer
)
av_free
(
buffer
);
old_frame_nb_samples
=
dataFrame
->
nb_samples
;
av_samples_alloc
(
reinterpret_cast
<
uint8_t
**>
(
&
buffer
),
nullptr
,
1
,
dataFrame
->
nb_samples
,
AV_SAMPLE_FMT_DBL
,
0
);
}
if
(
const
int
frame_count_int
=
swr_convert
(
dataSwrContext
.
get
(),
reinterpret_cast
<
uint8_t
**>
(
&
buffer
),
dataFrame
->
nb_samples
,
(
const
uint8_t
**
)
dataFrame
->
data
,
dataFrame
->
nb_samples
);
frame_count_int
<
0
)
[[
unlikely
]]
{
throw
std
::
runtime_error
(
"error on frame count, is negative but should not be"
);
}
else
[[
likely
]]
{
const
size_t
frame_count
=
static_cast
<
size_t
>
(
frame_count_int
);
/* Append resampled frames to data */
dataRealPtr
=
(
double
*
)
realloc
(
dataRealPtr
,
(
dataSize
+
(
size_t
)
dataFrame
->
nb_samples
)
*
sizeof
(
double
));
memcpy
(
dataRealPtr
+
dataSize
,
buffer
,
frame_count
*
sizeof
(
double
));
dataSize
+=
frame_count
;
}
}
if
(
buffer
)
av_free
(
buffer
);
av_packet_unref
(
&
packet
);
}
}
void
AudioStreamCodec
::
cleanUpData
()
noexcept
{
dataPtr
.
reset
();
dataRealPtr
=
nullptr
;
dataSize
=
0
;
}
int
AudioStreamCodec
::
getChannels
()
const
noexcept
{
return
codecContext
->
channels
;
}
int
AudioStreamCodec
::
getSampleRate
()
const
noexcept
{
return
codecContext
->
sample_rate
;
}
int
AudioStreamCodec
::
getDataSampleRate
()
const
noexcept
{
return
resamplerSampleRate
;
}
QString
AudioStreamCodec
::
getName
()
const
noexcept
{
return
QString
(
codec
->
name
);
}
AVCodecID
AudioStreamCodec
::
getCodecId
()
const
noexcept
{
return
codecId
;
}
qint64
AudioStreamCodec
::
getBitRate
()
const
noexcept
{
return
codecContext
->
bit_rate
;
}
bool
AudioStreamCodec
::
isDecoded
()
const
noexcept
{
return
dataPtr
!=
nullptr
&&
dataRealPtr
!=
nullptr
;
}
size_t
AudioStreamCodec
::
getDecodedDataSize
()
const
noexcept
{
return
dataSize
;
}
AudioStreamCodec
::
DataWeakPtr
AudioStreamCodec
::
getDecodedData
()
const
noexcept
{
return
DataWeakPtr
{
dataPtr
};
}
Ce diff est replié.
Cliquez pour l'agrandir.
src/Audio.hh
+
20
−
16
Voir le fichier @
e345c748
...
...
@@ -17,6 +17,7 @@ extern "C" {
#include
<QtGlobal>
#include
<QMap>
#include
<QVector>
#include
<QString>
#include
<memory.h>
namespace
Vivy
...
...
@@ -54,44 +55,47 @@ class AudioStreamCodec final {
using
SwrContextPtr
=
std
::
unique_ptr
<
SwrContext
,
decltype
(
swrContenxtDeleter
)
>
;
public
:
AudioStreamCodec
(
AVStream
*
);
~
AudioStreamCodec
();
AudioStreamCodec
(
AVFormatContext
*
,
AVStream
*
);
~
AudioStreamCodec
()
=
default
;
// Decode the stream
void
decodeData
();
void
cleanUpData
()
noexcept
;
bool
isDecoded
()
const
noexcept
;
int
getDataSampleRate
()
const
noexcept
;
size_t
getDecodedDataSize
()
const
noexcept
;
DataWeakPtr
getDecodedData
()
const
noexcept
;
// Some getters
int
getChannels
()
const
noexcept
;
int
getSampleRate
()
const
noexcept
;
const
char
*
getName
()
const
noexcept
;
QString
getName
()
const
noexcept
;
AVCodecID
getCodecId
()
const
noexcept
;
qint64
getBitRate
()
const
noexcept
;
private
:
bool
initFromStream
()
noexcept
;
// Init all the object
void
cleanupForReuse
()
noexcept
;
// Free everything, can now use initFromStream again
// Check if ready
bool
isReadyForUse
()
const
noexcept
;
bool
isResampled
()
const
noexcept
;
// Codec related informations
AVCodecID
codecId
{
AV_CODEC_ID_NONE
};
AVCodecContextPtr
codecContext
{
nullptr
};
AVCodecParameters
*
codecParams
{
nullptr
};
AVCodec
*
codec
{
nullptr
};
AVCodecParameters
*
codecParams
{
nullptr
};
AVCodecContextPtr
codecContext
{
nullptr
};
// Stream is held by AudioFormatCtx
AVStream
*
audioStream
{
nullptr
};
bool
isInitFromStream
{
false
};
// Resampled frame data
SwrContextPtr
dataSwrContext
{
nullptr
,
swrContenxtDeleter
};
AVFramePtr
dataFrame
{
nullptr
,
avFrameDeleter
};
DataPtr
dataPtr
{
nullptr
,
dataDeleter
};
AVFormatContext
*
dataFormat
;
SwrContextPtr
dataSwrContext
{
swr_alloc
(),
swrContenxtDeleter
};
AVFramePtr
dataFrame
{
av_frame_alloc
(),
avFrameDeleter
};
DataPtr
dataPtr
{
nullptr
,
dataDeleter
};
// Holds dataRealPtr
double
*
dataRealPtr
{
nullptr
};
size_t
dataSize
{
0
};
// Constants for the resampler
static
constexpr
uint
resamplerChunkSize
=
512
;
static
constexpr
uint
resamplerOverlap
=
128
;
static
constexpr
uint
resamplerDecalage
=
resamplerChunkSize
-
resamplerOverlap
;
static
constexpr
uint
resamplerSampleRate
=
44100
;
};
/* Facility for pointers to AudioStreamCodec objects */
...
...
Ce diff est replié.
Cliquez pour l'agrandir.
Aperçu
0%
Chargement en cours
Veuillez réessayer
ou
joindre un nouveau fichier
.
Annuler
You are about to add
0
people
to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Enregistrer le commentaire
Annuler
Veuillez vous
inscrire
ou vous
se connecter
pour commenter