From patchwork Wed Jul 27 04:21:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xinzheng Zhang X-Patchwork-Id: 11 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.67 with SMTP id o64csp30386vsd; Tue, 26 Jul 2016 21:21:57 -0700 (PDT) X-Received: by 10.194.18.35 with SMTP id t3mr24668807wjd.174.1469593317043; Tue, 26 Jul 2016 21:21:57 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id gm2si4588182wjb.163.2016.07.26.21.21.56; Tue, 26 Jul 2016 21:21:57 -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 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 A53C6689CA6; Wed, 27 Jul 2016 07:21:45 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf0-f194.google.com (mail-pf0-f194.google.com [209.85.192.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 255CD68998A for ; Wed, 27 Jul 2016 07:21:34 +0300 (EEST) Received: by mail-pf0-f194.google.com with SMTP id g202so1073848pfb.1 for ; Tue, 26 Jul 2016 21:21:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Xk3SwLUf9/hZVpmkHwz+f2cR4j4zDUJIQA2SmfI6Cm8=; b=OXQlptsBzUqEEspI3Na6DEqFHPerxwWSesG+6RJIKd46U/5pzG39u92kKfNv8gSOjr 51S3WGgtl6qch9CvRVyIszdaxPmzGdd1sZpHlcmgAaD9DqsDgKQc6qrzZnaEFWj186QU SIPAQFCwQpVh0DuchUxsfVpdlG5pfJ5raOtbzwp+FHZjKfFjkfOxGi2CgXVOVS82Eai+ WQV7/1Yfhxwhei/xI6AW1iTyhuRdBweKUZZaZwsRr/ZpL3hw7qm/dslhPTOHl7ghvGcJ uj3AgleRXkwmYOl56HQhYkcemu6ePbgL/t01spwLAsFy+xe4hhCTJAUxKYQF0MegA/UP U1gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Xk3SwLUf9/hZVpmkHwz+f2cR4j4zDUJIQA2SmfI6Cm8=; b=IdG3jjgKLUU592hSqF+bor4qiUFcw+yI8KDv3K6RDs9GV1SOk7b5OkVZMGJmU3mWTK PZpd3S5NsKgMIMMdNnmSem9jp9KVgR8KgH4KMA4Xi44AU1rBLPN3G9ZvC5bhZj98cyPD nNo97YSn2g+ZUr9LjNFIjSuGV68fZZxdxaLomUiLms/Q1gDyrOlC9Px2X8ZRh9anGlqj w/C6k03gCzh3Qb+T+xOlQ/gpmwTenFuIdwYxwKFNLjDekR4vjH9+ZGOuPjuDjhXsOpmB yiCi6ie2jiI4j2HKSH2XGAIt7JRXi+3eOE51Ciuqmc9uHnL60pyTnQN2u7782j3IRtCR KZBQ== X-Gm-Message-State: AEkoouvAagkCKP+0OJsMKYTgi6DxfcUoPC0AHJGL58ZxG8VBZZ71jSnGDap3ibRu7FL0sA== X-Received: by 10.98.26.133 with SMTP id a127mr45440105pfa.46.1469593296130; Tue, 26 Jul 2016 21:21:36 -0700 (PDT) Received: from localhost.localdomain (014136134118.ctinets.com. [14.136.134.118]) by smtp.gmail.com with ESMTPSA id o8sm4917050pav.5.2016.07.26.21.21.34 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 26 Jul 2016 21:21:35 -0700 (PDT) From: Xinzheng Zhang To: ffmpeg-devel@ffmpeg.org Date: Wed, 27 Jul 2016 12:21:24 +0800 Message-Id: <1469593285-28910-1-git-send-email-zhangxzheng@gmail.com> X-Mailer: git-send-email 2.6.4 (Apple Git-63) In-Reply-To: <1469030804-11538-1-git-send-email-zhangxzheng@gmail.com> References: <1469030804-11538-1-git-send-email-zhangxzheng@gmail.com> Subject: [FFmpeg-devel] [PATCH 1/2] avformat/flvdec: splitting add_keyframes_index() out from parse_keyframes_index() 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: Xinzheng Zhang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavformat/flvdec.c | 76 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 2bf1e05..633cad0 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -61,6 +61,11 @@ typedef struct FLVContext { int broken_sizes; int sum_flv_tag_size; + + int last_keyframe_stream_index; + int keyframe_count; + int64_t *keyframe_times; + int64_t *keyframe_filepositions; } FLVContext; static int probe(AVProbeData *p, int live) @@ -92,6 +97,35 @@ static int live_flv_probe(AVProbeData *p) return probe(p, 1); } +static void add_keyframes_index(AVFormatContext *s) +{ + FLVContext *flv = s->priv_data; + AVStream *stream = NULL; + unsigned int i = 0; + + if (flv->last_keyframe_stream_index < 0) { + av_log(s, AV_LOG_DEBUG, "keyframe stream hasn't been created\n"); + return; + } + + av_assert0(flv->last_keyframe_stream_index <= s->nb_streams); + stream = s->streams[flv->last_keyframe_stream_index]; + + if (stream->nb_index_entries == 0) { + for (i = 0; i < flv->keyframe_count; i++) { + av_add_index_entry(stream, flv->keyframe_filepositions[i], + flv->keyframe_times[i] * 1000, 0, 0, AVINDEX_KEYFRAME); + } + } else + av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); + + if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + av_freep(&flv->keyframe_times); + av_freep(&flv->keyframe_filepositions); + flv->keyframe_count = 0; + } +} + static AVStream *create_stream(AVFormatContext *s, int codec_type) { AVStream *st = avformat_new_stream(s, NULL); @@ -305,8 +339,7 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) return length; } -static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, - AVStream *vstream, int64_t max_pos) +static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t max_pos) { FLVContext *flv = s->priv_data; unsigned int timeslen = 0, fileposlen = 0, i; @@ -316,10 +349,12 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int ret = AVERROR(ENOSYS); int64_t initial_pos = avio_tell(ioc); - if (vstream->nb_index_entries>0) { - av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); + if (flv->keyframe_count > 0) { + av_log(s, AV_LOG_DEBUG, "keyframes have been paresed\n"); return 0; } + av_assert0(!flv->keyframe_times); + av_assert0(!flv->keyframe_filepositions); if (s->flags & AVFMT_FLAG_IGNIDX) return 0; @@ -368,15 +403,17 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, } if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) { - for (i = 0; i < fileposlen; i++) { - av_add_index_entry(vstream, filepositions[i], times[i] * 1000, - 0, 0, AVINDEX_KEYFRAME); - if (i < 2) { - flv->validate_index[i].pos = filepositions[i]; - flv->validate_index[i].dts = times[i] * 1000; - flv->validate_count = i + 1; - } + for (i = 0; i < FFMIN(2,fileposlen); i++) { + flv->validate_index[i].pos = filepositions[i]; + flv->validate_index[i].dts = times[i] * 1000; + flv->validate_count = i + 1; } + flv->keyframe_times = times; + flv->keyframe_filepositions = filepositions; + flv->keyframe_count = timeslen; + times = NULL; + filepositions = NULL; + add_keyframes_index(s); } else { invalid: av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n"); @@ -421,10 +458,9 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, if ((vstream || astream) && key && ioc->seekable && !strcmp(KEYFRAMES_TAG, key) && depth == 1) - if (parse_keyframes_index(s, ioc, vstream ? vstream : astream, + if (parse_keyframes_index(s, ioc, max_pos) < 0) av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); - while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) if (amf_parse_object(s, astream, vstream, str_val, max_pos, @@ -574,6 +610,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { + FLVContext *flv = s->priv_data; AMFDataType type; AVStream *stream, *astream, *vstream; AVStream av_unused *dstream; @@ -612,10 +649,14 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) // the lookup every time it is called. for (i = 0; i < s->nb_streams; i++) { stream = s->streams[i]; - if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) + if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { vstream = stream; - else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) + flv->last_keyframe_stream_index = i; + } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { astream = stream; + if (flv->last_keyframe_stream_index == -1) + flv->last_keyframe_stream_index = i; + } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) dstream = stream; } @@ -643,6 +684,7 @@ static int flv_read_header(AVFormatContext *s) s->start_time = 0; flv->sum_flv_tag_size = 0; + flv->last_keyframe_stream_index = -1; return 0; } @@ -653,6 +695,8 @@ static int flv_read_close(AVFormatContext *s) FLVContext *flv = s->priv_data; for (i=0; inew_extradata[i]); + av_freep(&flv->keyframe_times); + av_freep(&flv->keyframe_filepositions); return 0; }