summaryrefslogtreecommitdiff
path: root/plugins/ffmpeg
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <waker@users.sourceforge.net>2013-11-09 17:00:35 +0100
committerGravatar Alexey Yakovenko <waker@users.sourceforge.net>2013-11-09 17:00:35 +0100
commitdc255f983cca59d605c60d3f2b3b2d39deb9e6e0 (patch)
tree53a00579a972070e5f28375938240242093f58a0 /plugins/ffmpeg
parent5612863563b14b56221a23643d984b429c6f3a07 (diff)
ffmpeg: added planar sample formats support (required for TAK playback)
Diffstat (limited to 'plugins/ffmpeg')
-rw-r--r--plugins/ffmpeg/ffmpeg.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/plugins/ffmpeg/ffmpeg.c b/plugins/ffmpeg/ffmpeg.c
index e018ffc9..3c9d3e0b 100644
--- a/plugins/ffmpeg/ffmpeg.c
+++ b/plugins/ffmpeg/ffmpeg.c
@@ -97,6 +97,7 @@ typedef struct {
AVCodecContext *ctx;
AVFormatContext *fctx;
AVPacket pkt;
+ AVFrame *frame;
int stream_id;
int left_in_packet;
@@ -226,6 +227,8 @@ ffmpeg_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
return -1;
}
+ info->frame = avcodec_alloc_frame();
+
// fill in mandatory plugin fields
_info->plugin = &plugin;
_info->readpos = 0;
@@ -263,6 +266,9 @@ ffmpeg_free (DB_fileinfo_t *_info) {
trace ("ffmpeg: free\n");
ffmpeg_info_t *info = (ffmpeg_info_t*)_info;
if (info) {
+ if (info->frame) {
+ avcodec_free_frame(&info->frame);
+ }
if (info->buffer) {
free (info->buffer);
}
@@ -320,7 +326,35 @@ ffmpeg_read (DB_fileinfo_t *_info, char *bytes, int size) {
int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int len;
//trace ("in: out_size=%d(%d), size=%d\n", out_size, AVCODEC_MAX_AUDIO_FRAME_SIZE, size);
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0)
+
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 25, 0)
+ int got_frame = 0;
+ len = avcodec_decode_audio4(info->ctx, info->frame, &got_frame, &info->pkt);
+ if (len > 0) {
+ if (av_sample_fmt_is_planar(info->ctx->sample_fmt)) {
+ out_size = 0;
+ for (int c = 0; c < info->ctx->channels; c++) {
+ for (int i = 0; i < info->frame->nb_samples; i++) {
+ int32_t sample = ((int32_t *)info->frame->extended_data[c])[i];
+ if (_info->fmt.bps == 16) {
+ int16_t outsample = (int16_t)(sample >> 16);
+ ((int16_t*)info->buffer)[i*info->ctx->channels+c] = outsample;
+ out_size += 2;
+ }
+ else if (_info->fmt.bps == 32) {
+ ((int32_t*)info->buffer)[i*info->ctx->channels+c] = sample;
+ out_size += 4;
+ }
+ }
+ }
+ }
+ else {
+ out_size = info->frame->nb_samples * av_get_bytes_per_sample(info->frame->format);
+ memcpy (info->buffer, info->frame->extended_data[0], out_size);
+ }
+ }
+
+#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0)
len = avcodec_decode_audio3 (info->ctx, (int16_t *)info->buffer, &out_size, &info->pkt);
#else
len = avcodec_decode_audio2 (info->ctx, (int16_t *)info->buffer, &out_size, info->pkt.data, info->pkt.size);
@@ -801,7 +835,7 @@ ffmpeg_start (void) {
#endif
av_register_all ();
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(54, 6, 0)
-#warning FFMPEG-0.11 is no longer exposing register_protocol API, which means that it cant work with MMS and HTTP plugins. if you need this functionality, please downgrade FFMPEG, and rebuild the FFMPEG plugin
+#warning FFMPEG-0.11 and higher does not expose register_protocol API, which means that it cant work with MMS and HTTP plugins. If you need this functionality, please downgrade FFMPEG to version 0.10 or less, and rebuild the FFMPEG plugin
#elif LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52, 69, 0)
av_register_protocol2 (&vfswrapper, sizeof(vfswrapper));
#else