On Mon, Aug 29, 2016 at 09:56:59PM +0100, Simon H wrote: > thanks Michael, > > try the attached file. I assume the corruption came from email word > wrapping?
likely > or was there something else wrong? [...] > example: > take 25.mp4 created with: > ffmpeg -f lavfi -i sine=frequency=1000:beep_factor=2:r=48000:duration=720.0 > -f lavfi -i testsrc=duration=720.0:rate=25 -vcodec libx264 -cmp 22 -timecode > 10:00:00:00 -r 25 -y out\25.mp4 > > encrypt with: > openssl enc -aes-128-cbc -K 12345678901234567890123456789012 -iv > 12345678901234567890123456789012 -in 25.mp4 -out 25.enc > then to transcode in ffmpeg: > ffmpeg -key 12345678901234567890123456789012 -iv > 12345678901234567890123456789012 -i crypto:25.enc -vcodec mpeg4 -r 25 -y > 25dec.mp4 > > prior to this modification, the transcode would fail. > > Note also: crypto previously marked both reads and writes as streamed, which > caused the whole file > to be read before the transcode started. Now, for read only, if the > underlying layer is not marked as streamed, > then crypto is not. This should enable efficient reading of encrypted > containers which require seeking. > --- > libavformat/crypto.c | 115 > +++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 112 insertions(+), 3 deletions(-) > > diff --git a/libavformat/crypto.c b/libavformat/crypto.c > index 2999f50..23bc0a6 100644 > --- a/libavformat/crypto.c > +++ b/libavformat/crypto.c > @@ -26,7 +26,8 @@ > #include "internal.h" > #include "url.h" > > -#define MAX_BUFFER_BLOCKS 150 > +// encourage reads of 4096 bytes - 1 block is always retained. > +#define MAX_BUFFER_BLOCKS 257 > #define BLOCKSIZE 16 > > typedef struct CryptoContext { this should be in a separate patch > @@ -36,6 +37,8 @@ typedef struct CryptoContext { > outbuffer[BLOCKSIZE*MAX_BUFFER_BLOCKS]; > uint8_t *outptr; > int indata, indata_used, outdata; > + int64_t position; // position in file - used in seek > + int flags; > int eof; > uint8_t *key; > int keylen; > @@ -109,6 +112,7 @@ static int crypto_open2(URLContext *h, const char *uri, > int flags, AVDictionary > const char *nested_url; > int ret = 0; > CryptoContext *c = h->priv_data; > + c->flags = flags; > > if (!av_strstart(uri, "crypto+", &nested_url) && > !av_strstart(uri, "crypto:", &nested_url)) { > @@ -117,6 +121,8 @@ static int crypto_open2(URLContext *h, const char *uri, > int flags, AVDictionary > goto err; > } > > + c->position = 0L; > + > if (flags & AVIO_FLAG_READ) { > if ((ret = set_aes_arg(c, &c->decrypt_key, &c->decrypt_keylen, > c->key, c->keylen, "decryption key")) < 0) > @@ -152,6 +158,10 @@ static int crypto_open2(URLContext *h, const char *uri, > int flags, AVDictionary > ret = av_aes_init(c->aes_decrypt, c->decrypt_key, BLOCKSIZE*8, 1); > if (ret < 0) > goto err; > + > + // pass back information about the context we openned > + if (c->hd->is_streamed) > + h->is_streamed = c->hd->is_streamed; > } > > if (flags & AVIO_FLAG_WRITE) { > @@ -163,12 +173,13 @@ static int crypto_open2(URLContext *h, const char *uri, > int flags, AVDictionary > ret = av_aes_init(c->aes_encrypt, c->encrypt_key, BLOCKSIZE*8, 0); > if (ret < 0) > goto err; > + // for write, we must be streamed > + // - linear write only for crytpo aes-128-cbc > + h->is_streamed = 1; > } > > c->pad_len = 0; > > - h->is_streamed = 1; > - > err: > return ret; > } > @@ -183,6 +194,7 @@ retry: > memcpy(buf, c->outptr, size); > c->outptr += size; > c->outdata -= size; > + c->position = c->position + size; > return size; > } > // We avoid using the last block until we've found EOF, > @@ -222,6 +234,102 @@ retry: > goto retry; > } > > +static int64_t crypto_seek(URLContext *h, int64_t pos, int whence) > +{ > + CryptoContext *c = h->priv_data; > + int64_t block; > + int64_t newpos; > + > + if (c->flags & AVIO_FLAG_WRITE) { > + av_log(h, AV_LOG_ERROR, > + "Crypto: seek not supported for write\r\n"); > + return -1L; should be a AVERROR* code > + } > + > + // reset eof, else we won't read it correctly if we already hit eof. > + c->eof = 0; > + > + switch (whence) { > + case SEEK_SET: > + break; > + case SEEK_CUR: > + pos = pos + c->position; > + break; > + case SEEK_END: { > + int64_t newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE ); > + if (newpos < 0) { > + av_log(h, AV_LOG_ERROR, > + "Crypto: seek_end - can't get file size (pos=%lld)\r\n", > pos); libavformat/crypto.c: In function ‘crypto_seek’: libavformat/crypto.c:262:17: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 4 has type ‘int64_t’ [-Wformat] > + return newpos; > + } > + pos = newpos - pos; > + } > + break; > + case AVSEEK_SIZE: > + return ffurl_seek( c->hd, pos, AVSEEK_SIZE ); please use the same formating as the surrounding code > + default: > + av_log(h, AV_LOG_ERROR, > + "Crypto: no support for seek where 'whence' is %d\r\n", whence); > + return -1L; > + } > + > + c->outdata = 0; > + c->indata = 0; > + c->indata_used = 0; > + c->outptr = c->outbuffer; > + > + // identify the block containing the IV for the > + // next block we will decrypt > + block = pos/16L; many of the L suffixes are unneeded thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Let us carefully observe those good qualities wherein our enemies excel us and endeavor to excel them, by avoiding what is faulty, and imitating what is excellent in them. -- Plutarch
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel