19 #include <libavutil/dict.h> 20 #include <libavutil/opt.h> 21 #include <libavcodec/avcodec.h> 22 #include <libavformat/avformat.h> 25 #ifdef HAVE_SWRESAMPLE 27 #include <libswresample/swresample.h> 33 #if LIBAVFORMAT_VERSION_MAJOR < 53 34 #define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO 37 #ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE 39 #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 48 _filename(src->_filename),
50 _packet_data(nullptr),
53 _resample_ctx(nullptr),
55 _buffer_alloc(nullptr),
64 nassertv(_format_ctx !=
nullptr);
66 if (avformat_find_stream_info(_format_ctx,
nullptr) < 0) {
74 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100) 75 AVCodecParameters *codecpar;
77 AVCodecContext *codecpar;
81 AVStream *stream =
nullptr;
82 for (
int i = 0; i < (int)_format_ctx->nb_streams; i++) {
83 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100) 84 codecpar = _format_ctx->streams[i]->codecpar;
86 codecpar = _format_ctx->streams[i]->codec;
88 if (codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
90 stream = _format_ctx->streams[i];
95 if (stream ==
nullptr) {
100 _audio_timebase = av_q2d(stream->time_base);
101 _audio_rate = codecpar->sample_rate;
102 _audio_channels = codecpar->channels;
104 AVCodec *pAudioCodec = avcodec_find_decoder(codecpar->codec_id);
105 if (pAudioCodec ==
nullptr) {
110 _audio_ctx = avcodec_alloc_context3(pAudioCodec);
112 if (_audio_ctx ==
nullptr) {
117 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100) 118 avcodec_parameters_to_context(_audio_ctx, codecpar);
120 avcodec_copy_context(_audio_ctx, codecpar);
123 AVDictionary *opts =
nullptr;
124 av_dict_set(&opts,
"request_sample_fmt",
"s16", 0);
125 if (avcodec_open2(_audio_ctx, pAudioCodec,
nullptr) < 0) {
133 if (_audio_ctx->sample_fmt != AV_SAMPLE_FMT_S16) {
134 #ifdef HAVE_SWRESAMPLE 136 <<
"Codec does not use signed 16-bit sample format. Setting up swresample context.\n";
138 _resample_ctx = swr_alloc();
139 av_opt_set_int(_resample_ctx,
"in_channel_count", _audio_channels, 0);
140 av_opt_set_int(_resample_ctx,
"out_channel_count", _audio_channels, 0);
141 av_opt_set_int(_resample_ctx,
"in_channel_layout", _audio_ctx->channel_layout, 0);
142 av_opt_set_int(_resample_ctx,
"out_channel_layout", _audio_ctx->channel_layout, 0);
143 av_opt_set_int(_resample_ctx,
"in_sample_rate", _audio_ctx->sample_rate, 0);
144 av_opt_set_int(_resample_ctx,
"out_sample_rate", _audio_ctx->sample_rate, 0);
145 av_opt_set_sample_fmt(_resample_ctx,
"in_sample_fmt", _audio_ctx->sample_fmt, 0);
146 av_opt_set_sample_fmt(_resample_ctx,
"out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
148 if (swr_init(_resample_ctx) != 0) {
150 <<
"Failed to set up resample context.\n";
151 _resample_ctx =
nullptr;
155 <<
"Codec does not use signed 16-bit sample format, but support for libswresample has not been enabled.\n";
159 _length = (_format_ctx->duration * 1.0) / AV_TIME_BASE;
161 _can_seek_fast =
true;
163 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101) 164 _frame = av_frame_alloc();
166 _frame = avcodec_alloc_frame();
169 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 170 _packet = av_packet_alloc();
172 _packet =
new AVPacket;
175 _buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE / 2;
176 _buffer_alloc =
new int16_t[_buffer_size + 64];
179 if ((_packet ==
nullptr)||(_buffer_alloc ==
nullptr)) {
183 memset(_packet, 0,
sizeof(AVPacket));
187 _buffer = _buffer_alloc;
188 while (((
size_t)_buffer) & 31) {
193 _initial_dts = _packet->dts;
211 void FfmpegAudioCursor::
213 if (_audio_ctx && _audio_ctx->codec) {
214 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100) 216 avcodec_send_packet(_audio_ctx,
nullptr);
217 while (avcodec_receive_frame(_audio_ctx, _frame) == 0) {}
218 avcodec_flush_buffers(_audio_ctx);
221 avcodec_close(_audio_ctx);
222 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 52, 0) 223 avcodec_free_context(&_audio_ctx);
228 _audio_ctx =
nullptr;
231 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101) 232 av_frame_free(&_frame);
234 avcodec_free_frame(&_frame);
240 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 241 av_packet_free(&_packet);
244 av_free_packet(_packet);
252 delete[] _buffer_alloc;
253 _buffer_alloc =
nullptr;
259 _format_ctx =
nullptr;
262 #ifdef HAVE_SWRESAMPLE 264 swr_free(&_resample_ctx);
265 _resample_ctx =
nullptr;
276 void FfmpegAudioCursor::
279 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 280 av_packet_unref(_packet);
282 av_free_packet(_packet);
285 while (av_read_frame(_format_ctx, _packet) >= 0) {
286 if (_packet->stream_index == _audio_index) {
287 _packet_size = _packet->size;
288 _packet_data = _packet->data;
291 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 292 av_packet_unref(_packet);
294 av_free_packet(_packet);
297 _packet->data =
nullptr;
299 _packet_data =
nullptr;
307 bool FfmpegAudioCursor::
309 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100) 318 while (_packet->data !=
nullptr) {
319 ret = avcodec_send_packet(_audio_ctx, _packet);
328 if (_packet->data ==
nullptr) {
330 ret = avcodec_send_packet(_audio_ctx,
nullptr);
335 if ((ret != 0) && (ret != AVERROR(EAGAIN))) {
338 <<
"avcodec_send_packet returned " << ret <<
"\n";
343 ret = avcodec_receive_frame(_audio_ctx, _frame);
345 if (ret == AVERROR_EOF) {
347 nassertr(_packet->data ==
nullptr,
false);
351 _buffer_tail = _buffer_size;
352 memset(_buffer, 0, _buffer_size * 2);
355 }
else if (ret != 0) {
358 <<
"avcodec_receive_frame returned " << ret <<
"\n";
368 if (_packet->data ==
nullptr) {
370 _buffer_tail = _buffer_size;
371 memset(_buffer, 0, _buffer_size * 2);
373 }
else if (_packet_size == 0) {
378 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 379 pkt = av_packet_alloc();
385 pkt->data = _packet_data;
386 pkt->size = _packet_size;
388 int len = avcodec_decode_audio4(_audio_ctx, _frame, &got_frame, pkt);
389 movies_debug(
"avcodec_decode_audio4 returned " << len);
391 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) 392 av_packet_free(&pkt);
399 }
else if (len == 0) {
408 #ifdef HAVE_SWRESAMPLE 411 bufsize = swr_convert(_resample_ctx, (uint8_t **)&_buffer, _buffer_size / 2, (
const uint8_t**)_frame->extended_data, _frame->nb_samples);
412 bufsize *= _audio_channels * 2;
416 bufsize = _frame->linesize[0];
417 memcpy(_buffer, _frame->data[0], bufsize);
419 #if LIBAVUTIL_VERSION_INT > AV_VERSION_INT(52, 19, 100) 420 av_frame_unref(_frame);
425 _buffer_tail = (bufsize/2);
437 int64_t target_ts = (int64_t)(t / _audio_timebase);
438 if (target_ts < (int64_t)(_initial_dts)) {
440 target_ts = _initial_dts;
442 if (av_seek_frame(_format_ctx, _audio_index, target_ts, AVSEEK_FLAG_BACKWARD) < 0) {
443 ffmpeg_cat.error() <<
"Seek failure. Shutting down movie.\n";
447 avcodec_flush_buffers(_audio_ctx);
451 double ts = _packet->dts * _audio_timebase;
453 int skip = (int)((t-ts) * _audio_rate);
467 int desired = n * _audio_channels;
469 while (desired > 0) {
470 if (_buffer_head == _buffer_tail) {
471 if(!reload_buffer()){
474 movies_debug(
"read_samples() desired samples: " << desired <<
" N:" << n);
476 int available = _buffer_tail - _buffer_head;
477 int ncopy = (desired > available) ? available : desired;
479 if (data !=
nullptr) {
480 memcpy(data, _buffer + _buffer_head, ncopy * 2);
484 _buffer_head += ncopy;
virtual void read_samples(int n, int16_t *data)
Read audio samples from the stream.
virtual void seek(double offset)
Seeks to a target location.
bool open_vfs(const Filename &filename)
Opens the movie file via Panda's VFS.
A stream that generates a sequence of audio samples.
void close()
Explicitly closes the opened file.
virtual ~FfmpegAudioCursor()
xxx
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A MovieAudio is actually any source that provides a sequence of audio samples.
FfmpegAudioCursor(FfmpegAudio *src)
xxx
AVFormatContext * get_format_context() const
Returns a pointer to the opened ffmpeg context, or NULL if the file was not successfully opened.
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.