This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 753589abc9f2f936464a25c688ffeac33ea99a67 Author: Simon Capriotti <[email protected]> AuthorDate: Sun May 31 18:57:53 2026 +0200 Commit: michaelni <[email protected]> CommitDate: Sat Nov 7 20:27:32 2026 +0000 avcodec/pcm-bluray: split parsing of the header into separate function Makes it possible to decode raw HDMV PCM frames without a header at the start Signed-off-by: Simon Capriotti <[email protected]> --- libavcodec/pcm-bluray.c | 186 +++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 89 deletions(-) diff --git a/libavcodec/pcm-bluray.c b/libavcodec/pcm-bluray.c index fba7c8656d..e91d54f937 100644 --- a/libavcodec/pcm-bluray.c +++ b/libavcodec/pcm-bluray.c @@ -46,84 +46,8 @@ * 3/4+lfe L R C LS Rls Rrs RS lfe */ -/** - * Parse the header of a LPCM frame read from a Blu-ray MPEG-TS stream - * @param avctx the codec context - * @param header pointer to the first four bytes of the data packet - */ -static int pcm_bluray_parse_header(AVCodecContext *avctx, - const uint8_t *header) -{ - static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 }; - static const AVChannelLayout channel_layouts[16] = { - { 0 }, AV_CHANNEL_LAYOUT_MONO, { 0 }, - AV_CHANNEL_LAYOUT_STEREO, AV_CHANNEL_LAYOUT_SURROUND, AV_CHANNEL_LAYOUT_2_1, - AV_CHANNEL_LAYOUT_4POINT0, AV_CHANNEL_LAYOUT_2_2, AV_CHANNEL_LAYOUT_5POINT0, - AV_CHANNEL_LAYOUT_5POINT1, AV_CHANNEL_LAYOUT_7POINT0, AV_CHANNEL_LAYOUT_7POINT1, - { 0 }, { 0 }, { 0 }, { 0 }, - }; - uint8_t channel_layout = header[2] >> 4; - - if (avctx->debug & FF_DEBUG_PICT_INFO) - ff_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n", - header[0], header[1], header[2], header[3]); - - /* get the sample depth and derive the sample format from it */ - avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6]; - if (!(avctx->bits_per_coded_sample == 16 || avctx->bits_per_coded_sample == 24)) { - av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (%d)\n", avctx->bits_per_coded_sample); - return AVERROR_INVALIDDATA; - } - avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 - : AV_SAMPLE_FMT_S32; - if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) - avctx->bits_per_raw_sample = avctx->bits_per_coded_sample; - - /* get the sample rate. Not all values are used. */ - switch (header[2] & 0x0f) { - case 1: - avctx->sample_rate = 48000; - break; - case 4: - avctx->sample_rate = 96000; - break; - case 5: - avctx->sample_rate = 192000; - break; - default: - avctx->sample_rate = 0; - av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n", - header[2] & 0x0f); - return AVERROR_INVALIDDATA; - } - - /* - * get the channel number (and mapping). Not all values are used. - * It must be noted that the number of channels in the MPEG stream can - * differ from the actual meaningful number, e.g. mono audio still has two - * channels, one being empty. - */ - av_channel_layout_uninit(&avctx->ch_layout); - avctx->ch_layout = channel_layouts[channel_layout]; - if (!avctx->ch_layout.nb_channels) { - av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n", - channel_layout); - return AVERROR_INVALIDDATA; - } - - avctx->bit_rate = FFALIGN(avctx->ch_layout.nb_channels, 2) * avctx->sample_rate * - avctx->bits_per_coded_sample; - - if (avctx->debug & FF_DEBUG_PICT_INFO) - ff_dlog(avctx, - "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n", - avctx->ch_layout.nb_channels, avctx->bits_per_coded_sample, - avctx->sample_rate, avctx->bit_rate); - return 0; -} - -static int pcm_bluray_decode_frame(AVCodecContext *avctx, AVFrame *frame, - int *got_frame_ptr, AVPacket *avpkt) +static int decode_frame(AVCodecContext *avctx, AVFrame *frame, + int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *src = avpkt->data; int buf_size = avpkt->size; @@ -133,16 +57,6 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, AVFrame *frame, int16_t *dst16; int32_t *dst32; - if (buf_size < 4) { - av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n"); - return AVERROR_INVALIDDATA; - } - - if ((retval = pcm_bluray_parse_header(avctx, src))) - return retval; - src += 4; - buf_size -= 4; - bytestream2_init(&gb, src, buf_size); /* There's always an even number of channels in the source */ @@ -297,7 +211,101 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, AVFrame *frame, if (avctx->debug & FF_DEBUG_BITSTREAM) ff_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n", retval, buf_size); - return retval + 4; + return retval; +} + +/** + * Parse the header of a LPCM frame read from a Blu-ray MPEG-TS stream + * @param avctx the codec context + * @param header pointer to the first four bytes of the data packet + */ +static int pcm_bluray_parse_header(AVCodecContext *avctx, + const uint8_t *header) +{ + static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 }; + static const AVChannelLayout channel_layouts[16] = { + { 0 }, AV_CHANNEL_LAYOUT_MONO, { 0 }, + AV_CHANNEL_LAYOUT_STEREO, AV_CHANNEL_LAYOUT_SURROUND, AV_CHANNEL_LAYOUT_2_1, + AV_CHANNEL_LAYOUT_4POINT0, AV_CHANNEL_LAYOUT_2_2, AV_CHANNEL_LAYOUT_5POINT0, + AV_CHANNEL_LAYOUT_5POINT1, AV_CHANNEL_LAYOUT_7POINT0, AV_CHANNEL_LAYOUT_7POINT1, + { 0 }, { 0 }, { 0 }, { 0 }, + }; + uint8_t channel_layout = header[2] >> 4; + + if (avctx->debug & FF_DEBUG_PICT_INFO) + ff_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n", + header[0], header[1], header[2], header[3]); + + /* get the sample depth and derive the sample format from it */ + avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6]; + if (!(avctx->bits_per_coded_sample == 16 || avctx->bits_per_coded_sample == 24)) { + av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (%d)\n", avctx->bits_per_coded_sample); + return AVERROR_INVALIDDATA; + } + avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 + : AV_SAMPLE_FMT_S32; + if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) + avctx->bits_per_raw_sample = avctx->bits_per_coded_sample; + + /* get the sample rate. Not all values are used. */ + switch (header[2] & 0x0f) { + case 1: + avctx->sample_rate = 48000; + break; + case 4: + avctx->sample_rate = 96000; + break; + case 5: + avctx->sample_rate = 192000; + break; + default: + avctx->sample_rate = 0; + av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n", + header[2] & 0x0f); + return AVERROR_INVALIDDATA; + } + + /* + * get the channel number (and mapping). Not all values are used. + * It must be noted that the number of channels in the MPEG stream can + * differ from the actual meaningful number, e.g. mono audio still has two + * channels, one being empty. + */ + av_channel_layout_uninit(&avctx->ch_layout); + avctx->ch_layout = channel_layouts[channel_layout]; + if (!avctx->ch_layout.nb_channels) { + av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n", + channel_layout); + return AVERROR_INVALIDDATA; + } + + avctx->bit_rate = FFALIGN(avctx->ch_layout.nb_channels, 2) * avctx->sample_rate * + avctx->bits_per_coded_sample; + + if (avctx->debug & FF_DEBUG_PICT_INFO) + ff_dlog(avctx, + "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n", + avctx->ch_layout.nb_channels, avctx->bits_per_coded_sample, + avctx->sample_rate, avctx->bit_rate); + return 0; +} + +static int pcm_bluray_decode_frame(AVCodecContext *avctx, AVFrame *frame, + int *got_frame_ptr, AVPacket *avpkt) +{ + int retval; + + if (avpkt->size < 4) { + av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n"); + return AVERROR_INVALIDDATA; + } + + if ((retval = pcm_bluray_parse_header(avctx, avpkt->data))) + return retval; + + avpkt->data += 4; + avpkt->size -= 4; + return decode_frame(avctx, frame, got_frame_ptr, avpkt); } const FFCodec ff_pcm_bluray_decoder = { -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
