[FFmpeg-devel] [PATCH 2/3] Add muxer/demuxer for raw codec2 and .c2 files
Tomas Härdin
tjoppen at acc.umu.se
Mon Jan 15 23:36:33 EET 2018
fre 2018-01-12 klockan 21:21 +0100 skrev Michael Niedermayer:
> On Sat, Dec 23, 2017 at 11:15:35PM +0100, Tomas Härdin wrote:
> >
>
> [...]
> > +static int codec2_read_header_common(AVFormatContext *s, AVStream *st)
> > +{
> > + int mode = avpriv_codec2_mode_from_extradata(st->codecpar->extradata);
> > +
> > + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
> > + st->codecpar->codec_id = AV_CODEC_ID_CODEC2;
> > + st->codecpar->sample_rate = 8000;
> > + st->codecpar->channels = 1;
> > + st->codecpar->format = AV_SAMPLE_FMT_S16;
> > + st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
> > + st->codecpar->bit_rate = avpriv_codec2_mode_bit_rate(s, mode);
> > + st->codecpar->frame_size = avpriv_codec2_mode_frame_size(s, mode);
> > + st->codecpar->block_align = avpriv_codec2_mode_block_align(s, mode);
> > +
> > + if (st->codecpar->bit_rate <= 0 ||
> > + st->codecpar->frame_size <= 0 ||
> > + st->codecpar->block_align <= 0) {
> > + return AVERROR(EINVAL);
> > + }
>
> This should be AVERROR_INVALIDDATA i think
OK, seem reasonable. It will typically be triggered by invalid mode
> > +
> > + avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
> > +
> > + //replicating estimate_timings_from_bit_rate() in utils.c to avoid warnings
> > + if (s->pb && st->codecpar->bit_rate > 0) {
> > + int64_t filesize = avio_size(s->pb);
> > + if (filesize > s->internal->data_offset) {
> > + filesize -= s->internal->data_offset;
> > + st->duration = av_rescale(8 * filesize,
> > + st->time_base.den,
> > + st->codecpar->bit_rate * (int64_t) st->time_base.num);
> > + }
> > + }
>
> Is this exact ?
> or is a calculation from frame_size / block_align more accurate ?
> the most accurate one should be used
bit_rate is derived from block_align and frame_size in codec2utils.c so
either would be fine.
It strikes me that a better solution would be to suppress the
"Estimating duration from bitrate, this may be inaccurate" warning for
CBR formats. Removed this hunk for now.
> > +static int codec2_read_header(AVFormatContext *s)
> > +{
> > + [...]
> > + avio_read(s->pb, st->codecpar->extradata, AVPRIV_CODEC2_EXTRADATA_SIZE);
>
> The return codes from avio_read and not checked
Replaced with ffio_read_size() and checking for AVERROR
mån 2018-01-15 klockan 00:32 +0100 skrev Carl Eugen Hoyos:
> > 2017-12-23 23:15 GMT+01:00 Tomas Härdin <tjoppen at acc.umu.se>:
>
> > +//check for 0xC0DEC2, return non-zero if it doesn't match
> > +static int check_magic(uint8_t *ptr) {
> > + return memcmp(ptr, avpriv_codec2_magic, 3);
>
> AV_RB24(), or do I miss something?
Good idea. Replaced some of the related read/write functions with
avio_rb24/wb24 too
>
> > +static int codec2_probe(AVProbeData *p)
> > +{
> > + int score;
> > +
> > + //must be at least 7 bytes and start wih 0xC0DEC2
> > + if (p->buf_size < AVPRIV_CODEC2_HEADER_SIZE ||
>
> This check is unneeded.
Good, removed
> > check_magic(p->buf)) {
>
> + return 0;
> + }
> +
> + //no .c2 files prior to 0.8
>
> + if (p->buf[3] == 0 && p->buf[4] < 8) {
>
> You chose to define the versions, please use the defines here.
Fixed
> + return 0;
> + }
> +
> + //give a poor score if major version doesn't match
> + //this allows such files to be detected at least, even if we
> can't do much with them
> + if (p->buf[3] != EXPECTED_CODEC2_MAJOR_VERSION) {
> + return AVPROBE_SCORE_MAX/10;
> + }
>
> That may be ok.
Actually, I feel like being more strict and coordinating future format
changes with the FreeDV folks. Changed this to rejecting major != 0.
> + //if the minor version is known, no unknown mode is used and no
> flags are set then -> max score,
> + //else penalize 20% for each byte outside of expectations
> + //this way if only the first four bytes are OK then we're
> slightly less than AVPROBE_SCORE_MAX/2
> + //cap score at max-1 unless file extension is .c2
> + score = AVPROBE_SCORE_MAX;
>
> + if (!av_match_ext(p->filename, "c2")) score -= 1;
>
> We don't do this for any other demuxer, if this makes sense, it should
> be done in general code, not for a specific demuxer imo.
Removed it, see below.
> + if (p->buf[4] > EXPECTED_CODEC2_MINOR_VERSION) score -=
> AVPROBE_SCORE_MAX/5;
> + if (p->buf[5] > AVPRIV_CODEC2_MODE_MAX) score -=
> AVPROBE_SCORE_MAX/5;
> + if (p->buf[6] != 0) score -=
> AVPROBE_SCORE_MAX/5;
> + return score;
>
> Imo, this is too complicated:
> If the first 32bit are correct, return MAX/2, for 24bit, return less
>
> Returning MAX for less than 64bit seems wrong to me.
I think my reasoning was that if everything is within what the FreeDV
tools are currently outputting then a higher score may be OK. On the
other hand I can lobby the FreeDV list for more identifying bits
together with a major version bump in the future, if needed.
Changed to returning MAX/2 since we have C0 DE C2 00. Updated patch
attached.
/Tomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Add-muxer-demuxer-for-raw-codec2-and-.c2-files.patch
Type: text/x-patch
Size: 14194 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20180115/915b4f33/attachment.bin>
More information about the ffmpeg-devel
mailing list