From patchwork Wed Jun 17 19:45:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Timotej Lazar X-Patchwork-Id: 20442 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 CE9D544A7D6 for ; Wed, 17 Jun 2020 22:51:55 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id AFE3D68B2FD; Wed, 17 Jun 2020 22:51:55 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from araneo.si (araneo.si [90.157.193.204]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BFB1F68A800 for ; Wed, 17 Jun 2020 22:51:49 +0300 (EEST) Received: from araneo.si (localhost.lan [127.0.0.1]) by araneo.si (OpenSMTPD) with ESMTP id 7ef754fb for ; Wed, 17 Jun 2020 19:51:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=araneo.si; h=from:to:cc :subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=20180623; bh=g4QkkImbU5M8e4Hk8Y3tC BUgn+E=; b=SavV4NwOzLgoc8MgB/WM1LFUceMS5nkScfS7SfAPZxIULR5jZUBHP ITcI2erHITkNzrnHN2LWyrK9sOHrvDA92CeRXCen2uryLnMHSTToqHpOLQQwDkBo 6MwjntYTcHeAu2y3D5k3yVj4uEwA9powwhHd8L+WJZMN9vCk27rKsa6ZbHxrObIT wd+JcKVQtidYy31e74nTuM3PwMDc76bivnn0vFs0rPzKpwZArLidZMr8rrfKqnF8 tFANXSZL86MS+qh3FOTI5zRDrnqv5447DOlRkOS95B4tIMZnzQbBX9YeftkJwmaR UkDb07+kZ6UMqK429RFuACuvB3GVJMSeg== Received: by araneo.si (OpenSMTPD) with ESMTPSA id a82df847 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 17 Jun 2020 19:51:48 +0000 (UTC) From: Timotej Lazar To: ffmpeg-devel@ffmpeg.org Date: Wed, 17 Jun 2020 21:45:39 +0200 Message-Id: <20200617194538.24821-1-timotej.lazar@araneo.si> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avformat/smacker: Support seeking to first frame 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: Timotej Lazar Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Add .read_seek function to the smacker demuxer for the special case of seeking to ts=0. This is useful because smacker ā€“ like bink, with a similar implementation ā€“ was mostly used to encode clips in video games, where random seeks are rare but looping media are common. Signed-off-by: Timotej Lazar --- Unlike the existing bink implementation that always rewinds to start, regardless of arguments to seek(), this will return EINVAL when seeking to any timestamp other than 0. I tried to implement random seeking, but the smacker format is not very amenable to that. While it supports keyframes, most videos I could find do not use them. Since any video frame can contain an incremental palette update, it might be necessary to rewind in any case and decode all frames up to the target timestamp. This is the first time I dived into ffmpeg, so Iā€™d appreciate any feedback or suggestions on how to better approach this. Thanks! libavformat/smacker.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 8b1e185817..19df8edc67 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -230,7 +230,7 @@ static int smacker_read_header(AVFormatContext *s) } smk->curstream = -1; - smk->nextpos = avio_tell(pb); + smk->nextpos = s->internal->data_offset = avio_tell(pb); return 0; } @@ -373,6 +373,27 @@ static int smacker_read_close(AVFormatContext *s) return 0; } +static int smacker_read_seek(AVFormatContext *s, int stream_index, + int64_t timestamp, int flags) +{ + SmackerContext *smk = s->priv_data; + + /* only rewinding to start is supported */ + if (timestamp != 0) { + av_log(s, AV_LOG_ERROR, + "Random seeks are not supported (can only seek to start).\n"); + return AVERROR(EINVAL); + } + + smk->cur_frame = 0; + smk->curstream = -1; + smk->nextpos = s->internal->data_offset; + memset(smk->pal, 0, sizeof(smk->pal)); + memset(smk->aud_pts, 0, sizeof(smk->aud_pts)); + + return 0; +} + AVInputFormat ff_smacker_demuxer = { .name = "smk", .long_name = NULL_IF_CONFIG_SMALL("Smacker"), @@ -381,4 +402,5 @@ AVInputFormat ff_smacker_demuxer = { .read_header = smacker_read_header, .read_packet = smacker_read_packet, .read_close = smacker_read_close, + .read_seek = smacker_read_seek, };