From patchwork Mon Jun 19 23:42:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hein-Pieter van Braam X-Patchwork-Id: 4055 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.22.4 with SMTP id 4csp1139861vsw; Mon, 19 Jun 2017 16:43:14 -0700 (PDT) X-Received: by 10.223.170.7 with SMTP id p7mr19492082wrd.72.1497915794099; Mon, 19 Jun 2017 16:43:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497915794; cv=none; d=google.com; s=arc-20160816; b=jj6SaP65aKXKyYdawkY6oJt8oOg9EVnO51VE0uiGJP+c94NKCnCQwE1sO0LpCUoQgs hEXzTf1hJxULZW20zydivE6v3F3E5xHl+EH4546w3HWzyogt9Z+wbX56wFEl2m9Fj4NA Ozpoi395XHKNdhKFYvyLXCkS8ze+FZACDusYoDzR5E5R11OPrfuUGgF3/QJoFVlBRae1 Ofcy1yiurJh3nXXVekC8VKW+X9wtOZmDCW9dMQnVCJrg9BPoFFcob4IAS0lg1jHRCZJ0 2/aFkS5ZMTdy8meDelDiK0ZEq5GsKfGcxO26Ko7AAhvlZl41GsCfn0ZF54JcnOuZ1t0D eXnQ== 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:cc: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:dkim-filter:delivered-to :arc-authentication-results; bh=JtBWRYlr/q60wMcW8887UxdJjyTwWHiza00HEcMafRI=; b=S1vuHuwVTMqvGZwI3WmKlvX3RkV9RFdV6uRnx7v87JhPBSHdqvdw8M4xxFiAVqiML3 wUdZR7gM8iQGrX4fEYXiPib8sB5fAyUAs8UVJZV27BPtCg7GeAjbTDHoch6gHQVziefM mRJJejZm3fNnHGRENAdMLNdf2GU4TBfRhhwKKghZiJrrYTGnYNZydDWI/O4u5v0WuCXY uAd+btG0pAmZIBB9JmJahqq3xYRzCH8X7wdytayjrcUoWtesL72BYMnZbXNDB70TXTeY rzsI+yvTdDeWRCAw+TwYoVkIwh2sffsaydg+PMfdHjan/MxGd5BiDxhlthh0IdEsJmUe GJGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@tmm.cx header.b=AbRZyfMc; 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=REJECT dis=NONE) header.from=tmm.cx Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id b64si7776750wmd.13.2017.06.19.16.43.13; Mon, 19 Jun 2017 16:43:14 -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=@tmm.cx header.b=AbRZyfMc; 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=REJECT dis=NONE) header.from=tmm.cx Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 63B8868A643; Tue, 20 Jun 2017 02:42:49 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from eva.tmm.cx (eva.tmm.cx [5.9.73.21]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2B98768A5D1 for ; Tue, 20 Jun 2017 02:42:41 +0300 (EEST) Received: from lola.ttg.global (unknown [92.110.172.3]) by eva.tmm.cx (Postfix) with ESMTPSA id 717D817DD511; Mon, 19 Jun 2017 23:42:45 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 eva.tmm.cx 717D817DD511 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tmm.cx; s=mail; t=1497915766; bh=hnJjbX8XP9jPxHb1vk5C4y5Fbg44LLd2rFl5P7cDGmQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AbRZyfMcgZEBQAw5NYzxne5+G7AlV2kXnXe4iL3Sr/g9OJCOPBiz2eEy6IWnc/gyh Z2zM+umvyxpCTyhe7F2ozbsiGiBThW5isHKy6yMe/FAnR9eYKavIZs8hWX+usQnhhr 3NY8RMB80maCFQyyf41C4lgh4cfl82T2iCFGy+xI= From: Hein-Pieter van Braam To: FFmpeg development discussions and patches Date: Tue, 20 Jun 2017 01:42:35 +0200 Message-Id: <20170619234238.1364-3-hp@tmm.cx> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170619234238.1364-1-hp@tmm.cx> References: <20170619234238.1364-1-hp@tmm.cx> X-Spam-Status: No, score=0.0 required=2.4 tests=UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on eva.tmm.cx Subject: [FFmpeg-devel] [PATCH v2 2/5] Interplay MVE: Refactor IP packet format 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: Hein-Pieter van Braam MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Interplay MVE can contain up to three different frame formats. They require different streams of information to render a frame. This patch changes the IP packet format to prepare for the extra frame formats. Signed-off-by: Hein-Pieter van Braam --- libavcodec/interplayvideo.c | 33 +++++++++++++++++++++----------- libavformat/ipmovie.c | 46 ++++++++++++++++++++++++++++----------------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index 9fed8f6..5dfb0d6 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -991,29 +991,40 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame = data; int ret; int send_buffer; + int frame_format; + int video_data_size; if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) { av_frame_unref(s->last_frame); av_frame_unref(s->second_last_frame); } - if (buf_size < 2) + if (buf_size < 6) return AVERROR_INVALIDDATA; - send_buffer = AV_RL8(avpkt->data); + frame_format = AV_RL8(buf); + send_buffer = AV_RL8(buf + 1); + video_data_size = AV_RL16(buf + 2); + s->decoding_map_size = AV_RL16(buf + 4); - /* decoding map contains 4 bits of information per 8x8 block */ - s->decoding_map_size = AV_RL16(avpkt->data + 1); + if (frame_format != 0x11) + av_log(avctx, AV_LOG_ERROR, "Frame type 0x%02X unsupported\n", frame_format); - /* compressed buffer needs to be large enough to at least hold an entire - * decoding map */ - if (buf_size < s->decoding_map_size + 2) - return buf_size; + if (! s->decoding_map_size) { + av_log(avctx, AV_LOG_ERROR, "Empty decoding map\n"); + return AVERROR_INVALIDDATA; + } + bytestream2_init(&s->stream_ptr, buf + 6, video_data_size); - s->decoding_map = buf + 3; - bytestream2_init(&s->stream_ptr, buf + 3 + s->decoding_map_size, - buf_size - s->decoding_map_size - 3); + /* decoding map contains 4 bits of information per 8x8 block */ + s->decoding_map = buf + 6 + video_data_size; + + /* ensure we can't overread the packet */ + if (buf_size < 6 + s->decoding_map_size + video_data_size) { + av_log(avctx, AV_LOG_ERROR, "Invalid IP packet size\n"); + return AVERROR_INVALIDDATA; + } if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index 0705d33..a9ffca4 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -69,7 +69,7 @@ #define OPCODE_UNKNOWN_0E 0x0E #define OPCODE_SET_DECODING_MAP 0x0F #define OPCODE_UNKNOWN_10 0x10 -#define OPCODE_VIDEO_DATA 0x11 +#define OPCODE_VIDEO_DATA_11 0x11 #define OPCODE_UNKNOWN_12 0x12 #define OPCODE_UNKNOWN_13 0x13 #define OPCODE_UNKNOWN_14 0x14 @@ -92,6 +92,7 @@ typedef struct IPMVEContext { int has_palette; int changed; uint8_t send_buffer; + uint8_t frame_format; unsigned int audio_bits; unsigned int audio_channels; @@ -153,11 +154,11 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, chunk_type = CHUNK_VIDEO; - } else if (s->decode_map_chunk_offset) { + } else if (s->frame_format) { - /* send the decode map, the video data, and the send_buffer flag together */ + /* send the frame format, decode map, the video data, and the send_buffer flag together */ - if (av_new_packet(pkt, 3 + s->decode_map_chunk_size + s->video_chunk_size)) + if (av_new_packet(pkt, 6 + s->decode_map_chunk_size + s->video_chunk_size)) return CHUNK_NOMEM; if (s->has_palette) { @@ -175,29 +176,38 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, ff_add_param_change(pkt, 0, 0, 0, s->video_width, s->video_height); s->changed = 0; } - pkt->pos= s->decode_map_chunk_offset; - avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); - s->decode_map_chunk_offset = 0; - AV_WL8(pkt->data, s->send_buffer); + AV_WL8(pkt->data, s->frame_format); + AV_WL8(pkt->data + 1, s->send_buffer); + AV_WL16(pkt->data + 2, s->video_chunk_size); + AV_WL16(pkt->data + 4, s->decode_map_chunk_size); + + s->frame_format = 0; s->send_buffer = 0; - AV_WL16(pkt->data + 1, s->decode_map_chunk_size); - if (avio_read(pb, pkt->data + 3, s->decode_map_chunk_size) != - s->decode_map_chunk_size) { + pkt->pos = s->video_chunk_offset; + avio_seek(pb, s->video_chunk_offset, SEEK_SET); + s->video_chunk_offset = 0; + + if (avio_read(pb, pkt->data + 6, s->video_chunk_size) != + s->video_chunk_size) { av_packet_unref(pkt); return CHUNK_EOF; } - avio_seek(pb, s->video_chunk_offset, SEEK_SET); - s->video_chunk_offset = 0; + pkt->pos = s->decode_map_chunk_offset; + avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); + s->decode_map_chunk_offset = 0; - if (avio_read(pb, pkt->data + 3 + s->decode_map_chunk_size, - s->video_chunk_size) != s->video_chunk_size) { + if (avio_read(pb, pkt->data + 6 + s->video_chunk_size, + s->decode_map_chunk_size) != s->decode_map_chunk_size) { av_packet_unref(pkt); return CHUNK_EOF; } + s->video_chunk_size = 0; + s->decode_map_chunk_size = 0; + pkt->stream_index = s->video_stream_index; pkt->pts = s->video_pts; @@ -527,8 +537,9 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, avio_skip(pb, opcode_size); break; - case OPCODE_VIDEO_DATA: + case OPCODE_VIDEO_DATA_11: av_log(s->avf, AV_LOG_TRACE, "set video data\n"); + s->frame_format = 0x11; /* log position and move on for now */ s->video_chunk_offset = avio_tell(pb); @@ -595,7 +606,8 @@ static int ipmovie_read_header(AVFormatContext *s) ipmovie->video_pts = ipmovie->audio_frame_count = 0; ipmovie->audio_chunk_offset = ipmovie->video_chunk_offset = ipmovie->decode_map_chunk_offset = 0; - ipmovie->send_buffer = 0; + ipmovie->decode_map_chunk_size = ipmovie->video_chunk_size = 0; + ipmovie->send_buffer = ipmovie->frame_format = 0; /* on the first read, this will position the stream at the first chunk */ ipmovie->next_chunk_offset = avio_tell(pb) + 4;