From patchwork Wed Jul 22 09:15:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Steven X-Patchwork-Id: 21221 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 CE6A544A06F for ; Wed, 22 Jul 2020 12:15:46 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A4A7668B73A; Wed, 22 Jul 2020 12:15:46 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from smtpproxy21.qq.com (smtpbg704.qq.com [203.205.195.105]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A869968B605 for ; Wed, 22 Jul 2020 12:15:38 +0300 (EEST) X-QQ-mid: bizesmtp19t1595409332t8bfknu5 Received: from localhost (unknown [103.107.216.230]) by esmtp10.qq.com (ESMTP) with id ; Wed, 22 Jul 2020 17:15:31 +0800 (CST) X-QQ-SSF: 01100000002000Z0ZXF0000A0000000 X-QQ-FEAT: 4LTZo2uvvHvcsJCOwgkYG8T/6jOn/L3yqUea9iHSbmGH8pFJUD0hIplKdFLLs 1W6sKh00mpdd2PySxGVxxurgpgUx7LMuQARBULRd3KaOu5EUaN4pxyso5f1dWZc0Ofqiqe9 STg6rsbyx1rfW5iOP85B8dKJWgUl7baq2lZgf2Bw9rInxtv3K2uuqFlGZOgof5TE9MAK256 Z6skDiHmvqe/78yhCP2gWG+34Wv9KsLWW5W0nf38hLDeBlupQhubOxneIrxxQ/TPF3JBlME 7vZps5xf08i2RgTBwze75lvH0l8yHGPkpi88l1whjKysH/j6BKwHUtnDAoIiRxyZU4QD5yb 2tpa+Z9 X-QQ-GoodBg: 0 From: Steven Liu To: ffmpeg-devel@ffmpeg.org Date: Wed, 22 Jul 2020 17:15:28 +0800 Message-Id: <20200722091529.71809-1-lq@chinaffmpeg.org> X-Mailer: git-send-email 2.25.0 MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:chinaffmpeg.org:qybgforeign:qybgforeign7 X-QQ-Bgrelay: 1 Subject: [FFmpeg-devel] [PATCH v2 1/2] avformat/hls: support avio_seek in encryption mode 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: Steven Liu Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Steven Liu --- libavformat/hls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index ba17c4ed96..5bc775cd8b 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -1291,7 +1291,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, * as would be expected. Wrong offset received from the server will not be * noticed without the call, though. */ - if (ret == 0 && !is_http && seg->key_type == KEY_NONE && seg->url_offset) { + if (ret == 0 && !is_http && seg->url_offset) { int64_t seekret = avio_seek(*in, seg->url_offset, SEEK_SET); if (seekret < 0) { av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url); From patchwork Wed Jul 22 09:15:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Steven X-Patchwork-Id: 21222 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 BA8A444A06F for ; Wed, 22 Jul 2020 12:15:56 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A1B5268B7DA; Wed, 22 Jul 2020 12:15:56 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from smtpproxy21.qq.com (smtpbg702.qq.com [203.205.195.102]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BC79868B7DA for ; Wed, 22 Jul 2020 12:15:49 +0300 (EEST) X-QQ-mid: bizesmtp11t1595409335tfl2r31g Received: from localhost (unknown [103.107.216.230]) by esmtp6.qq.com (ESMTP) with id ; Wed, 22 Jul 2020 17:15:34 +0800 (CST) X-QQ-SSF: 01100000002000Z0ZXF0000A0000000 X-QQ-FEAT: iV2IPzHxhZmyfD6ttKDYUgKy8AE6a5Qx9auDRcYHhLKGHMBGjdcFyyHU2fhW9 IEqodh1P5XSPx/zJrW1VM0PfOlXZhgMMVXtR/MEirjV7dkFEWJiQPrPw1yGj7eBAROd+ByA DiNOtGCzAsAP86IM+uQ/wHRAI7U3bxG7xNTnaTxVDJGERBqm9zat4gE+8es+xa377y+GaW3 rvEm0zI7lYAfzzEHUB1A5yjl0XKgw2E9DPfEX3qxEf1O93iUmvGe0s0GsBvl2dbcg7KtAST MfnmnlLJibe/0LnzXZxOlcq6g1Pg2PSlJGV0yZBZoRV11OstdZ+opglfPjmEcpAEjHq1PRu H0Cl8w0 X-QQ-GoodBg: 0 From: Steven Liu To: ffmpeg-devel@ffmpeg.org Date: Wed, 22 Jul 2020 17:15:29 +0800 Message-Id: <20200722091529.71809-2-lq@chinaffmpeg.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200722091529.71809-1-lq@chinaffmpeg.org> References: <20200722091529.71809-1-lq@chinaffmpeg.org> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:chinaffmpeg.org:qybgforeign:qybgforeign6 X-QQ-Bgrelay: 1 Subject: [FFmpeg-devel] [PATCH v2 2/2] avformat/hlsenc: write temp file for append single file by encryption mode 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: Steven Liu Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" fix ticket: 8783 Because in single file by encryption mode, it cannot get the last one block of the file, it need ff_format_io_close for get full file size, then hlsenc can get the total size of the encryption content, so write the content into temp file first, and get the temp file content append the temp file content into append to single file, then hlsenc can get the correct file/content size and offset. Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 70 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index df84e6487d..f1e4a302d8 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -69,6 +69,7 @@ typedef enum { #define KEYSIZE 16 #define LINE_BUFFER_SIZE MAX_URL_SIZE #define HLS_MICROSECOND_UNIT 1000000 +#define BUFSIZE (16 * 1024) #define POSTFIX_PATTERN "_%d" typedef struct HLSSegment { @@ -119,6 +120,7 @@ typedef struct VariantStream { ff_const59 AVOutputFormat *oformat; ff_const59 AVOutputFormat *vtt_oformat; AVIOContext *out; + AVIOContext *out_single_file; int packets_written; int init_range_length; uint8_t *temp_buffer; @@ -149,6 +151,7 @@ typedef struct VariantStream { HLSSegment *last_segment; HLSSegment *old_segments; + char *basename_tmp; char *basename; char *vtt_basename; char *vtt_m3u8_name; @@ -1722,12 +1725,34 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0); } if (c->flags & HLS_SINGLE_FILE) { + if (c->key_info_file || c->encrypt) { + av_dict_set(&options, "encryption_key", vs->key_string, 0); + av_dict_set(&options, "encryption_iv", vs->iv_string, 0); + + /* Write temp file with cryption content */ + av_freep(&vs->basename_tmp); + vs->basename_tmp = av_asprintf("crypto:%s.tmp", oc->url); + + /* append temp file content into single file */ + av_freep(&vs->basename); + vs->basename = av_asprintf("%s", oc->url); + } else { + vs->basename_tmp = vs->basename; + } set_http_options(s, &options, c); - if ((err = hlsenc_io_open(s, &vs->out, oc->url, &options)) < 0) { + if (!vs->out_single_file) + if ((err = hlsenc_io_open(s, &vs->out_single_file, vs->basename, &options)) < 0) { + if (c->ignore_io_errors) + err = 0; + goto fail; + } + + if ((err = hlsenc_io_open(s, &vs->out, vs->basename_tmp, &options)) < 0) { if (c->ignore_io_errors) err = 0; goto fail; } + } } if (vs->vtt_basename) { @@ -2258,6 +2283,38 @@ static int hls_init_file_resend(AVFormatContext *s, VariantStream *vs) return ret; } +static int64_t append_single_file(AVFormatContext *s, VariantStream *vs) +{ + int ret = 0; + int64_t read_byte = 0; + int64_t total_size = 0; + char *filename = NULL; + char buf[BUFSIZE]; + AVFormatContext *oc = vs->avf; + + hlsenc_io_close(s, &vs->out, vs->basename_tmp); + filename = av_asprintf("%s.tmp", oc->url); + ret = s->io_open(s, &vs->out, filename, AVIO_FLAG_READ, NULL); + if (ret < 0) { + av_free(filename); + return ret; + } + + do { + memset(buf, 0, sizeof(BUFSIZE)); + read_byte = avio_read(vs->out, buf, BUFSIZE); + avio_write(vs->out_single_file, buf, read_byte); + if (read_byte > 0) { + total_size += read_byte; + ret = total_size; + } + } while (read_byte > 0); + + hlsenc_io_close(s, &vs->out, filename); + av_free(filename); + + return ret; +} static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) { HLSContext *hls = s->priv_data; @@ -2383,6 +2440,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } vs->size = range_length; + if (hls->key_info_file || hls->encrypt) + vs->size = append_single_file(s, vs); } else { if (oc->url[0]) { proto = avio_find_protocol_name(oc->url); @@ -2484,6 +2543,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (hls->flags & HLS_SINGLE_FILE) { vs->start_pos += vs->size; + if (hls->key_info_file || hls->encrypt) + ret = hls_start(s, vs); } else if (hls->max_seg_size > 0) { if (vs->size + vs->start_pos >= hls->max_seg_size) { vs->sequence++; @@ -2644,7 +2705,12 @@ static int hls_write_trailer(struct AVFormatContext *s) if (ret < 0) av_log(s, AV_LOG_WARNING, "Failed to upload file '%s' at the end.\n", oc->url); } - + if (hls->flags & HLS_SINGLE_FILE) { + if (hls->key_info_file || hls->encrypt) { + vs->size = append_single_file(s, vs); + } + hlsenc_io_close(s, &vs->out_single_file, vs->basename); + } failed: av_freep(&vs->temp_buffer); av_dict_free(&options);