From patchwork Thu May 16 22:30:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 13163 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 66E8F449A02 for ; Fri, 17 May 2019 01:48:42 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 29887689FB4; Fri, 17 May 2019 01:48:42 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 96F766809C2 for ; Fri, 17 May 2019 01:48:35 +0300 (EEST) Received: by mail-wm1-f68.google.com with SMTP id 7so4973295wmo.2 for ; Thu, 16 May 2019 15:48:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SI1zik4GuPUNm6AEMgqCAB6TiwawLEfj86pI/9lZbJo=; b=GtOzr1NOMtRF+uDcPUA+NFLeYZ2ZhX7ideTzLqrsk/Cci2Y3B8Bo0wPLrhJNzN4LTD oh9k57Q4VGzzLQznrLSi9I/eZihdYDZl1c93/dRLzLenQ+9PmmnUSoSiCQegw7E8simt 6zu6BduOlRchpqyaX1bOXlFhTbW4YBnzTw+/pjtwL7OK/3tQaWpZDYUQ/3tujuvPSXOk fSvpdFtoMucRRx2LKWittjUiCQJxl0kpfzHllmaLY+SlClL0qv1rnGizBBe2HNAC3Igu uY6r0kG2Fhn5T6cU4HJKJiO0LnoWi0x/JBc8cuktPKn9g41oHmYQ/nrmjg29M6bPaMPE ZIvg== 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=SI1zik4GuPUNm6AEMgqCAB6TiwawLEfj86pI/9lZbJo=; b=LTUAjkHsHCcM49UJsAnpV00DZZm7m/3o3zrbr9zS0ykjuhIV9Cj9M3LDUF2wqifSS+ 9C9v+fGdn4hcMdcipNhqZOO8rp9KLenjwbYJDcLFaBsMRhVWXysV+zj3tLDJjlE3h0r9 AXP7qxX3GhEVIPHmXZ9ns8OUTr4gZZcJ66naLrCn05LPM9m2FHKnxiva/TdrhnqKZSvH FU3JrAuAiAf/r2G6z+3nA7m9DC+HZXDn+Gl2QSBtLo2oKsQ4oNMnE6eSBE8XUac+GxPL o3xMoyUkNxhKSiiVUykbBqTdanBaayBeCeSyzY8wkSCNlK/NOlR2FU0p3S+pQ7stP+wS /kgg== X-Gm-Message-State: APjAAAWOiysrf2JmcHZ90O8bZFdenVY1pDpo9ztqKD6Y09Q9T33QI9J2 Hfb0evFt5li0l45afSaCeE97I6vG X-Google-Smtp-Source: APXvYqzMGh7qagZFPq/+S8tGXHUpTk9cl7/HaD/VPNsdQonqxTSxfZq3QJrrFmaSWwMHBozi6OIAAg== X-Received: by 2002:a1c:414:: with SMTP id 20mr27914296wme.84.1558046597512; Thu, 16 May 2019 15:43:17 -0700 (PDT) Received: from localhost.localdomain (ipbcc18715.dynamic.kabel-deutschland.de. [188.193.135.21]) by smtp.gmail.com with ESMTPSA id i185sm11168725wmg.32.2019.05.16.15.43.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 May 2019 15:43:17 -0700 (PDT) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Fri, 17 May 2019 00:30:03 +0200 Message-Id: <20190516223018.30827-20-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190516223018.30827-1-andreas.rheinhardt@gmail.com> References: <20190516223018.30827-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] =?utf-8?q?=5BPATCH_19/37=5D_avformat/matroskadec?= =?utf-8?q?=3A_Use_proper_levels_after_discont=C3=ADnuity?= 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" The earlier code set the level to zero upon seeking and after a discontinuity although in both cases parsing (re)starts at a level 1 element. Also set the segment's length to unkown if an error occured in order not to drop any valid data that happens to be beyond the designated end of the segment. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskadec.c | 45 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 4e81108dbe..2084b72748 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -762,8 +762,6 @@ static int matroska_resync(MatroskaDemuxContext *matroska, int64_t last_pos) { AVIOContext *pb = matroska->ctx->pb; uint32_t id; - matroska->current_id = 0; - matroska->num_levels = 0; /* Try to seek to the last position to resync from. If this doesn't work, * we resync from the earliest position available: The start of the buffer. */ @@ -783,7 +781,13 @@ static int matroska_resync(MatroskaDemuxContext *matroska, int64_t last_pos) id == MATROSKA_ID_CUES || id == MATROSKA_ID_TAGS || id == MATROSKA_ID_SEEKHEAD || id == MATROSKA_ID_ATTACHMENTS || id == MATROSKA_ID_CLUSTER || id == MATROSKA_ID_CHAPTERS) { - matroska->current_id = id; + /* Prepare the context for parsing of a level 1 element. */ + matroska_reset_status(matroska, id, -1); + /* Given that we are here means that an error has occured, + * so treat the segment as unknown length in order not to + * discard valid data that happens to be beyond the designated + * end of the segment. */ + matroska->levels[0].length = EBML_UNKNOWN_LENGTH; return 0; } id = (id << 8) | avio_r8(pb); @@ -1671,18 +1675,11 @@ static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, matroska->current_id = 0; ret = ebml_parse(matroska, matroska_segment, matroska); - - /* remove dummy level */ - while (matroska->num_levels) { - uint64_t length = matroska->levels[--matroska->num_levels].length; - if (length == EBML_UNKNOWN_LENGTH) - break; - } } } - /* seek back */ - avio_seek(matroska->ctx->pb, before_pos, SEEK_SET); - matroska->current_id = saved_id; + /* Seek back - notice that in all instances where this is used it is safe + * to set the level to 1 and unset the position of the current cluster. */ + matroska_reset_status(matroska, saved_id, before_pos); return ret; } @@ -3596,9 +3593,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, timestamp = FFMAX(timestamp, st->index_entries[0].timestamp); if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) { - avio_seek(s->pb, st->index_entries[st->nb_index_entries - 1].pos, - SEEK_SET); - matroska->current_id = 0; + matroska_reset_status(matroska, 0, st->index_entries[st->nb_index_entries - 1].pos); while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) { matroska_clear_queue(matroska); if (matroska_parse_cluster(matroska) < 0) @@ -3618,8 +3613,8 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, tracks[i].end_timecode = 0; } - avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET); - matroska->current_id = 0; + /* We seek to a level 1 element, so set the appropriate status. */ + matroska_reset_status(matroska, 0, st->index_entries[index].pos); if (flags & AVSEEK_FLAG_ANY) { st->skip_to_keyframe = 0; matroska->skip_to_timecode = timestamp; @@ -3629,18 +3624,16 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, } matroska->skip_to_keyframe = 1; matroska->done = 0; - matroska->num_levels = 0; ff_update_cur_dts(s, st, st->index_entries[index].timestamp); return 0; err: // slightly hackish but allows proper fallback to // the generic seeking code. + matroska_reset_status(matroska, 0, -1); matroska_clear_queue(matroska); - matroska->current_id = 0; st->skip_to_keyframe = matroska->skip_to_keyframe = 0; matroska->done = 0; - matroska->num_levels = 0; return -1; } @@ -3703,6 +3696,7 @@ static CueDesc get_cue_desc(AVFormatContext *s, int64_t ts, int64_t cues_start) static int webm_clusters_start_with_keyframe(AVFormatContext *s) { MatroskaDemuxContext *matroska = s->priv_data; + uint32_t id = matroska->current_id; int64_t cluster_pos, before_pos; int index, rv = 1; if (s->streams[0]->nb_index_entries <= 0) return 0; @@ -3723,8 +3717,8 @@ static int webm_clusters_start_with_keyframe(AVFormatContext *s) read = ebml_read_length(matroska, matroska->ctx->pb, &cluster_length); if (read < 0) break; - avio_seek(s->pb, cluster_pos, SEEK_SET); - matroska->current_id = 0; + + matroska_reset_status(matroska, 0, cluster_pos); matroska_clear_queue(matroska); if (matroska_parse_cluster(matroska) < 0 || !matroska->queue) { @@ -3738,7 +3732,10 @@ static int webm_clusters_start_with_keyframe(AVFormatContext *s) break; } } - avio_seek(s->pb, before_pos, SEEK_SET); + + /* Restore the status after matroska_read_header: */ + matroska_reset_status(matroska, id, before_pos); + return rv; }