From patchwork Thu Feb 20 21:43:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Hubbard X-Patchwork-Id: 17859 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 2876644A94E for ; Thu, 20 Feb 2020 23:44:03 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 04CD968B0D0; Thu, 20 Feb 2020 23:44:03 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f201.google.com (mail-qt1-f201.google.com [209.85.160.201]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 60EC868B0A4 for ; Thu, 20 Feb 2020 23:43:56 +0200 (EET) Received: by mail-qt1-f201.google.com with SMTP id t4so131289qtd.3 for ; Thu, 20 Feb 2020 13:43:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to; bh=87VQcV/Aya+98PuwvNdhZd9MBpQCUmd9upf1KOnvd6A=; b=TGse0TFgmf7l36h9crzoW8gAQGXVFBzWg6qCj6C0VpJ5ulYqO4pIO6pSuLvgH5DDQy 809TOqyhlg/O9VcL7abB0img+SWYMnxphQDZ1UDXm91ldoCkWejpvnGahOs1nqeVi3Tp qnGlH97UVrIk5yUdTszEHIc8TMFDe3h6adBj6mKnO2k9HkpVlJGhR5S2sBlyg2qxgXut 5vXUoK6RLJY2VqI0mbdhPPb1lxGnS4N0AggUhgZoVL3WebzfgUOR82KT5wfxBHLWbROK wyomabaezTSbBEFd+Iaevx+FoGM4J5lRB6oKO8xTe6yed0+j0r1HCQEPEsHn6ARnOVhQ Srfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to; bh=87VQcV/Aya+98PuwvNdhZd9MBpQCUmd9upf1KOnvd6A=; b=b9amR6HLf++CFl94+6VJtgdOt+HPXGRS1K+ShkOvJVE5c/DREOncXRhKL1EbQvwD8C cUF/QN+t68+jnJpKOpSvWvMBvW1I1dcg4DyCIT0pJajZOo+cNcVTzsFbLze3ylY8XJ6m +VRv/tmY7dcaOst5xpl1exleKKJAZuo9uvu5iJQxrnRSIZMmUUtse8Z5K+6WuunHqrt5 dgQVc4aaPgwVGdUQ4tc72ajTqjrVYAa8va7THaiQA42NV3QfIL4H7/kFYRG789U9HvD+ gX9j+IRAdybLDM1ANZsgKTFVGcPOhsEoZTxsAjdug6vc5pGhnYL5RZIwkIb+gL3vU/+I WeHA== X-Gm-Message-State: APjAAAXfKysZdL0i85+Pp0PvZPyEbF+qvyko8T4zyKwdKefOeXOm0Fcw qUbckGTC0APnJQT1vmSb5CcoeWWPfCmwSU6mPIcwuxB+oZwKEaSKcqxDWF0ionId1exX9sLvYvp 8aucqqAdCXG4uwNhmHgYagAOKOG/r9eleLoVh0jLoCnvOizLYJi9iRPICBw== X-Google-Smtp-Source: APXvYqxBD/yAkgIqIn9MELhSMrZhlPsRG3gd1WtUtBSgOQruvPlbv6hfiezLIZK2JeUs+ig/G/kYuxFV X-Received: by 2002:ae9:e114:: with SMTP id g20mr30174445qkm.458.1582235034546; Thu, 20 Feb 2020 13:43:54 -0800 (PST) Date: Thu, 20 Feb 2020 16:43:53 -0500 Message-Id: <20200220214353.240335-1-sebh@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog From: Sebastian Hubbard To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH] avformat/ac3dec: detect fairplay encryption 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Added id3v2_buf and id3v2_buf_size fields to AVProbeData. When an id3v2 tag is found at the start of probed content, id3v2_buf is filled with a pointer to the start of the tag bytes, and id3v2_buf_size with the number of bytes in the tag. ac3_eac3_probe checks the tag when present for a private frame with an owner identifier of com.apple.streaming.audioDescription, which signals that the file is encrypted with an Apple DRM scheme. The CRC checksums for such files are for the content post-decryption, and with this change they are skipped when Apple DRM is detected. This enables ffprobe to detect the stream type, even though it will not be playable. Signed-off-by: Sebastian Hubbard --- libavformat/ac3dec.c | 22 ++++++++++++++++++++-- libavformat/avformat.h | 2 ++ libavformat/format.c | 6 ++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c index 1f87939388..c29c6fb27b 100644 --- a/libavformat/ac3dec.c +++ b/libavformat/ac3dec.c @@ -24,17 +24,35 @@ #include "libavcodec/ac3_parser.h" #include "avformat.h" #include "rawdec.h" +#include "id3v2.h" +#include "avio_internal.h" static int ac3_eac3_probe(const AVProbeData *p, enum AVCodecID expected_codec_id) { int max_frames, first_frames = 0, frames; const uint8_t *buf, *buf2, *end; enum AVCodecID codec_id = AV_CODEC_ID_AC3; + AVIOContext ioctx; + AVDictionary *metadata = NULL; + ID3v2ExtraMeta *id3v2_extra_meta = NULL; + int skip_crc = 0; max_frames = 0; buf = p->buf; end = buf + p->buf_size; + if (p->id3v2_buf && p->id3v2_buf_size > 0) { + ffio_init_context(&ioctx, p->id3v2_buf, p->id3v2_buf_size, 0, NULL, NULL, NULL, NULL); + ff_id3v2_read_dict(&ioctx, &metadata, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); + if (!ff_id3v2_parse_priv_dict(&metadata, &id3v2_extra_meta)) { + if (av_dict_get(metadata, "id3v2_priv.com.apple.streaming.audioDescription", NULL, 0)) { + skip_crc = 1; + } + } + ff_id3v2_free_extra_meta(&id3v2_extra_meta); + av_dict_free(&metadata); + } + for(; buf < end; buf++) { if(buf > p->buf && !(buf[0] == 0x0B && buf[1] == 0x77) && !(buf[0] == 0x77 && buf[1] == 0x0B) ) @@ -72,10 +90,10 @@ static int ac3_eac3_probe(const AVProbeData *p, enum AVCodecID expected_codec_id buf3[i ] = buf2[i+1]; buf3[i+1] = buf2[i ]; } - if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf3 + 2, frame_size - 2)) + if (!skip_crc && av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf3 + 2, frame_size - 2)) break; } else { - if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf2 + 2, frame_size - 2)) + if (!skip_crc && av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf2 + 2, frame_size - 2)) break; } if (bitstream_id > 10) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 9b9b634ec3..afd1b67b5c 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -448,6 +448,8 @@ typedef struct AVProbeData { unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */ int buf_size; /**< Size of buf except extra allocated bytes */ const char *mime_type; /**< mime_type, when known. */ + unsigned char *id3v2_buf; /**< Bytes of id3v2 tag if one was found at start of file. */ + int id3v2_buf_size; /**< Size of id3v2_buf */ } AVProbeData; #define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4) diff --git a/libavformat/format.c b/libavformat/format.c index c47490c8eb..cd510976a6 100644 --- a/libavformat/format.c +++ b/libavformat/format.c @@ -149,8 +149,10 @@ ff_const59 AVInputFormat *av_probe_input_format3(ff_const59 AVProbeData *pd, int if (lpd.buf_size > id3len + 16) { if (lpd.buf_size < 2LL*id3len + 16) nodat = ID3_ALMOST_GREATER_PROBE; - lpd.buf += id3len; - lpd.buf_size -= id3len; + lpd.id3v2_buf = lpd.buf; + lpd.id3v2_buf_size = id3len; + lpd.buf += id3len; + lpd.buf_size -= id3len; } else if (id3len >= PROBE_BUF_MAX) { nodat = ID3_GREATER_MAX_PROBE; } else