From patchwork Wed Feb 21 03:08:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 7687 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.150.33 with SMTP id c30csp293078jai; Tue, 20 Feb 2018 19:09:18 -0800 (PST) X-Google-Smtp-Source: AH8x226IXL3Mn48xhwpUyMV3D5EdBoU6UbN606j5/TCtiJBYwVGDiVghK7nJxESVXt8Tz8v9gWFK X-Received: by 10.223.135.65 with SMTP id 1mr1529195wrz.238.1519182558230; Tue, 20 Feb 2018 19:09:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519182558; cv=none; d=google.com; s=arc-20160816; b=Nz6nb1I1JRQnMP5YgyT0m3765xaWH4mMWBRSst3gDiB0Fm/LMtBP9tcnqp1vAdzKdR s2KIHdRFi3ADRWrlpA0u1qQdBK+QVeJ+l+70+LqjnDUSOzRHWbvU+gMHJwmJfPuIMju4 8EQsG/VsiqjqttZWWPYoPa2IzTlmQlMkJvSpr6wr/cIvEzunPLcIH8dXmFb2VtfVph24 sqIcWbRHMhURWcBZAbHG2VE7HgZJOv19WOsHlYqhpo3efj8SxFY4YRxjkGDkPURLyhGP jCwgCw9KD1J/xdW9OFog0x91BiLjvpv4WL+U6WC7WW4Lg7xcBMwZjdj4fYnWttEw9XN+ 59GA== 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:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=2aLxKnP4Xs/RS7WqzIRxfFhKkExcg8CD2ZPEMzpDQFk=; b=n7ZkR0AABEzjRKsx1iuW4xKqTr16ePVOuDLQ6zr5TVT6vOCkzxLuHEFPxQwvkM0+gp jbJ0TxD/WBheRjrjbJ+jvdpQF2RyFsmpJMTD5AgaaZnJyeVHFLQAJ/2XKeQZJFdmzKw2 67DuUksZmjfC982dlkdrF8wGzhhi1zX0GRkhU1s9tb3tcq81TZQ+x3t8toaPouXuzYbi zzyyRSDmcH1cABOzGwrDnXyD69WsvfpcON0n6cfgdSb6Evrpt/kJ87e0LPCRg+wKgoaM gcFRHkf6U4jA1xr1TQmAuJ/dLFiHKIxpkyDEhtIgJAT37WuQdfOkHMMZtWkQ0mtvWYg3 PZyQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=U7aUaG7Y; 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 j125si2954543wmd.133.2018.02.20.19.09.17; Tue, 20 Feb 2018 19:09:18 -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=20161025 header.b=U7aUaG7Y; 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 1D90768A331; Wed, 21 Feb 2018 05:09:14 +0200 (EET) 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 8202168A30F for ; Wed, 21 Feb 2018 05:09:07 +0200 (EET) Received: by mail-qk0-f195.google.com with SMTP id z197so293684qkb.6 for ; Tue, 20 Feb 2018 19:09:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=fNcleHyx6xBI0WNRp9V+WfAFbz47J0DWM3F4ihgtibs=; b=U7aUaG7YhH1DzmZMnHK2v0BabbRu5iupo7DZ3+OTTl/geQ7f16dXmDUEYyaOdBzLS+ pMVhOOzcaXPbL860tF7xhRfF1PtWVI8px3a6MR9ZWlPS/VHFlBqjLcwsw2mrgvoKTQER T/HBvTwRKTAIslesAyIXJSczkJjgLuHgKTznCaKLEVg7rEQ4cuBCmbOugfpLkRBXLn5x kt+qt/99dgX0QSTl/HvuUy2flWVGDtIf621AC5tTWZh0WgIO55WnlK598FKWCQl7CGm+ LgW4CO0UcjAxfq79D6R1j2eNpC2oYWU+ydwAnNK2de9SXBOHu2SBmOvkGAtTVBW+Blnc bvvw== 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; bh=fNcleHyx6xBI0WNRp9V+WfAFbz47J0DWM3F4ihgtibs=; b=e7ZFI0EejMJ9b7PApxFeTZKf4kMIT/wLmsdTt1tCflxzemG+g3vtQMqmZzWA1ZcWeT HzVAbnX6rcz/hsFiZVHkuk9QmkngNB1o365xT+x6K+xo5oP3erGBK3YsHKT18EKYOxTv BoY90aTfSDOjHNEW4zSS3TpKHxUqjzC4j/hJzT/V2ethEBuIeY0gG/d/G0ytU+tbqgtw LkwpkEY5zkY1u1ieYNJHmLRTBZHimuQ/eq7ZSYSpx2LLXM+uaima6pJHf5zz1Dj75VeC ReCTJhBPjpZAMi231ftsP08Tm8+c+nohfACznI8vO7MUJvAMRnXnfvw+FyC2i8yEX46S Iv3Q== X-Gm-Message-State: APf1xPB21iXH3CQTn/Gd24m/xaXbN+HcNZGnpFgBHHt+MRTizIpyj187 ZJNH1rojHmuZa70w6uaC4u8PvA== X-Received: by 10.55.33.129 with SMTP id f1mr3071410qki.158.1519182547397; Tue, 20 Feb 2018 19:09:07 -0800 (PST) Received: from localhost.localdomain ([181.229.225.176]) by smtp.gmail.com with ESMTPSA id f134sm3599749qke.78.2018.02.20.19.09.05 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Feb 2018 19:09:06 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Wed, 21 Feb 2018 00:08:45 -0300 Message-Id: <20180221030845.6056-1-jamrial@gmail.com> X-Mailer: git-send-email 2.16.2 Subject: [FFmpeg-devel] [PATCH] avformat/matroskadec: use a linked list to queue packets 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" It's more robust and efficient. Signed-off-by: James Almer --- libavformat/matroskadec.c | 90 +++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 2faaf9dfb8..241ee5fed1 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -338,9 +338,8 @@ typedef struct MatroskaDemuxContext { int64_t segment_start; /* the packet queue */ - AVPacket **packets; - int num_packets; - AVPacket *prev_pkt; + AVPacketList *queue; + AVPacketList *queue_end; int done; @@ -2722,11 +2721,14 @@ fail: static int matroska_deliver_packet(MatroskaDemuxContext *matroska, AVPacket *pkt) { - if (matroska->num_packets > 0) { + if (matroska->queue) { MatroskaTrack *tracks = matroska->tracks.elem; MatroskaTrack *track; - memcpy(pkt, matroska->packets[0], sizeof(AVPacket)); - av_freep(&matroska->packets[0]); + AVPacketList *pktl = matroska->queue; + + av_packet_move_ref(pkt, &pktl->pkt); + matroska->queue = pktl->next; + av_free(pktl); track = &tracks[pkt->stream_index]; if (track->has_palette) { uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); @@ -2737,41 +2739,45 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, } track->has_palette = 0; } - if (matroska->num_packets > 1) { - void *newpackets; - memmove(&matroska->packets[0], &matroska->packets[1], - (matroska->num_packets - 1) * sizeof(AVPacket *)); - newpackets = av_realloc(matroska->packets, - (matroska->num_packets - 1) * - sizeof(AVPacket *)); - if (newpackets) - matroska->packets = newpackets; - } else { - av_freep(&matroska->packets); - matroska->prev_pkt = NULL; - } - matroska->num_packets--; + if (!matroska->queue) + matroska->queue_end = NULL; return 0; } return -1; } +static int matroska_queue_packet(MatroskaDemuxContext *matroska, AVPacket *pkt) +{ + AVPacketList *pktl = av_malloc(sizeof(*pktl)); + + if (!pktl) + return AVERROR(ENOMEM); + av_packet_move_ref(&pktl->pkt, pkt); + pktl->next = NULL; + + if (matroska->queue_end) + matroska->queue_end->next = pktl; + else + matroska->queue = pktl; + matroska->queue_end = pktl; + + return 0; +} + /* * Free all packets in our internal queue. */ static void matroska_clear_queue(MatroskaDemuxContext *matroska) { - matroska->prev_pkt = NULL; - if (matroska->packets) { - int n; - for (n = 0; n < matroska->num_packets; n++) { - av_packet_unref(matroska->packets[n]); - av_freep(&matroska->packets[n]); - } - av_freep(&matroska->packets); - matroska->num_packets = 0; + AVPacketList *pktl; + + while (pktl = matroska->queue) { + av_packet_unref(&pktl->pkt); + matroska->queue = pktl->next; + av_free(pktl); } + matroska->queue_end = NULL; } static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, @@ -2953,7 +2959,11 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, track->audio.buf_timecode = AV_NOPTS_VALUE; pkt->pos = pos; pkt->stream_index = st->index; - dynarray_add(&matroska->packets, &matroska->num_packets, pkt); + ret = matroska_queue_packet(matroska, pkt); + if (ret < 0) { + av_packet_free(&pkt); + return AVERROR(ENOMEM); + } } return 0; @@ -3152,8 +3162,11 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, pkt->duration = duration; pkt->pos = pos; - dynarray_add(&matroska->packets, &matroska->num_packets, pkt); - matroska->prev_pkt = pkt; + err = matroska_queue_packet(matroska, pkt); + if (err < 0) { + av_packet_free(&pkt); + return AVERROR(ENOMEM); + } return 0; } @@ -3268,8 +3281,11 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif - dynarray_add(&matroska->packets, &matroska->num_packets, pkt); - matroska->prev_pkt = pkt; + res = matroska_queue_packet(matroska, pkt); + if (res < 0) { + av_packet_free(&pkt); + return AVERROR(ENOMEM); + } return 0; @@ -3433,7 +3449,6 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska) memset(&matroska->current_cluster, 0, sizeof(MatroskaCluster)); matroska->current_cluster_num_blocks = 0; matroska->current_cluster_pos = avio_tell(matroska->ctx->pb); - matroska->prev_pkt = NULL; /* sizeof the ID which was already read */ if (matroska->current_id) matroska->current_cluster_pos -= 4; @@ -3486,7 +3501,6 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska) if (!matroska->contains_ssa) return matroska_parse_cluster_incremental(matroska); pos = avio_tell(matroska->ctx->pb); - matroska->prev_pkt = NULL; if (matroska->current_id) pos -= 4; /* sizeof the ID which was already read */ res = ebml_parse(matroska, matroska_clusters, &cluster); @@ -3671,10 +3685,10 @@ static int webm_clusters_start_with_keyframe(AVFormatContext *s) matroska->current_id = 0; matroska_clear_queue(matroska); if (matroska_parse_cluster(matroska) < 0 || - matroska->num_packets <= 0) { + !matroska->queue) { break; } - pkt = matroska->packets[0]; + pkt = &matroska->queue->pkt; cluster_pos += cluster_length + 12; // 12 is the offset of the cluster id and length. if (!(pkt->flags & AV_PKT_FLAG_KEY)) { rv = 0;