19 #include <libavutil/dict.h>
20 #include <libavutil/opt.h>
21 #include <libavcodec/avcodec.h>
22 #include <libavformat/avformat.h>
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 const 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
135 if (ffmpeg_cat.is_debug()) {
137 <<
"Codec does not use signed 16-bit sample format. Setting up swresample context.\n";
140 _resample_ctx = swr_alloc();
141 av_opt_set_int(_resample_ctx,
"in_channel_count", _audio_channels, 0);
142 av_opt_set_int(_resample_ctx,
"out_channel_count", _audio_channels, 0);
143 av_opt_set_int(_resample_ctx,
"in_channel_layout", _audio_ctx->channel_layout, 0);
144 av_opt_set_int(_resample_ctx,
"out_channel_layout", _audio_ctx->channel_layout, 0);
145 av_opt_set_int(_resample_ctx,
"in_sample_rate", _audio_ctx->sample_rate, 0);
146 av_opt_set_int(_resample_ctx,
"out_sample_rate", _audio_ctx->sample_rate, 0);
147 av_opt_set_sample_fmt(_resample_ctx,
"in_sample_fmt", _audio_ctx->sample_fmt, 0);
148 av_opt_set_sample_fmt(_resample_ctx,
"out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
150 if (swr_init(_resample_ctx) != 0) {
152 <<
"Failed to set up resample context.\n";
153 _resample_ctx =
nullptr;
157 <<
"Codec does not use signed 16-bit sample format, but support for libswresample has not been enabled.\n";
161 _length = (_format_ctx->duration * 1.0) / AV_TIME_BASE;
163 _can_seek_fast =
true;
165#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101)
166 _frame = av_frame_alloc();
168 _frame = avcodec_alloc_frame();
171#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100)
172 _packet = av_packet_alloc();
174 _packet =
new AVPacket;
177 _buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE / 2;
178 _buffer_alloc =
new int16_t[_buffer_size + 64];
181 if ((_packet ==
nullptr)||(_buffer_alloc ==
nullptr)) {
185 memset(_packet, 0,
sizeof(AVPacket));
189 _buffer = _buffer_alloc;
190 while (((
size_t)_buffer) & 31) {
195 _initial_dts = _packet->dts;
213void FfmpegAudioCursor::
215 if (_audio_ctx && _audio_ctx->codec) {
216#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100)
218 avcodec_send_packet(_audio_ctx,
nullptr);
219 while (avcodec_receive_frame(_audio_ctx, _frame) == 0) {}
220 avcodec_flush_buffers(_audio_ctx);
223 avcodec_close(_audio_ctx);
224#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 52, 0)
225 avcodec_free_context(&_audio_ctx);
230 _audio_ctx =
nullptr;
233#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101)
234 av_frame_free(&_frame);
236 avcodec_free_frame(&_frame);
242#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100)
243 av_packet_free(&_packet);
246 av_free_packet(_packet);
254 delete[] _buffer_alloc;
255 _buffer_alloc =
nullptr;
261 _format_ctx =
nullptr;
264#ifdef HAVE_SWRESAMPLE
266 swr_free(&_resample_ctx);
267 _resample_ctx =
nullptr;
278void FfmpegAudioCursor::
281#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100)
282 av_packet_unref(_packet);
284 av_free_packet(_packet);
287 while (av_read_frame(_format_ctx, _packet) >= 0) {
288 if (_packet->stream_index == _audio_index) {
289 _packet_size = _packet->size;
290 _packet_data = _packet->data;
293#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100)
294 av_packet_unref(_packet);
296 av_free_packet(_packet);
299 _packet->data =
nullptr;
301 _packet_data =
nullptr;
309bool FfmpegAudioCursor::
311#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100)
320 while (_packet->data !=
nullptr) {
321 ret = avcodec_send_packet(_audio_ctx, _packet);
330 if (_packet->data ==
nullptr) {
332 ret = avcodec_send_packet(_audio_ctx,
nullptr);
337 if ((ret != 0) && (ret != AVERROR(EAGAIN))) {
340 <<
"avcodec_send_packet returned " << ret <<
"\n";
345 ret = avcodec_receive_frame(_audio_ctx, _frame);
347 if (ret == AVERROR_EOF) {
349 nassertr(_packet->data ==
nullptr,
false);
353 _buffer_tail = _buffer_size;
354 memset(_buffer, 0, _buffer_size * 2);
357 }
else if (ret != 0) {
360 <<
"avcodec_receive_frame returned " << ret <<
"\n";
370 if (_packet->data ==
nullptr) {
372 _buffer_tail = _buffer_size;
373 memset(_buffer, 0, _buffer_size * 2);
375 }
else if (_packet_size == 0) {
380#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100)
381 pkt = av_packet_alloc();
387 pkt->data = _packet_data;
388 pkt->size = _packet_size;
390 int len = avcodec_decode_audio4(_audio_ctx, _frame, &got_frame, pkt);
391 movies_debug(
"avcodec_decode_audio4 returned " << len);
393#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100)
394 av_packet_free(&pkt);
401 }
else if (len == 0) {
410#ifdef HAVE_SWRESAMPLE
413 bufsize = swr_convert(_resample_ctx, (uint8_t **)&_buffer, _buffer_size / 2, (
const uint8_t**)_frame->extended_data, _frame->nb_samples);
414 bufsize *= _audio_channels * 2;
418 bufsize = _frame->linesize[0];
419 memcpy(_buffer, _frame->data[0], bufsize);
421#if LIBAVUTIL_VERSION_INT > AV_VERSION_INT(52, 19, 100)
422 av_frame_unref(_frame);
427 _buffer_tail = (bufsize/2);
439 int64_t target_ts = (int64_t)(t / _audio_timebase);
440 if (target_ts < (int64_t)(_initial_dts)) {
442 target_ts = _initial_dts;
444 if (av_seek_frame(_format_ctx, _audio_index, target_ts, AVSEEK_FLAG_BACKWARD) < 0) {
445 ffmpeg_cat.error() <<
"Seek failure. Shutting down movie.\n";
449 avcodec_flush_buffers(_audio_ctx);
453 double ts = _packet->dts * _audio_timebase;
455 int skip = (int)((t-ts) * _audio_rate);
469 int desired = n * _audio_channels;
471 while (desired > 0) {
472 if (_buffer_head == _buffer_tail) {
473 if(!reload_buffer()){
476 movies_debug(
"read_samples() desired samples: " << desired <<
" N:" << n);
478 int available = _buffer_tail - _buffer_head;
479 int ncopy = (desired > available) ? available : desired;
481 if (data !=
nullptr) {
482 memcpy(data, _buffer + _buffer_head, ncopy * 2);
486 _buffer_head += ncopy;
virtual void seek(double offset)
Seeks to a target location.
FfmpegAudioCursor(FfmpegAudio *src)
xxx
virtual void read_samples(int n, int16_t *data)
Read audio samples from the stream.
virtual ~FfmpegAudioCursor()
xxx
A stream that generates a sequence of audio samples.
bool open_vfs(const Filename &filename)
Opens the movie file via Panda's VFS.
AVFormatContext * get_format_context() const
Returns a pointer to the opened ffmpeg context, or NULL if the file was not successfully opened.
void close()
Explicitly closes the opened file.
A MovieAudio is actually any source that provides a sequence of audio samples.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.