[FFmpeg-devel] [RFC] av_get_bits_per_sample() questions
Stefano Sabatini
stefano.sabatini-lala at poste.it
Mon Jun 6 00:31:46 CEST 2011
On date Sunday 2011-03-13 17:20:51 -0400, Justin Ruggles wrote:
> On 03/13/2011 04:59 PM, Stefano Sabatini wrote:
>
> > Hi,
> >
> > just discovered that we have:
> >
> > int av_get_bits_per_sample(enum CodecID codec_id);
> > and:
> > int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt);
> >
> > av_get_bits_per_sample() return per-codec bits per sample, and is only
> > used in pcm:
> > ./pcm.c:48: avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id);
> > ./pcm.c:93: sample_size = av_get_bits_per_sample(avctx->codec->id)/8;
> > ./pcm.c:232: avctx->bits_per_raw_sample = av_get_bits_per_sample(avctx->codec->id);
> > ./pcm.c:285: sample_size = av_get_bits_per_sample(avctx->codec_id)/8;
> > ./pcm.c:287: /* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */
> >
> > Since this is a per-codec property I wonder if it would be a better
> > idea to put the information in the codec context and drop the
> > function.
>
> I agree it's ugly.
>
> I think it's supposed to just be a convenience function for libavformat
> and other muxers/demuxers to be able to handle raw pcm/adpcm/dpcm more
> easily. I think it would be ok to redefine how bits_per_raw_sample is
> used as an alternative. Currently it only has meaning for encoding with
> sample_fmt==SAMPLE_FMT_S32, but I think it would be better if that were
> expanded to be valid for any sample format with any raw pcm-like codec
> (ADPCM, DPCM, PCM). Then I think we could set that in the decoders and
> make the function return bits_per_raw_sample just for backwards
> compatibility.
Is there a specific reason for preferring
AVCodecContext.bits_per_raw_sample over bits_per_coded_sample?, I can't
say exactly which is the difference, the doxy is not particularly helpful:
/**
* bits per sample/pixel from the demuxer (needed for huffyuv).
* - encoding: Set by libavcodec.
* - decoding: Set by user.
*/
int bits_per_coded_sample;
...
/**
* Bits per sample/pixel of internal libavcodec pixel/sample format.
* This field is applicable only when sample_fmt is AV_SAMPLE_FMT_S32.
* - encoding: set by user.
* - decoding: set by libavcodec.
*/
int bits_per_raw_sample;
Currently the behavior of av_get_bits_per_sample(codec_id) is to
return a value expressing the compressed sample size for PCM and
ADPCM audio codecs (it will be 0 otherwise).
The function it is sometimes called *before* the codec context is
opened, like in mov.c:ff_mov_read_stsd_entries():
bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
if (bits_per_sample) {
st->codec->bits_per_coded_sample = bits_per_sample;
sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
}
this code sets sc->sample_size only for AD/PCM codecs, at this stage
the codec was not still initialized so bits_per_coded_sample can't
yet be set in the decoder.
I see different solutions:
1) remove av_get_bits_per_sample(), and directly access
avctx->bits_per_coded_context, which is set during the decoder
initialization.
In the above case we need the property value *before* to
actually open the decoder, so we may do:
if (codec id is AD/PCM) {
bits_per_sample = ff_pcm_get_bits_per_coded_sample(codec_id);
sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
}
_assuming_ this is indeed the correct semantics (Baptiste?).
2) leave the av_get_bits_per_sample() function, possibly give a more
meaningful name to it, something like
avcodec_get_bits_per_coded_sample() for avoiding confusion with
av_get_bits/bytes_per_sample()
More information about the ffmpeg-devel
mailing list