From patchwork Tue Feb 5 01:02:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niki Bowe X-Patchwork-Id: 11972 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 15E10448660 for ; Tue, 5 Feb 2019 03:08:18 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E41ED68ACBE; Tue, 5 Feb 2019 03:08:17 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f194.google.com (mail-pl1-f194.google.com [209.85.214.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D5F7B68ACAE for ; Tue, 5 Feb 2019 03:08:11 +0200 (EET) Received: by mail-pl1-f194.google.com with SMTP id e5so762341plb.5 for ; Mon, 04 Feb 2019 17:08:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=C7XCy8arOEGJEQbqMlxYWnEq5HbVp+/6V70feY7LxzY=; b=S0G5QHucpqXApVYMXLqcrrpJ5dteYY+nQb17NjprD0rdzGDTM0ZtCLEWHR+yw3+BRv 5i75qsgN7w8Kpw2Czx5rvmPU2Wq6R2HCr4taH7l511P/pF5VfGk7YpuPqV/NKY9yAFD3 rhnNrqHmQHdIayHBhyIHq7tMwmG4Obo9QDN15zHCS+3iAZ56hC8p+JXUEz2VaHqYavMh QlEv9xlP1TOJHmVd3YExX/KZ2mZHIjOIPD9UthBBWVXSmK65tm3nzlPsEy1MtwWEdTtn LqiEBjcCu5xaVp9I7YpzrCdOYvgLgO2elzQEjsesq6tn79HhczR6Oa5Jud95oSBYpPQF ecuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=C7XCy8arOEGJEQbqMlxYWnEq5HbVp+/6V70feY7LxzY=; b=U949Ro/WQldk6wCg0Eb8VRjxyFydVR2W6W5CSNXI0vv6PacHrWmx9dK+xNTvf0ktew Dmge1jdGz3yEgi5oiauBncb7xY8j2l9Kx1+Dxh34/EGwZRD4alGWWoItQUh1NMKYIL1c 7sZPBX6i066U1uohH9Gmaw/jItaJXZ6J+9xVWv4I98la4FOT+W+EoIIlQUgxRaTcXj5K UaCVKj8FcZhRtNyyz49BIKgBATf+H7KDVSobaCg/chdYXRKhZh9LupZ/9/pYmiu7QmRm Nz+Swv/awNhDukef7yQgDRIc6v7TGI29u9AlCQxobPs/r0+nPGbKvb72E0jPr3zBbxFN fU9Q== X-Gm-Message-State: AHQUAuZqzzeIQVEEXMFS9zsN9vjVLkaULazC51NVIPb81blSe0bQ7I7/ YtI6NgtR+XyUxqqHB2Wu7XMoM7kwBt0A2A== X-Google-Smtp-Source: AHgI3IY9wX53ED/Lrgye1Kw+p5ZiKIwdMELpzIcqm/nIJTWH4hw1Zn6kdbQKNZLIHLRnfUW+yfyHHg== X-Received: by 2002:a17:902:4222:: with SMTP id g31mr2312465pld.240.1549328545519; Mon, 04 Feb 2019 17:02:25 -0800 (PST) Received: from nbowe.mtv.corp.google.com ([2620:0:1000:4011:fa9f:875c:58f2:5c3e]) by smtp.gmail.com with ESMTPSA id 19sm1856400pfs.108.2019.02.04.17.02.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Feb 2019 17:02:24 -0800 (PST) From: Nikolas Bowe To: ffmpeg-devel@ffmpeg.org Date: Mon, 4 Feb 2019 17:02:19 -0800 Message-Id: <20190205010219.129764-1-nbowe@google.com> X-Mailer: git-send-email 2.20.1.611.gfbb209baf1-goog MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avformat/movenc: Add more error checking when writing sample entries. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Cc: Nikolas Bowe Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Fixes a problem where a sample entry which cannot be written correctly appears to succeed, but produces an invalid file. For example, this command: ffmpeg -f lavfi -i sine=frequency=1000:duration=5 -codec:a ac3 -movflags +empty_moov -frag_duration 5000000 /tmp/foo.mp4 produced a file with the ac-3 sample entry, but no AC3SpecificBox (dac3) child, which is invalid according to ETSI TS 102 366. --- libavformat/movenc.c | 73 ++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 65be2968a1..3a1ce40e4f 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -320,8 +320,12 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track) uint8_t buf[3]; int fscod, bsid, bsmod, acmod, lfeon, frmsizecod; - if (track->vos_len < 7) - return -1; + if (track->vos_len < 7) { + av_log(pb, AV_LOG_ERROR, + "Cannot write moov atom before AC3 packets." + " Set the delay_moov flag to fix this.\n"); + return AVERROR(EINVAL); + } avio_wb32(pb, 11); ffio_wfourcc(pb, "dac3"); @@ -538,8 +542,11 @@ static int mov_write_eac3_tag(AVIOContext *pb, MOVTrack *track) struct eac3_info *info; int size, i; - if (!track->eac3_priv) + if (!track->eac3_priv) { + av_log(pb, AV_LOG_ERROR, + "Cannot write moov atom before EAC3 packets parsed.\n"); return AVERROR(EINVAL); + } info = track->eac3_priv; size = 2 + ((34 * (info->num_ind_sub + 1) + 7) >> 3); @@ -1022,6 +1029,7 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex int64_t pos = avio_tell(pb); int version = 0; uint32_t tag = track->tag; + int ret = 0; if (track->mode == MODE_MOV) { if (track->timescale > UINT16_MAX || !track->par->channels) { @@ -1125,34 +1133,41 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex track->par->codec_id == AV_CODEC_ID_QDM2 || (mov_pcm_le_gt16(track->par->codec_id) && version==1) || (mov_pcm_be_gt16(track->par->codec_id) && version==1))) - mov_write_wave_tag(s, pb, track); + ret = mov_write_wave_tag(s, pb, track); else if (track->tag == MKTAG('m','p','4','a')) - mov_write_esds_tag(pb, track); + ret = mov_write_esds_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) - mov_write_amr_tag(pb, track); + ret = mov_write_amr_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_AC3) - mov_write_ac3_tag(pb, track); + ret = mov_write_ac3_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_EAC3) - mov_write_eac3_tag(pb, track); + ret = mov_write_eac3_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_ALAC) - mov_write_extradata_tag(pb, track); + ret = mov_write_extradata_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) - mov_write_wfex_tag(s, pb, track); + ret = mov_write_wfex_tag(s, pb, track); else if (track->par->codec_id == AV_CODEC_ID_FLAC) - mov_write_dfla_tag(pb, track); + ret = mov_write_dfla_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_OPUS) - mov_write_dops_tag(pb, track); + ret = mov_write_dops_tag(pb, track); else if (track->vos_len > 0) - mov_write_glbl_tag(pb, track); + ret = mov_write_glbl_tag(pb, track); - if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO) - mov_write_chan_tag(s, pb, track); + if (ret < 0) + return ret; - if (mov->encryption_scheme != MOV_ENC_NONE) { - ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid); + if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO + && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) { + return ret; } - return update_size(pb, pos); + if (mov->encryption_scheme != MOV_ENC_NONE + && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) { + return ret; + } + + ret = update_size(pb, pos); + return ret; } static int mov_write_d263_tag(AVIOContext *pb) @@ -2217,22 +2232,27 @@ static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track) static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { int64_t pos = avio_tell(pb); + int ret = 0; avio_wb32(pb, 0); /* size */ ffio_wfourcc(pb, "stsd"); avio_wb32(pb, 0); /* version & flags */ avio_wb32(pb, 1); /* entry count */ if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) - mov_write_video_tag(pb, mov, track); + ret = mov_write_video_tag(pb, mov, track); else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) - mov_write_audio_tag(s, pb, mov, track); + ret = mov_write_audio_tag(s, pb, mov, track); else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) - mov_write_subtitle_tag(pb, track); + ret = mov_write_subtitle_tag(pb, track); else if (track->par->codec_tag == MKTAG('r','t','p',' ')) - mov_write_rtp_tag(pb, track); + ret = mov_write_rtp_tag(pb, track); else if (track->par->codec_tag == MKTAG('t','m','c','d')) - mov_write_tmcd_tag(pb, track); + ret = mov_write_tmcd_tag(pb, track); else if (track->par->codec_tag == MKTAG('g','p','m','d')) - mov_write_gpmd_tag(pb, track); + ret = mov_write_gpmd_tag(pb, track); + + if (ret < 0) + return ret; + return update_size(pb, pos); } @@ -2435,11 +2455,12 @@ static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track) static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { int64_t pos = avio_tell(pb); - int ret; + int ret = 0; avio_wb32(pb, 0); /* size */ ffio_wfourcc(pb, "stbl"); - mov_write_stsd_tag(s, pb, mov, track); + if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0) + return ret; mov_write_stts_tag(pb, track); if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO || track->par->codec_tag == MKTAG('r','t','p',' ')) &&