00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avformat.h"
00023 #include "internal.h"
00024 #include "avio_internal.h"
00025 #include "apetag.h"
00026
00027 typedef struct{
00028 uint32_t duration;
00029 int off;
00030 } WVMuxContext;
00031
00032 static int write_header(AVFormatContext *s)
00033 {
00034 WVMuxContext *wc = s->priv_data;
00035 AVCodecContext *codec = s->streams[0]->codec;
00036
00037 if (s->nb_streams > 1) {
00038 av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
00039 return AVERROR(EINVAL);
00040 }
00041 if (codec->codec_id != AV_CODEC_ID_WAVPACK) {
00042 av_log(s, AV_LOG_ERROR, "unsupported codec\n");
00043 return AVERROR(EINVAL);
00044 }
00045 if (codec->extradata_size > 0) {
00046 av_log_missing_feature(s, "remuxing from matroska container", 0);
00047 return AVERROR_PATCHWELCOME;
00048 }
00049 wc->off = codec->channels > 2 ? 4 : 0;
00050 avpriv_set_pts_info(s->streams[0], 64, 1, codec->sample_rate);
00051
00052 return 0;
00053 }
00054
00055 static int write_packet(AVFormatContext *s, AVPacket *pkt)
00056 {
00057 WVMuxContext *wc = s->priv_data;
00058 AVIOContext *pb = s->pb;
00059
00060 wc->duration += pkt->duration;
00061 ffio_wfourcc(pb, "wvpk");
00062 avio_wl32(pb, pkt->size + 12 + wc->off);
00063 avio_wl16(pb, 0x410);
00064 avio_w8(pb, 0);
00065 avio_w8(pb, 0);
00066 avio_wl32(pb, -1);
00067 avio_wl32(pb, pkt->pts);
00068 avio_write(s->pb, pkt->data, pkt->size);
00069 avio_flush(s->pb);
00070
00071 return 0;
00072 }
00073
00074 static int write_trailer(AVFormatContext *s)
00075 {
00076 WVMuxContext *wc = s->priv_data;
00077 AVIOContext *pb = s->pb;
00078
00079 ff_ape_write(s);
00080
00081 if (pb->seekable) {
00082 avio_seek(pb, 12, SEEK_SET);
00083 avio_wl32(pb, wc->duration);
00084 avio_flush(pb);
00085 }
00086
00087 return 0;
00088 }
00089
00090 AVOutputFormat ff_wv_muxer = {
00091 .name = "wv",
00092 .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
00093 .priv_data_size = sizeof(WVMuxContext),
00094 .extensions = "wv",
00095 .audio_codec = AV_CODEC_ID_WAVPACK,
00096 .video_codec = AV_CODEC_ID_NONE,
00097 .write_header = write_header,
00098 .write_packet = write_packet,
00099 .write_trailer = write_trailer,
00100 };