You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	opus: convert to new channel layout API
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
		
				
					committed by
					
						 James Almer
						James Almer
					
				
			
			
				
	
			
			
			
						parent
						
							045d6b9abf
						
					
				
				
					commit
					cc37640a72
				
			| @@ -296,14 +296,15 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|     static const uint8_t default_channel_map[2] = { 0, 1 }; | ||||
|  | ||||
|     int (*channel_reorder)(int, int) = channel_reorder_unknown; | ||||
|     int channels = avctx->ch_layout.nb_channels; | ||||
|  | ||||
|     const uint8_t *extradata, *channel_map; | ||||
|     int extradata_size; | ||||
|     int version, channels, map_type, streams, stereo_streams, i, j; | ||||
|     uint64_t layout; | ||||
|     int version, map_type, streams, stereo_streams, i, j, ret; | ||||
|     AVChannelLayout layout = { 0 }; | ||||
|  | ||||
|     if (!avctx->extradata) { | ||||
|         if (avctx->channels > 2) { | ||||
|         if (channels > 2) { | ||||
|             av_log(avctx, AV_LOG_ERROR, | ||||
|                    "Multichannel configuration without extradata.\n"); | ||||
|             return AVERROR(EINVAL); | ||||
| @@ -331,7 +332,7 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|     if (avctx->internal) | ||||
|         avctx->internal->skip_samples = avctx->delay; | ||||
|  | ||||
|     channels = avctx->extradata ? extradata[9] : (avctx->channels == 1) ? 1 : 2; | ||||
|     channels = avctx->extradata ? extradata[9] : (channels == 1) ? 1 : 2; | ||||
|     if (!channels) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extradata\n"); | ||||
|         return AVERROR_INVALIDDATA; | ||||
| @@ -346,9 +347,11 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|         if (channels > 2) { | ||||
|             av_log(avctx, AV_LOG_ERROR, | ||||
|                    "Channel mapping 0 is only specified for up to 2 channels\n"); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|             ret = AVERROR_INVALIDDATA; | ||||
|             goto fail; | ||||
|         } | ||||
|         layout         = (channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; | ||||
|         layout         = (channels == 1) ? (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO : | ||||
|                                            (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; | ||||
|         streams        = 1; | ||||
|         stereo_streams = channels - 1; | ||||
|         channel_map    = default_channel_map; | ||||
| @@ -356,7 +359,8 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|         if (extradata_size < 21 + channels) { | ||||
|             av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", | ||||
|                    extradata_size); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|             ret = AVERROR_INVALIDDATA; | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         streams        = extradata[19]; | ||||
| @@ -365,16 +369,18 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|             streams + stereo_streams > 255) { | ||||
|             av_log(avctx, AV_LOG_ERROR, | ||||
|                    "Invalid stream/stereo stream count: %d/%d\n", streams, stereo_streams); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|             ret = AVERROR_INVALIDDATA; | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         if (map_type == 1) { | ||||
|             if (channels > 8) { | ||||
|                 av_log(avctx, AV_LOG_ERROR, | ||||
|                        "Channel mapping 1 is only specified for up to 8 channels\n"); | ||||
|                 return AVERROR_INVALIDDATA; | ||||
|                 ret = AVERROR_INVALIDDATA; | ||||
|                 goto fail; | ||||
|             } | ||||
|             layout = ff_vorbis_channel_layouts[channels - 1]; | ||||
|             av_channel_layout_copy(&layout, &ff_vorbis_ch_layouts[channels - 1]); | ||||
|             channel_reorder = channel_reorder_vorbis; | ||||
|         } else if (map_type == 2) { | ||||
|             int ambisonic_order = ff_sqrt(channels) - 1; | ||||
| @@ -384,15 +390,20 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|                        "Channel mapping 2 is only specified for channel counts" | ||||
|                        " which can be written as (n + 1)^2 or (n + 1)^2 + 2" | ||||
|                        " for nonnegative integer n\n"); | ||||
|                 return AVERROR_INVALIDDATA; | ||||
|                 ret = AVERROR_INVALIDDATA; | ||||
|                 goto fail; | ||||
|             } | ||||
|             if (channels > 227) { | ||||
|                 av_log(avctx, AV_LOG_ERROR, "Too many channels\n"); | ||||
|                 return AVERROR_INVALIDDATA; | ||||
|                 ret = AVERROR_INVALIDDATA; | ||||
|                 goto fail; | ||||
|             } | ||||
|             layout = 0; | ||||
|         } else | ||||
|             layout = 0; | ||||
|             layout.order       = AV_CHANNEL_ORDER_UNSPEC; | ||||
|             layout.nb_channels = channels; | ||||
|         } else { | ||||
|             layout.order       = AV_CHANNEL_ORDER_UNSPEC; | ||||
|             layout.nb_channels = channels; | ||||
|         } | ||||
|  | ||||
|         channel_map = extradata + 21; | ||||
|     } else { | ||||
| @@ -401,8 +412,10 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|     } | ||||
|  | ||||
|     s->channel_maps = av_calloc(channels, sizeof(*s->channel_maps)); | ||||
|     if (!s->channel_maps) | ||||
|         return AVERROR(ENOMEM); | ||||
|     if (!s->channel_maps) { | ||||
|         ret = AVERROR(ENOMEM); | ||||
|         goto fail; | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < channels; i++) { | ||||
|         ChannelMap *map = &s->channel_maps[i]; | ||||
| @@ -415,7 +428,8 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|             av_log(avctx, AV_LOG_ERROR, | ||||
|                    "Invalid channel map for output channel %d: %d\n", i, idx); | ||||
|             av_freep(&s->channel_maps); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|             ret = AVERROR_INVALIDDATA; | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         /* check that we did not see this index yet */ | ||||
| @@ -436,12 +450,15 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     avctx->channels       = channels; | ||||
|     avctx->channel_layout = layout; | ||||
|     av_channel_layout_uninit(&avctx->ch_layout); | ||||
|     avctx->ch_layout = layout; | ||||
|     s->nb_streams         = streams; | ||||
|     s->nb_stereo_streams  = stereo_streams; | ||||
|  | ||||
|     return 0; | ||||
| fail: | ||||
|     av_channel_layout_uninit(&layout); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc) | ||||
|   | ||||
| @@ -458,7 +458,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, | ||||
|         return ret; | ||||
|     frame->nb_samples = 0; | ||||
|  | ||||
|     for (i = 0; i < avctx->channels; i++) { | ||||
|     for (i = 0; i < avctx->ch_layout.nb_channels; i++) { | ||||
|         ChannelMap *map = &c->channel_maps[i]; | ||||
|         if (!map->copy) | ||||
|             c->streams[map->stream_idx].out[map->channel_idx] = (float*)frame->extended_data[i]; | ||||
| @@ -541,7 +541,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < avctx->channels; i++) { | ||||
|     for (i = 0; i < avctx->ch_layout.nb_channels; i++) { | ||||
|         ChannelMap *map = &c->channel_maps[i]; | ||||
|  | ||||
|         /* handle copied channels */ | ||||
|   | ||||
| @@ -66,7 +66,7 @@ static void opus_write_extradata(AVCodecContext *avctx) | ||||
|  | ||||
|     bytestream_put_buffer(&bs, "OpusHead", 8); | ||||
|     bytestream_put_byte  (&bs, 0x1); | ||||
|     bytestream_put_byte  (&bs, avctx->channels); | ||||
|     bytestream_put_byte  (&bs, avctx->ch_layout.nb_channels); | ||||
|     bytestream_put_le16  (&bs, avctx->initial_padding); | ||||
|     bytestream_put_le32  (&bs, avctx->sample_rate); | ||||
|     bytestream_put_le16  (&bs, 0x0); | ||||
| @@ -518,11 +518,16 @@ static void opus_packet_assembler(OpusEncContext *s, AVPacket *avpkt) | ||||
| static AVFrame *spawn_empty_frame(OpusEncContext *s) | ||||
| { | ||||
|     AVFrame *f = av_frame_alloc(); | ||||
|     int ret; | ||||
|     if (!f) | ||||
|         return NULL; | ||||
|     f->format         = s->avctx->sample_fmt; | ||||
|     f->nb_samples     = s->avctx->frame_size; | ||||
|     f->channel_layout = s->avctx->channel_layout; | ||||
|     ret = av_channel_layout_copy(&f->ch_layout, &s->avctx->ch_layout); | ||||
|     if (ret < 0) { | ||||
|         av_frame_free(&f); | ||||
|         return NULL; | ||||
|     } | ||||
|     if (av_frame_get_buffer(f, 4)) { | ||||
|         av_frame_free(&f); | ||||
|         return NULL; | ||||
| @@ -626,7 +631,7 @@ static av_cold int opus_encode_init(AVCodecContext *avctx) | ||||
|     OpusEncContext *s = avctx->priv_data; | ||||
|  | ||||
|     s->avctx = avctx; | ||||
|     s->channels = avctx->channels; | ||||
|     s->channels = avctx->ch_layout.nb_channels; | ||||
|  | ||||
|     /* Opus allows us to change the framesize on each packet (and each packet may | ||||
|      * have multiple frames in it) but we can't change the codec's frame size on | ||||
| @@ -734,8 +739,12 @@ const AVCodec ff_opus_encoder = { | ||||
|     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, | ||||
|     .capabilities   = AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY, | ||||
|     .supported_samplerates = (const int []){ 48000, 0 }, | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
|     .channel_layouts = (const uint64_t []){ AV_CH_LAYOUT_MONO, | ||||
|                                             AV_CH_LAYOUT_STEREO, 0 }, | ||||
| #endif | ||||
|     .ch_layouts      = (const AVChannelLayout []){ AV_CHANNEL_LAYOUT_MONO, | ||||
|                                                    AV_CHANNEL_LAYOUT_STEREO, { 0 } }, | ||||
|     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, | ||||
|                                                      AV_SAMPLE_FMT_NONE }, | ||||
| }; | ||||
|   | ||||
| @@ -83,7 +83,7 @@ static void step_collect_psy_metrics(OpusPsyContext *s, int index) | ||||
|  | ||||
|     st->index = index; | ||||
|  | ||||
|     for (ch = 0; ch < s->avctx->channels; ch++) { | ||||
|     for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) { | ||||
|         const int lap_size = (1 << s->bsize_analysis); | ||||
|         for (i = 1; i <= FFMIN(lap_size, index); i++) { | ||||
|             const int offset = i*120; | ||||
| @@ -105,7 +105,7 @@ static void step_collect_psy_metrics(OpusPsyContext *s, int index) | ||||
|             st->bands[ch][i] = &st->coeffs[ch][ff_celt_freq_bands[i] << s->bsize_analysis]; | ||||
|     } | ||||
|  | ||||
|     for (ch = 0; ch < s->avctx->channels; ch++) { | ||||
|     for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) { | ||||
|         for (i = 0; i < CELT_MAX_BANDS; i++) { | ||||
|             float avg_c_s, energy = 0.0f, dist_dev = 0.0f; | ||||
|             const int range = ff_celt_freq_range[i] << s->bsize_analysis; | ||||
| @@ -128,7 +128,7 @@ static void step_collect_psy_metrics(OpusPsyContext *s, int index) | ||||
|  | ||||
|     st->silence = !silence; | ||||
|  | ||||
|     if (s->avctx->channels > 1) { | ||||
|     if (s->avctx->ch_layout.nb_channels > 1) { | ||||
|         for (i = 0; i < CELT_MAX_BANDS; i++) { | ||||
|             float incompat = 0.0f; | ||||
|             const float *coeffs1 = st->bands[0][i]; | ||||
| @@ -140,7 +140,7 @@ static void step_collect_psy_metrics(OpusPsyContext *s, int index) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     for (ch = 0; ch < s->avctx->channels; ch++) { | ||||
|     for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) { | ||||
|         for (i = 0; i < CELT_MAX_BANDS; i++) { | ||||
|             OpusBandExcitation *ex = &s->ex[ch][i]; | ||||
|             float bp_e = bessel_filter(&s->bfilter_lo[ch][i], st->energy[ch][i]); | ||||
| @@ -259,7 +259,7 @@ void ff_opus_psy_celt_frame_init(OpusPsyContext *s, CeltFrame *f, int index) | ||||
|  | ||||
|     f->start_band = (s->p.mode == OPUS_MODE_HYBRID) ? 17 : 0; | ||||
|     f->end_band   = ff_celt_band_end[s->p.bandwidth]; | ||||
|     f->channels   = s->avctx->channels; | ||||
|     f->channels   = s->avctx->ch_layout.nb_channels; | ||||
|     f->size       = s->p.framesize; | ||||
|  | ||||
|     for (i = 0; i < (1 << f->size); i++) | ||||
| @@ -327,7 +327,7 @@ static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start, | ||||
|         float tonal_contrib = 0.0f; | ||||
|         for (f = 0; f < (1 << s->p.framesize); f++) { | ||||
|             weight = start[f]->stereo[i]; | ||||
|             for (ch = 0; ch < s->avctx->channels; ch++) { | ||||
|             for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) { | ||||
|                 weight += start[f]->change_amp[ch][i] + start[f]->tone[ch][i] + start[f]->energy[ch][i]; | ||||
|                 tonal_contrib += start[f]->tone[ch][i]; | ||||
|             } | ||||
| @@ -384,7 +384,7 @@ static void celt_search_for_dual_stereo(OpusPsyContext *s, CeltFrame *f) | ||||
|     float td1, td2; | ||||
|     f->dual_stereo = 0; | ||||
|  | ||||
|     if (s->avctx->channels < 2) | ||||
|     if (s->avctx->ch_layout.nb_channels < 2) | ||||
|         return; | ||||
|  | ||||
|     bands_dist(s, f, &td1); | ||||
| @@ -402,7 +402,7 @@ static void celt_search_for_intensity(OpusPsyContext *s, CeltFrame *f) | ||||
|     /* TODO: fix, make some heuristic up here using the lambda value */ | ||||
|     float end_band = 0; | ||||
|  | ||||
|     if (s->avctx->channels < 2) | ||||
|     if (s->avctx->ch_layout.nb_channels < 2) | ||||
|         return; | ||||
|  | ||||
|     for (i = f->end_band; i >= end_band; i--) { | ||||
| @@ -436,7 +436,7 @@ static int celt_search_for_tf(OpusPsyContext *s, OpusPsyStep **start, CeltFrame | ||||
|             float iscore0 = 0.0f; | ||||
|             float iscore1 = 0.0f; | ||||
|             for (j = 0; j < (1 << f->size); j++) { | ||||
|                 for (k = 0; k < s->avctx->channels; k++) { | ||||
|                 for (k = 0; k < s->avctx->ch_layout.nb_channels; k++) { | ||||
|                     iscore0 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[0]; | ||||
|                     iscore1 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[1]; | ||||
|                 } | ||||
| @@ -540,7 +540,7 @@ av_cold int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx, | ||||
|         goto fail; | ||||
|     } | ||||
|  | ||||
|     for (ch = 0; ch < s->avctx->channels; ch++) { | ||||
|     for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) { | ||||
|         for (i = 0; i < CELT_MAX_BANDS; i++) { | ||||
|             bessel_init(&s->bfilter_hi[ch][i], 1.0f, 19.0f, 100.0f, 1); | ||||
|             bessel_init(&s->bfilter_lo[ch][i], 1.0f, 20.0f, 100.0f, 0); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user