Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * WavPack muxer
  3.  * Copyright (c) 2013 Konstantin Shishkov <kostya.shishkov@gmail.com>
  4.  * Copyright (c) 2012 Paul B Mahol
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  */
  22.  
  23. #include "libavutil/attributes.h"
  24.  
  25. #include "apetag.h"
  26. #include "avformat.h"
  27. #include "wv.h"
  28.  
  29. typedef struct WvMuxContext {
  30.     int64_t samples;
  31. } WvMuxContext;
  32.  
  33. static av_cold int wv_write_header(AVFormatContext *ctx)
  34. {
  35.     if (ctx->nb_streams > 1 ||
  36.         ctx->streams[0]->codec->codec_id != AV_CODEC_ID_WAVPACK) {
  37.         av_log(ctx, AV_LOG_ERROR, "This muxer only supports a single WavPack stream.\n");
  38.         return AVERROR(EINVAL);
  39.     }
  40.  
  41.     return 0;
  42. }
  43.  
  44. static int wv_write_packet(AVFormatContext *ctx, AVPacket *pkt)
  45. {
  46.     WvMuxContext *s = ctx->priv_data;
  47.     WvHeader header;
  48.     int ret;
  49.  
  50.     if (pkt->size < WV_HEADER_SIZE ||
  51.         (ret = ff_wv_parse_header(&header, pkt->data)) < 0) {
  52.         av_log(ctx, AV_LOG_ERROR, "Invalid WavPack packet.\n");
  53.         return AVERROR(EINVAL);
  54.     }
  55.     s->samples += header.samples;
  56.  
  57.     avio_write(ctx->pb, pkt->data, pkt->size);
  58.  
  59.     return 0;
  60. }
  61.  
  62. static av_cold int wv_write_trailer(AVFormatContext *ctx)
  63. {
  64.     WvMuxContext *s = ctx->priv_data;
  65.  
  66.     /* update total number of samples in the first block */
  67.     if (ctx->pb->seekable && s->samples &&
  68.         s->samples < UINT32_MAX) {
  69.         int64_t pos = avio_tell(ctx->pb);
  70.         avio_seek(ctx->pb, 12, SEEK_SET);
  71.         avio_wl32(ctx->pb, s->samples);
  72.         avio_seek(ctx->pb, pos, SEEK_SET);
  73.     }
  74.  
  75.     ff_ape_write_tag(ctx);
  76.     return 0;
  77. }
  78.  
  79. AVOutputFormat ff_wv_muxer = {
  80.     .name              = "wv",
  81.     .long_name         = NULL_IF_CONFIG_SMALL("raw WavPack"),
  82.     .mime_type         = "audio/x-wavpack",
  83.     .extensions        = "wv",
  84.     .priv_data_size    = sizeof(WvMuxContext),
  85.     .audio_codec       = AV_CODEC_ID_WAVPACK,
  86.     .video_codec       = AV_CODEC_ID_NONE,
  87.     .write_header      = wv_write_header,
  88.     .write_packet      = wv_write_packet,
  89.     .write_trailer     = wv_write_trailer,
  90.     .flags             = AVFMT_NOTIMESTAMPS,
  91. };
  92.