From patchwork Thu Jan 13 01:55:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 33374 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:cd86:0:0:0:0:0 with SMTP id d128csp25479iog; Wed, 12 Jan 2022 18:12:45 -0800 (PST) X-Google-Smtp-Source: ABdhPJylo4Hz8d9bvKNSUss4eiJDposIaKbyxfksggL2/gCCuhZrsFXuf9a6ANikEbhyaKPpIAzf X-Received: by 2002:a17:907:7b8a:: with SMTP id ne10mr1871475ejc.587.1642039965781; Wed, 12 Jan 2022 18:12:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642039965; cv=none; d=google.com; s=arc-20160816; b=dWXK46xU6Pm+XBBbCOHS/2OLnmu+DXBYq1iwwfqRLGrZy0wIxcQtgAaTvnvemeghCB sh41XECAK4Redaacz6+v7o4drAtHFNq0SX0j4m+n3P/D0Kz9bLeAUm9AYahJn4FDTkwk JNjfmJSDLWYY1xPpLoypzVZtR8mHWhRL1i6eLtwmLJu3C8aFn31fnVFaXyfFYyRdvaHw 2xghEGtcj9nCHY5JPWKi7Z6q3/YkRKKtv+jlnfrSXHIii8ccWXKneXqj5PI28gSTLUCX bwnlPvJ/phHG6+Wcw715e1crATxwcZ8g0t0Y6EdEDrscHIj3o0vFne2Yd+O8aVOR45wP RK8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=QUkrXRMSQwKy06VXsnt8kCOLPX10jOghs13JjxkbYtk=; b=r2M5dLuz/ScBKhKEQrg5HYtYGzfaJQzm+JkDDTABxlCVAtc91Wh1slrBYVjWIdd7Fq 3ybpbeuGEv9XLQV9Kzyebwmd1gejy2jOMvpgjxT71R8NDDJiGMcX5BP+rc+QRTXH3vHg lPynhHszGXD674dTVZG8RFK4JIzGkxCFV7kOHP4KiVBpkALR9y1hBB3fQobfSZ5edzW1 eE+/G7Bgu/jMv3cVaAtTU4vEAC/aV79toJLZh6NKbaZPozdWWk0RB2r7xyz14jPbzxT7 LFBE43NLvTRPmT6nHjDG5x9LeS23p3uvxQEWbTE7smtZsI6fMzxffTyM3vPAzV+F51qh WRJQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=bLhMG02q; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id o6si1014466edi.174.2022.01.12.18.12.45; Wed, 12 Jan 2022 18:12:45 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=bLhMG02q; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id AB28368B247; Thu, 13 Jan 2022 03:56:38 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk1-f169.google.com (mail-qk1-f169.google.com [209.85.222.169]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6EE0F68B22B for ; Thu, 13 Jan 2022 03:56:35 +0200 (EET) Received: by mail-qk1-f169.google.com with SMTP id t66so5567879qkb.4 for ; Wed, 12 Jan 2022 17:56:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=V8vC6CDpaWYvqN72a42X6fUKIXM3qxi7FzZ8D36qXq8=; b=bLhMG02qFPgkoMraid4E89kiOVCaq0+dfxn9jNdgSPElkFdsoaYCsaZSLdGvZNiB9w d42nFKOK2Pcm7eHrxOVb4Of4bJQ9BCot7saSe6onFoMGpVzV+5fcO+6w0k+rzyDyaJS3 6VLiyyMypuKYBg5xvcOVqDGT79gS8Tdq+xSxAVaXPJYM/mykOTtUaL5B+VlcF5S1jS/Q HhJZiXoSgTnQbj+EGGDhAvBREFnLn3T4UaW5qV5pZZNre1OXxEprVnfoDwynNStUwrel E7ciavYoUtZQI8N4rc1SY+SSf24TWlAaJfvRASzPNOgmAzHPzK0aPlE5XkAcNh2tgbur +ANg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=V8vC6CDpaWYvqN72a42X6fUKIXM3qxi7FzZ8D36qXq8=; b=AKSueW2jRzc8HqdV1RvJzeWWnjzAgRCU4xdFPWLRhy+jFtj91/us4FN0lnwYA0Fs5V YlltSILwRxJZBZUXF+DAl6iLYYeusdS+9aKbi93sVBX6D1qmLqLWNfvIFm8ohKNTVjao 56NqlOYDM3W7dewGzIhmBYpPYJPX8dL+fCnMlzKkCrRVuJV0pPq68DZh4oT2yliC/meq rdb1gCr2S3CEbpZuEHm/7/g75zjlQDP/SwCTFBEno6bcLhLxgfUcZnqxefOPyva1XhNY tNIWdWX/6KUQio5ox8hUA3j7Iz+G3Y0ua5IhY82Cb61ZggDiaYYDZAKgwxzj9RBoGLsm eQag== X-Gm-Message-State: AOAM530wHRB+zu+JEkOzygI47WXMkBM8P/1P4w4EDdR6/uqLo2SyS2/b SUhRrYK25vtDk0HsINjtacbZpghs6xc= X-Received: by 2002:a05:620a:12e4:: with SMTP id f4mr1850755qkl.249.1642038993814; Wed, 12 Jan 2022 17:56:33 -0800 (PST) Received: from localhost.localdomain ([186.136.131.95]) by smtp.gmail.com with ESMTPSA id t11sm906506qkm.77.2022.01.12.17.56.32 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jan 2022 17:56:33 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Wed, 12 Jan 2022 22:55:49 -0300 Message-Id: <20220113015612.448-8-jamrial@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220113015101.4-1-jamrial@gmail.com> References: <20220113015101.4-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 096/281] mov: convert to new channel layout API X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: wA18zaxI5ni8 From: Vittorio Giovara Signed-off-by: Vittorio Giovara Signed-off-by: Anton Khirnov Signed-off-by: James Almer --- libavformat/isom.c | 5 +-- libavformat/mov.c | 80 +++++++++++++++++++++++++++--------------- libavformat/mov_chan.c | 21 +++++++---- libavformat/mov_chan.h | 3 +- libavformat/movenc.c | 25 +++++++------ 5 files changed, 85 insertions(+), 49 deletions(-) diff --git a/libavformat/isom.c b/libavformat/isom.c index 015c82e1bb..e6569dfb68 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -360,7 +360,8 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext st->codecpar->extradata_size, 1, fc); if (ret < 0) return ret; - st->codecpar->channels = cfg.channels; + st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + st->codecpar->ch_layout.nb_channels = cfg.channels; if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 st->codecpar->sample_rate = ff_mpa_freq_tab[cfg.sampling_index]; else if (cfg.ext_sample_rate) @@ -368,7 +369,7 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext else st->codecpar->sample_rate = cfg.sample_rate; av_log(fc, AV_LOG_TRACE, "mp4a config channels %d obj %d ext obj %d " - "sample rate %d ext sample rate %d\n", st->codecpar->channels, + "sample rate %d ext sample rate %d\n", cfg.channels, cfg.object_type, cfg.ext_object_type, cfg.sample_rate, cfg.ext_sample_rate); if (!(st->codecpar->codec_id = ff_codec_get_id(mp4_audio_types, diff --git a/libavformat/mov.c b/libavformat/mov.c index e401cd39b5..e307df8e3c 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -798,6 +798,7 @@ static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom) AVStream *st; enum AVAudioServiceType *ast; int ac3info, acmod, lfeon, bsmod; + uint64_t mask; if (c->fc->nb_streams < 1) return 0; @@ -812,12 +813,15 @@ static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom) bsmod = (ac3info >> 14) & 0x7; acmod = (ac3info >> 11) & 0x7; lfeon = (ac3info >> 10) & 0x1; - st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon; - st->codecpar->channel_layout = ff_ac3_channel_layout_tab[acmod]; + + mask = ff_ac3_channel_layout_tab[acmod]; if (lfeon) - st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY; + mask |= AV_CH_LOW_FREQUENCY; + av_channel_layout_uninit(&st->codecpar->ch_layout); + av_channel_layout_from_mask(&st->codecpar->ch_layout, mask); + *ast = bsmod; - if (st->codecpar->channels > 1 && bsmod == 0x7) + if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7) *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE; return 0; @@ -828,6 +832,7 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) AVStream *st; enum AVAudioServiceType *ast; int eac3info, acmod, lfeon, bsmod; + uint64_t mask; if (c->fc->nb_streams < 1) return 0; @@ -846,12 +851,15 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) bsmod = (eac3info >> 12) & 0x1f; acmod = (eac3info >> 9) & 0x7; lfeon = (eac3info >> 8) & 0x1; - st->codecpar->channel_layout = ff_ac3_channel_layout_tab[acmod]; + + mask = ff_ac3_channel_layout_tab[acmod]; if (lfeon) - st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY; - st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout); + mask |= AV_CH_LOW_FREQUENCY; + av_channel_layout_uninit(&st->codecpar->ch_layout); + av_channel_layout_from_mask(&st->codecpar->ch_layout, mask); + *ast = bsmod; - if (st->codecpar->channels > 1 && bsmod == 0x7) + if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7) *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE; return 0; @@ -898,15 +906,14 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (channel_layout_code > 0xff) { av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n"); } - st->codecpar->channel_layout = + av_channel_layout_uninit(&st->codecpar->ch_layout); + av_channel_layout_from_mask(&st->codecpar->ch_layout, ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) | ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) | ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) | ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) | ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) | - ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0); - - st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout); + ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0)); return 0; } @@ -2162,14 +2169,18 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, uint16_t version = avio_rb16(pb); uint32_t id = 0; AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE); + int channel_count; avio_rb16(pb); /* revision level */ id = avio_rl32(pb); /* vendor */ av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0); - st->codecpar->channels = avio_rb16(pb); /* channel count */ + channel_count = avio_rb16(pb); + + st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + st->codecpar->ch_layout.nb_channels = channel_count; st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */ - av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels); + av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count); sc->audio_cid = avio_rb16(pb); avio_rb16(pb); /* packet size = 0 */ @@ -2189,7 +2200,9 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, } else if (version == 2) { avio_rb32(pb); /* sizeof struct only */ st->codecpar->sample_rate = av_int2double(avio_rb64(pb)); - st->codecpar->channels = avio_rb32(pb); + channel_count = avio_rb32(pb); + st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + st->codecpar->ch_layout.nb_channels = channel_count; avio_rb32(pb); /* always 0x7F000000 */ st->codecpar->bits_per_coded_sample = avio_rb32(pb); @@ -2241,15 +2254,15 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, /* set values for old format before stsd version 1 appeared */ case AV_CODEC_ID_MACE3: sc->samples_per_frame = 6; - sc->bytes_per_frame = 2 * st->codecpar->channels; + sc->bytes_per_frame = 2 * st->codecpar->ch_layout.nb_channels; break; case AV_CODEC_ID_MACE6: sc->samples_per_frame = 6; - sc->bytes_per_frame = 1 * st->codecpar->channels; + sc->bytes_per_frame = 1 * st->codecpar->ch_layout.nb_channels; break; case AV_CODEC_ID_ADPCM_IMA_QT: sc->samples_per_frame = 64; - sc->bytes_per_frame = 34 * st->codecpar->channels; + sc->bytes_per_frame = 34 * st->codecpar->ch_layout.nb_channels; break; case AV_CODEC_ID_GSM: sc->samples_per_frame = 160; @@ -2260,9 +2273,9 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, } bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id); - if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) { + if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) { st->codecpar->bits_per_coded_sample = bits_per_sample; - sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels; + sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels; } } @@ -2402,7 +2415,8 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, #endif /* no ifdef since parameters are always those */ case AV_CODEC_ID_QCELP: - st->codecpar->channels = 1; + av_channel_layout_uninit(&st->codecpar->ch_layout); + st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; // force sample rate for qcelp when not stored in mov if (st->codecpar->codec_tag != MKTAG('Q','c','l','p')) st->codecpar->sample_rate = 8000; @@ -2412,12 +2426,14 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, sc->bytes_per_frame = 35; break; case AV_CODEC_ID_AMR_NB: - st->codecpar->channels = 1; + av_channel_layout_uninit(&st->codecpar->ch_layout); + st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; /* force sample rate for amr, stsd in 3gp does not store sample rate */ st->codecpar->sample_rate = 8000; break; case AV_CODEC_ID_AMR_WB: - st->codecpar->channels = 1; + av_channel_layout_uninit(&st->codecpar->ch_layout); + st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; st->codecpar->sample_rate = 16000; break; case AV_CODEC_ID_MP2: @@ -2436,7 +2452,12 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, break; case AV_CODEC_ID_ALAC: if (st->codecpar->extradata_size == 36) { - st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21); + int channel_count = AV_RB8(st->codecpar->extradata + 21); + if (st->codecpar->ch_layout.nb_channels != channel_count) { + av_channel_layout_uninit(&st->codecpar->ch_layout); + st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + st->codecpar->ch_layout.nb_channels = channel_count; + } st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32); } break; @@ -2543,8 +2564,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate); return AVERROR_INVALIDDATA; } - if (st->codecpar->channels < 0) { - av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->channels); + if (st->codecpar->ch_layout.nb_channels < 0) { + av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels); return AVERROR_INVALIDDATA; } } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){ @@ -7034,6 +7055,7 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) unsigned format_info; int channel_assignment, channel_assignment1, channel_assignment2; int ratebits; + uint64_t chmask; if (c->fc->nb_streams < 1) return 0; @@ -7054,8 +7076,10 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom) st->codecpar->frame_size = 40 << (ratebits & 0x7); st->codecpar->sample_rate = mlp_samplerate(ratebits); - st->codecpar->channels = truehd_channels(channel_assignment); - st->codecpar->channel_layout = truehd_layout(channel_assignment); + + av_channel_layout_uninit(&st->codecpar->ch_layout); + chmask = truehd_layout(channel_assignment); + av_channel_layout_from_mask(&st->codecpar->ch_layout, chmask); return 0; } diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index 349634094c..5894bb8ce2 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -499,7 +499,7 @@ static uint32_t mov_get_channel_label(uint32_t label) } uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id, - uint64_t channel_layout, + AVChannelLayout *ch_layout, uint32_t *bitmap) { int i, j; @@ -519,7 +519,7 @@ uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id, const struct MovChannelLayoutMap *layout_map; /* get the layout map based on the channel count */ - channels = av_get_channel_layout_nb_channels(channel_layout); + channels = ch_layout->nb_channels; if (channels > 9) channels = 0; layout_map = mov_ch_layout_map[channels]; @@ -530,7 +530,8 @@ uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id, continue; for (j = 0; layout_map[j].tag != 0; j++) { if (layout_map[j].tag == layouts[i] && - layout_map[j].layout == channel_layout) + (ch_layout->order == AV_CHANNEL_ORDER_NATIVE && + layout_map[j].layout == ch_layout->u.mask)) break; } if (layout_map[j].tag) @@ -540,9 +541,9 @@ uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id, } /* if no tag was found, use channel bitmap as a backup if possible */ - if (tag == 0 && channel_layout > 0 && channel_layout < 0x40000) { + if (tag == 0 && av_channel_layout_check(ch_layout) && ch_layout->u.mask < 0x40000) { tag = MOV_CH_LAYOUT_USE_BITMAP; - *bitmap = (uint32_t)channel_layout; + *bitmap = (uint32_t)ch_layout->u.mask; } else *bitmap = 0; @@ -555,6 +556,7 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size) { uint32_t layout_tag, bitmap, num_descr, label_mask; + uint64_t mask = 0; int i; if (size < 12) @@ -596,9 +598,14 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, } if (layout_tag == 0) { if (label_mask) - st->codecpar->channel_layout = label_mask; + mask = label_mask; } else - st->codecpar->channel_layout = mov_get_channel_layout(layout_tag, bitmap); + mask = mov_get_channel_layout(layout_tag, bitmap); + + if (mask) { + av_channel_layout_uninit(&st->codecpar->ch_layout); + av_channel_layout_from_mask(&st->codecpar->ch_layout, mask); + } avio_skip(pb, size - 12); return 0; diff --git a/libavformat/mov_chan.h b/libavformat/mov_chan.h index f7916e9899..a9bc9f80d4 100644 --- a/libavformat/mov_chan.h +++ b/libavformat/mov_chan.h @@ -28,6 +28,7 @@ #include +#include "libavutil/channel_layout.h" #include "libavcodec/codec_id.h" #include "avformat.h" @@ -41,7 +42,7 @@ * @return channel layout tag */ uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id, - uint64_t channel_layout, + AVChannelLayout *ch_layout, uint32_t *bitmap); /** diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 4c868919ae..6d02a9ea39 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -868,7 +868,7 @@ static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra int64_t pos = avio_tell(pb); layout_tag = ff_mov_get_channel_layout_tag(track->par->codec_id, - track->par->channel_layout, + &track->par->ch_layout, &bitmap); if (!layout_tag) { av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to " @@ -1137,7 +1137,7 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex int ret = 0; if (track->mode == MODE_MOV) { - if (track->timescale > UINT16_MAX || !track->par->channels) { + if (track->timescale > UINT16_MAX || !track->par->ch_layout.nb_channels) { if (mov_get_lpcm_flags(track->par->codec_id)) tag = AV_RL32("lpcm"); version = 2; @@ -1173,7 +1173,7 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex avio_wb32(pb, 0x00010000); avio_wb32(pb, 72); avio_wb64(pb, av_double2int(track->par->sample_rate)); - avio_wb32(pb, track->par->channels); + avio_wb32(pb, track->par->ch_layout.nb_channels); avio_wb32(pb, 0x7F000000); avio_wb32(pb, av_get_bits_per_sample(track->par->codec_id)); avio_wb32(pb, mov_get_lpcm_flags(track->par->codec_id)); @@ -1181,7 +1181,7 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex avio_wb32(pb, get_samples_per_packet(track)); } else { if (track->mode == MODE_MOV) { - avio_wb16(pb, track->par->channels); + avio_wb16(pb, track->par->ch_layout.nb_channels); if (track->par->codec_id == AV_CODEC_ID_PCM_U8 || track->par->codec_id == AV_CODEC_ID_PCM_S8) avio_wb16(pb, 8); /* bits per sample */ @@ -1194,7 +1194,7 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex if (track->par->codec_id == AV_CODEC_ID_FLAC || track->par->codec_id == AV_CODEC_ID_ALAC || track->par->codec_id == AV_CODEC_ID_OPUS) { - avio_wb16(pb, track->par->channels); + avio_wb16(pb, track->par->ch_layout.nb_channels); } else { avio_wb16(pb, 2); } @@ -1226,7 +1226,7 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex avio_wb32(pb, 1); /* must be 1 for uncompressed formats */ else avio_wb32(pb, track->par->frame_size); /* Samples per packet */ - avio_wb32(pb, track->sample_size / track->par->channels); /* Bytes per packet */ + avio_wb32(pb, track->sample_size / track->par->ch_layout.nb_channels); /* Bytes per packet */ avio_wb32(pb, track->sample_size); /* Bytes per frame */ avio_wb32(pb, 2); /* Bytes per sample */ } @@ -4392,7 +4392,7 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormat track->par->extradata_size); param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id)); - param_write_int(pb, "Channels", track->par->channels); + param_write_int(pb, "Channels", track->par->ch_layout.nb_channels); param_write_int(pb, "SamplingRate", track->par->sample_rate); param_write_int(pb, "BitsPerSample", 16); param_write_int(pb, "PacketSize", track->par->block_align ? @@ -5150,7 +5150,7 @@ static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s) avio_wb32(pb, audio_kbitrate); avio_wb32(pb, audio_kbitrate); avio_wb32(pb, audio_rate); - avio_wb32(pb, audio_par->channels); + avio_wb32(pb, audio_par->ch_layout.nb_channels); avio_wb32(pb, 0x34); /* size */ ffio_wfourcc(pb, "VPRF"); /* video */ @@ -6830,7 +6830,8 @@ static int mov_init(AVFormatContext *s) }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */ track->audio_vbr = 1; }else{ - track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) * st->codecpar->channels; + track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) * + st->codecpar->ch_layout.nb_channels; } if (st->codecpar->codec_id == AV_CODEC_ID_ILBC || st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) { @@ -6966,7 +6967,8 @@ static int mov_write_header(AVFormatContext *s) } if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO || - track->par->channel_layout != AV_CH_LAYOUT_MONO) + av_channel_layout_compare(&track->par->ch_layout, + &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO)) continue; for (j = 0; j < s->nb_streams; j++) { @@ -6976,7 +6978,8 @@ static int mov_write_header(AVFormatContext *s) continue; if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO || - trackj->par->channel_layout != AV_CH_LAYOUT_MONO || + av_channel_layout_compare(&trackj->par->ch_layout, + &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO) || trackj->language != track->language || trackj->tag != track->tag )