mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
avformat: add argo_asf muxer
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com> Reviewed-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
parent
62da99e1d0
commit
0549daa71b
@ -12,6 +12,7 @@ version <next>:
|
||||
- AV1 encoding support SVT-AV1
|
||||
- Cineform HD encoder
|
||||
- ADPCM Argonaut Games encoder
|
||||
- Argonaut Games ASF muxer
|
||||
|
||||
|
||||
version 4.3:
|
||||
|
@ -103,6 +103,7 @@ OBJS-$(CONFIG_APTX_HD_DEMUXER) += aptxdec.o rawdec.o
|
||||
OBJS-$(CONFIG_APTX_HD_MUXER) += rawenc.o
|
||||
OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o
|
||||
OBJS-$(CONFIG_ARGO_ASF_DEMUXER) += argo_asf.o
|
||||
OBJS-$(CONFIG_ARGO_ASF_MUXER) += argo_asf.o
|
||||
OBJS-$(CONFIG_ASF_DEMUXER) += asfdec_f.o asf.o asfcrypt.o \
|
||||
avlanguage.o
|
||||
OBJS-$(CONFIG_ASF_O_DEMUXER) += asfdec_o.o asf.o asfcrypt.o \
|
||||
|
@ -64,6 +64,7 @@ extern AVInputFormat ff_aptx_hd_demuxer;
|
||||
extern AVOutputFormat ff_aptx_hd_muxer;
|
||||
extern AVInputFormat ff_aqtitle_demuxer;
|
||||
extern AVInputFormat ff_argo_asf_demuxer;
|
||||
extern AVOutputFormat ff_argo_asf_muxer;
|
||||
extern AVInputFormat ff_asf_demuxer;
|
||||
extern AVOutputFormat ff_asf_muxer;
|
||||
extern AVInputFormat ff_asf_o_demuxer;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Argonaut Games ASF demuxer
|
||||
* Argonaut Games ASF (de)muxer
|
||||
*
|
||||
* Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com)
|
||||
*
|
||||
@ -63,6 +63,7 @@ typedef struct ArgoASFDemuxContext {
|
||||
uint32_t blocks_read;
|
||||
} ArgoASFDemuxContext;
|
||||
|
||||
#if CONFIG_ARGO_ASF_DEMUXER
|
||||
static void argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *buf)
|
||||
{
|
||||
hdr->magic = AV_RL32(buf + 0);
|
||||
@ -254,3 +255,127 @@ AVInputFormat ff_argo_asf_demuxer = {
|
||||
.read_header = argo_asf_read_header,
|
||||
.read_packet = argo_asf_read_packet
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_ARGO_ASF_MUXER
|
||||
static int argo_asf_write_init(AVFormatContext *s)
|
||||
{
|
||||
const AVCodecParameters *par;
|
||||
|
||||
if (s->nb_streams != 1) {
|
||||
av_log(s, AV_LOG_ERROR, "ASF files have exactly one stream\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
par = s->streams[0]->codecpar;
|
||||
|
||||
if (par->codec_id != AV_CODEC_ID_ADPCM_ARGO) {
|
||||
av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
|
||||
avcodec_get_name(par->codec_id));
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (par->channels > 2) {
|
||||
av_log(s, AV_LOG_ERROR, "ASF files only support up to 2 channels\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (par->sample_rate > UINT16_MAX) {
|
||||
av_log(s, AV_LOG_ERROR, "Sample rate too large\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
|
||||
av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void argo_asf_write_file_header(const ArgoASFFileHeader *fhdr, AVIOContext *pb)
|
||||
{
|
||||
avio_wl32( pb, fhdr->magic);
|
||||
avio_wl16( pb, fhdr->version_major);
|
||||
avio_wl16( pb, fhdr->version_minor);
|
||||
avio_wl32( pb, fhdr->num_chunks);
|
||||
avio_wl32( pb, fhdr->chunk_offset);
|
||||
avio_write(pb, fhdr->name, sizeof(fhdr->name));
|
||||
}
|
||||
|
||||
static void argo_asf_write_chunk_header(const ArgoASFChunkHeader *ckhdr, AVIOContext *pb)
|
||||
{
|
||||
avio_wl32(pb, ckhdr->num_blocks);
|
||||
avio_wl32(pb, ckhdr->num_samples);
|
||||
avio_wl32(pb, ckhdr->unk1);
|
||||
avio_wl16(pb, ckhdr->sample_rate);
|
||||
avio_wl16(pb, ckhdr->unk2);
|
||||
avio_wl32(pb, ckhdr->flags);
|
||||
}
|
||||
|
||||
static int argo_asf_write_header(AVFormatContext *s)
|
||||
{
|
||||
const AVCodecParameters *par = s->streams[0]->codecpar;
|
||||
ArgoASFFileHeader fhdr;
|
||||
ArgoASFChunkHeader chdr;
|
||||
|
||||
fhdr.magic = ASF_TAG;
|
||||
fhdr.version_major = 2;
|
||||
fhdr.version_minor = 1;
|
||||
fhdr.num_chunks = 1;
|
||||
fhdr.chunk_offset = ASF_FILE_HEADER_SIZE;
|
||||
strncpy(fhdr.name, av_basename(s->url), FF_ARRAY_ELEMS(fhdr.name));
|
||||
|
||||
chdr.num_blocks = 0;
|
||||
chdr.num_samples = ASF_SAMPLE_COUNT;
|
||||
chdr.unk1 = 0;
|
||||
chdr.sample_rate = par->sample_rate;
|
||||
chdr.unk2 = ~0;
|
||||
chdr.flags = ASF_CF_BITS_PER_SAMPLE | ASF_CF_ALWAYS1;
|
||||
|
||||
if (par->channels == 2)
|
||||
chdr.flags |= ASF_CF_STEREO;
|
||||
|
||||
argo_asf_write_file_header(&fhdr, s->pb);
|
||||
argo_asf_write_chunk_header(&chdr, s->pb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int argo_asf_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
if (pkt->size != 17 * s->streams[0]->codecpar->channels)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (s->streams[0]->nb_frames >= UINT32_MAX)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
avio_write(s->pb, pkt->data, pkt->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int argo_asf_write_trailer(AVFormatContext *s)
|
||||
{
|
||||
int64_t ret;
|
||||
|
||||
if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET) < 0))
|
||||
return ret;
|
||||
|
||||
avio_wl32(s->pb, (uint32_t)s->streams[0]->nb_frames);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVOutputFormat ff_argo_asf_muxer = {
|
||||
.name = "argo_asf",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Argonaut Games ASF"),
|
||||
/*
|
||||
* NB: Can't do this as it conflicts with the actual ASF format.
|
||||
* .extensions = "asf",
|
||||
*/
|
||||
.audio_codec = AV_CODEC_ID_ADPCM_ARGO,
|
||||
.video_codec = AV_CODEC_ID_NONE,
|
||||
.init = argo_asf_write_init,
|
||||
.write_header = argo_asf_write_header,
|
||||
.write_packet = argo_asf_write_packet,
|
||||
.write_trailer = argo_asf_write_trailer
|
||||
};
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
|
||||
// Also please add any ticket numbers that you believe might be affected here
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 58
|
||||
#define LIBAVFORMAT_VERSION_MINOR 49
|
||||
#define LIBAVFORMAT_VERSION_MINOR 50
|
||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
|
Loading…
Reference in New Issue
Block a user