[FFmpeg-devel] [PATCH] PSMF audio support, trac ticket #3233
Michael Niedermayer
michaelni at gmx.at
Tue Dec 2 02:31:14 CET 2014
On Tue, Dec 02, 2014 at 01:13:56AM +0100, Maxim Polijakowski wrote:
> Hello crews,
>
> attached patch enables PSMF audio demuxing/decoding. As suggested by
> Carl Eugen Hoyos, mpeg.c has been extended to identify ATRAC3+
> streams inside of PSMF files. Additionally, a ATRAC3+ parser has
> been implemented in order to extract Atrac3+ frames from
> PRIVATE_STREAM_1 packets.
>
> It works well for these samples: http://samples.ffmpeg.org/PSMF
>
> The code is not perfect and can be surely improved a lot. I hope
> though that my work goes in the right direction :))
>
> Best regards
> Maxim
> libavcodec/Makefile | 1
> libavcodec/allcodecs.c | 1
> libavcodec/atrac3plus_parser.c | 153 +++++++++++++++++++++++++++++++++++++++++
> libavformat/mpeg.c | 27 ++++++-
> 4 files changed, 181 insertions(+), 1 deletion(-)
> edf831c5b273b61c8a09c3c0c669d81727b3d87e 0002-mpeg-add-experimental-support-for-PSMF-audio.patch
> From 9fef4512d8e5e7e8cc93a8c108d67811931cc05c Mon Sep 17 00:00:00 2001
> From: Maxim Poliakovski <maximumspatium at googlemail.com>
> Date: Mon, 24 Nov 2014 01:20:21 +0100
> Subject: [PATCH 2/2] mpeg: add experimental support for PSMF audio.
>
> ---
> libavcodec/Makefile | 1 +
> libavcodec/allcodecs.c | 1 +
> libavcodec/atrac3plus_parser.c | 153 +++++++++++++++++++++++++++++++++++++++++
> libavformat/mpeg.c | 27 +++++++-
> 4 files changed, 181 insertions(+), 1 deletion(-)
> create mode 100644 libavcodec/atrac3plus_parser.c
>
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index fa0f53d..c9520d7 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -775,6 +775,7 @@ OBJS-$(CONFIG_AAC_LATM_PARSER) += latm_parser.o
> OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \
> aac_ac3_parser.o
> OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o
> +OBJS-$(CONFIG_ATRAC3P_PARSER) += atrac3plus_parser.o
> OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o
> OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o
> OBJS-$(CONFIG_COOK_PARSER) += cook_parser.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 0d39d33..a5a44af 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -544,6 +544,7 @@ void avcodec_register_all(void)
> REGISTER_PARSER(AAC_LATM, aac_latm);
> REGISTER_PARSER(AC3, ac3);
> REGISTER_PARSER(ADX, adx);
> + REGISTER_PARSER(ATRAC3P, atrac3p);
> REGISTER_PARSER(BMP, bmp);
> REGISTER_PARSER(CAVSVIDEO, cavsvideo);
> REGISTER_PARSER(COOK, cook);
> diff --git a/libavcodec/atrac3plus_parser.c b/libavcodec/atrac3plus_parser.c
> new file mode 100644
> index 0000000..01fcad4
> --- /dev/null
> +++ b/libavcodec/atrac3plus_parser.c
> @@ -0,0 +1,153 @@
> +/*
> + * Copyright (C) 2014 Maxim Poliakovski
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include "parser.h"
> +#include "get_bits.h"
> +#include "libavformat/oma.h"
libavformat can use things from libavcodec but
libavcodec cannot use things from libavformat as it doesnt depend on
it, libavcodec can be used alone without libavformat
so some things may need to be moved to libavcodec in a seperate patch
before this
[...]
> +static int ff_atrac3p_parse(AVCodecParserContext *s,
> + AVCodecContext *avctx,
> + const uint8_t **poutbuf, int *poutbuf_size,
> + const uint8_t *buf, int buf_size)
> +{
> + Atrac3PlusParseContext *ctx = s->priv_data;
> + const uint8_t *hdr_buf = buf;
> + size_t bytes_remain;
> + int frame_size, hdr_bytes = 8;
> + int next = 0;
> +
> + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES || !buf_size) {
> + next = buf_size;
> + } else {
> + if (buf_size >= 2) {
> + bytes_remain = AV_RB16(buf);
> +
> + if (bytes_remain != 0xFD0) {
> + next += 2;
> + buf += 2;
> + buf_size -= 2;
> + hdr_buf = buf;
> +
> + if (bytes_remain && !ctx->pc.index && !ctx->hdr_bytes_needed) {
> + av_log(avctx, AV_LOG_ERROR,
> + "2nd frame portion found but the 1st one is missing!\n");
> + return AVERROR_INVALIDDATA;
> + }
> +
> + if (ctx->hdr_bytes_needed) {
> + if (buf_size >= ctx->hdr_bytes_needed) {
> + memcpy(&ctx->hdr[8 - ctx->hdr_bytes_needed],
> + buf, ctx->hdr_bytes_needed);
> + hdr_bytes = ctx->hdr_bytes_needed;
> + ctx->hdr_bytes_needed = 0;
> + hdr_buf = ctx->hdr;
> + }
> + } else if (bytes_remain) {
> + if (buf_size < bytes_remain) {
> + av_log(avctx, AV_LOG_ERROR,
> + "Couldn't combine frame: bytes needed=%d, bytes supplied=%d\n",
> + bytes_remain, buf_size);
> + return AVERROR_INVALIDDATA;
> + }
> +
> + next += bytes_remain;
> + ff_combine_frame(&ctx->pc, bytes_remain, &buf, &buf_size);
> +
> + *poutbuf = buf;
> + *poutbuf_size = buf_size;
> + return next;
> + }
> + }
> + }
> +
> + if (buf_size < hdr_bytes) {
> + /* looks like we got an incomplete header */
> + memcpy(ctx->hdr, buf, buf_size);
> + ctx->hdr_bytes_needed = 8 - buf_size;
> + *poutbuf = NULL;
> + *poutbuf_size = 0;
> + return buf_size;
> + }
> +
> + if (parse_sound_frame_header(ctx, hdr_buf)) {
> + av_log(avctx, AV_LOG_ERROR, "Invalid sound frame header!\n");
> + return AVERROR_INVALIDDATA;
> + }
> +
> + avctx->sample_rate = ctx->sample_rate;
> + avctx->block_align = ctx->frame_size;
> + avctx->bit_rate = ctx->sample_rate * ctx->frame_size * 8 / 2048;
> + avctx->channels = ff_oma_chid_to_num_channels[ctx->channel_id - 1];
> + avctx->channel_layout = ff_oma_chid_to_native_layout[ctx->channel_id - 1];
if you set these from the parser instead of the decoder then you
must be a bit careful as the decoder can run in a seperate thread as
the parser so the parser cannot change anything midstream it could
only set the parameters once before the decoder can start
(that is when the parameters where not set before)
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The bravest are surely those who have the clearest vision
of what is before them, glory and danger alike, and yet
notwithstanding go out to meet it. -- Thucydides
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20141202/8fef387b/attachment.asc>
More information about the ffmpeg-devel
mailing list