From patchwork Mon May 8 04:36:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodger Combs X-Patchwork-Id: 3610 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.3.129 with SMTP id 123csp684264vsd; Sun, 7 May 2017 21:42:56 -0700 (PDT) X-Received: by 10.223.132.39 with SMTP id 36mr26115531wrf.179.1494218576702; Sun, 07 May 2017 21:42:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494218576; cv=none; d=google.com; s=arc-20160816; b=02evVE2R+LmTRbBe2gfZx3AuSN2lAwdlQQC+zoYm9pWsxORnRp5bVn7Btn8hzL+ZNG 155T6qyxVttoy2ffFDl2HTno/HYWaNS4ArF9BsDqn2E5mPfvV1djS/gt44AJvtnrqtBV RSVC7puNIqgo28w5HsYlwo2np0IYqK2pi8J6pEw5uF8kP1/qEcnZuIVgTfQcOg9iM7wW LFnfINSxWIDIpRp1lF33OKcawNmQ5LaYBqFJ10gF18bbJiFcGmeRKe3zcUdf8TpUVcev J+I2j9zV60TsMiB6O09KK3otxdAe8iWaz3fVg1KDiQupS1Nw4xZQxSJd/SugiXcFR9WR 9mEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=MrkkJ5PJsO5oeP4YftSXQf6nGymKSheSMhJOs6f4tqk=; b=rJLt4zKn9buv6rosUzZTdywNfcI9vrpBN8UN386jHgO6UPriGGl1pMKWXXZaltL68S U4qwGDOv6M0WdwMWKN1VlrvFWkdlm33zsAIlSZnrMKDYGHkPyJ8jqUMBqhmxnYihJrri FhKbMbPWINsLHIoqv4AE0+DqW14EARZUCAV4oqiPRXVDTxD38m/4vb/Mc9/v9ZeVfC/x ROhSTr2eYqa8cgbVJxC+QOxhYm4uwOowjNcBd1w2gZet9pA+0sYuqvhsXxQfScu41Az+ 7JH0CtPqgABLT0QUHQkCLrrUcENJezSzFG/i1gMsUlf9b6NGPNxhYEp7N95FR8SlE1zJ thLw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com; 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=NONE 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 l204si2392124wmf.95.2017.05.07.21.42.56; Sun, 07 May 2017 21:42:56 -0700 (PDT) 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; 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=NONE 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 7C60C6882A1; Mon, 8 May 2017 07:42:48 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk0-f195.google.com (mail-qk0-f195.google.com [209.85.220.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D9928688287 for ; Mon, 8 May 2017 07:42:41 +0300 (EEST) Received: by mail-qk0-f195.google.com with SMTP id u75so8633233qka.1 for ; Sun, 07 May 2017 21:42:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=duZlwfjKjydQrbFh/geP8pvl7D1x27kVYtDxqUpCMTw=; b=Lp8slxZL7e4sNBSgZqNMAP3qbx0rRDd5S7cM3sU7JU0Q7k2nYE3tKdMBdMpTmI8BWn VbE7Q4aonWN7jeQcb9MKVhousbyQHpDxylJxfrldc2qUTotlZFXAECvShmooNrUSnmZ5 b3yeSFeYd3o8hYG3bkFOxbWZ0Zt4Id4HszdXZ3d7mxxpDnu8+5LIT9Nk6thjnJctAOlO L6jZ23L8Ft9/wT6ECRQdcmp9w+l5lv9KZQih11jEwvOY5Plst/CMs9RQFtMyZ8s5+qbV 0N30B7YQLnBG9ikzn5rLXQgbmzyrdeVGfKaGByB40vwBVmr7vGSly6T2PiI8+FL3mXjj TueQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=duZlwfjKjydQrbFh/geP8pvl7D1x27kVYtDxqUpCMTw=; b=D0H3EX0UFpAe/8SlwP/LyAxbdKTEW2h/Dnyd8ObG14hO69R+mkSpfl0gyK14oI7jn+ 2YDQdCwOM6eXlNza+vJYc54P856qUtYwl3/xVC0LxKD2xryOdGXmItt6bHX+Fm81nEX9 VYf7WQbxdDWNGlwH5D3/jE5i6lhlyErZJpp5OCdC1WevvEjRaTViIlRAz+yC1ZV8j2z8 FhNA5V9KM9T60IPUgn8+R4JwY3QFBe5eP+v8HESyeih/761YIaIZTgiZ/x01WM3LIsHs 8/68IMH0tPcLWOkGuR0ifNSyaUP4AjdXg5/9+7bZxbixU4qQgAr7acar6rGdS2kIc845 0udQ== X-Gm-Message-State: AODbwcAGrSxbp4bPKrKOzUik2JUmjladsXO0Ots+SoMZdgPaLPq7AWoj 4LfyXHXiP6uvkXvvopk= X-Received: by 10.55.31.222 with SMTP id n91mr21668767qkh.69.1494218192082; Sun, 07 May 2017 21:36:32 -0700 (PDT) Received: from rcombs-NAS.hsd1.il.comcast.net. (c-73-110-121-59.hsd1.il.comcast.net. [73.110.121.59]) by smtp.gmail.com with ESMTPSA id 88sm10056162qkx.68.2017.05.07.21.36.31 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 07 May 2017 21:36:31 -0700 (PDT) From: Rodger Combs To: ffmpeg-devel@ffmpeg.org Date: Sun, 7 May 2017 23:36:24 -0500 Message-Id: <1494218184-17850-7-git-send-email-rodger.combs@gmail.com> X-Mailer: git-send-email 2.6.4 In-Reply-To: <1494218184-17850-1-git-send-email-rodger.combs@gmail.com> References: <1494218184-17850-1-git-send-email-rodger.combs@gmail.com> Subject: [FFmpeg-devel] [PATCH 7/7] lavf/flacenc: generate timestamps internally 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavformat/flacenc.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index b8800cc..0e948ac 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -30,6 +30,7 @@ #include "internal.h" #include "vorbiscomment.h" #include "libavcodec/bytestream.h" +#include "libavutil/crc.h" typedef struct FlacMuxerContext { @@ -46,6 +47,9 @@ typedef struct FlacMuxerContext { uint8_t *streaminfo; unsigned attached_types; + + uint64_t samples; + unsigned last_bs; } FlacMuxerContext; static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_bytes, @@ -256,11 +260,17 @@ static int flac_write_header(struct AVFormatContext *s) return ret; } +static const int32_t blocksize_table[16] = { + 0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0, +256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7 +}; + static int flac_write_audio_packet(struct AVFormatContext *s, AVPacket *pkt) { FlacMuxerContext *c = s->priv_data; uint8_t *streaminfo; int streaminfo_size; + char header[16]; /* check for updated streaminfo */ streaminfo = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, @@ -274,8 +284,77 @@ static int flac_write_audio_packet(struct AVFormatContext *s, AVPacket *pkt) memcpy(c->streaminfo, streaminfo, FLAC_STREAMINFO_SIZE); } - if (pkt->size) - avio_write(s->pb, pkt->data, pkt->size); + if (pkt->size) { + uint8_t tmp; + uint64_t pts = c->samples; + int offset = 5; + int headerlen = 4; + int bscode, bs; + int crc; + if (pkt->size < FLAC_MIN_FRAME_SIZE) + return AVERROR_INVALIDDATA; + memcpy(header, pkt->data, 4); + if (pkt->pts == AV_NOPTS_VALUE) + pts = 0; + if ((pkt->data[4] & 0xC0) == 0xC0) + offset += ff_clz((unsigned char)~pkt->data[4]) - 25; + else if (pkt->data[4] & 0x80) + return AVERROR_INVALIDDATA; + if (pkt->size <= offset + 1) + return AVERROR_INVALIDDATA; + + bscode = (unsigned char)header[2] >> 4; + bs = blocksize_table[bscode]; + if (bscode == 0) + return AVERROR_INVALIDDATA; + if (bscode == 6) { + if (pkt->size <= offset + 1) + return AVERROR_INVALIDDATA; + bs = pkt->data[offset] + 1; + } else if (bscode == 7) { + if (pkt->size <= offset + 2) + return AVERROR_INVALIDDATA; + bs = AV_RB16(&pkt->data[offset]) + 1; + } + if ((header[1] & 1) == 0) + pts /= c->last_bs ? c->last_bs : bs; + + c->last_bs = bs; + + c->samples += bs; + + PUT_UTF8(pts, tmp, header[headerlen++] = tmp;) + if (headerlen > 11) + return AVERROR_INVALIDDATA; + if ((bscode & 0xE) == 0x6) + header[headerlen++] = pkt->data[offset++]; + if (pkt->size <= offset + 1) + return AVERROR_INVALIDDATA; + if (bscode == 0x7) + header[headerlen++] = pkt->data[offset++]; + if (pkt->size <= offset + 1) + return AVERROR_INVALIDDATA; + if ((header[2] & 0xC) == 0xC) { + header[headerlen++] = pkt->data[offset++]; + if (pkt->size <= offset + 1) + return AVERROR_INVALIDDATA; + if ((header[2] & 0x3) == 0x3) + return AVERROR_INVALIDDATA; + else if (header[2] & 0x3) { + header[headerlen++] = pkt->data[offset++]; + if (pkt->size <= offset + 1) + return AVERROR_INVALIDDATA; + } + } + header[headerlen] = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, header, headerlen); + headerlen++; offset++; + crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, header, headerlen); + if (pkt->size < offset + 3) + return AVERROR_INVALIDDATA; + avio_write(s->pb, header, headerlen); + avio_write(s->pb, pkt->data + offset, pkt->size - offset - 2); + avio_wl16(s->pb, av_crc(av_crc_get_table(AV_CRC_16_ANSI), crc, pkt->data + offset, pkt->size - offset - 2)); + } return 0; } @@ -319,7 +398,10 @@ static int flac_write_trailer(struct AVFormatContext *s) /* rewrite the STREAMINFO header block data */ file_size = avio_tell(pb); avio_seek(pb, 8, SEEK_SET); - avio_write(pb, streaminfo, FLAC_STREAMINFO_SIZE); + avio_write(pb, streaminfo, 13); + avio_w8(pb, (streaminfo[13] & 0xF0) | ((c->samples >> 32) & 0xF)); + avio_wb32(pb, c->samples); + avio_write(pb, streaminfo + 18, FLAC_STREAMINFO_SIZE - 18); avio_seek(pb, file_size, SEEK_SET); avio_flush(pb); } else {