diff options
author | Alexey Yakovenko <waker@users.sourceforge.net> | 2013-11-09 17:00:35 +0100 |
---|---|---|
committer | Alexey Yakovenko <waker@users.sourceforge.net> | 2013-11-09 17:00:35 +0100 |
commit | dc255f983cca59d605c60d3f2b3b2d39deb9e6e0 (patch) | |
tree | 53a00579a972070e5f28375938240242093f58a0 /plugins/ffmpeg | |
parent | 5612863563b14b56221a23643d984b429c6f3a07 (diff) |
ffmpeg: added planar sample formats support (required for TAK playback)
Diffstat (limited to 'plugins/ffmpeg')
-rw-r--r-- | plugins/ffmpeg/ffmpeg.c | 38 |
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 |