video sem perdas usando o FFmpeg ffv1 em imagens jpeg não é comprimido mas expandido

1

É possível que o FFmpeg / ffv1.3 / mkv crie um vídeo sem perda não é maior que a soma de suas partes (e se sim, como) e se não, qual é uma boa alternativa para se aproximar do tamanho? O vídeo deve ser sem perdas.

Eu estou tentando usar o FFmpeg para criar um mkv com ffv1.3 em um conjunto de imagens jpeg similares (imagens de uma web cam). Eu sou capaz de criar o vídeo no entanto, pelo menos 2 vezes o tamanho da coleção de imagens jpeg. Eu teria esperado o mesmo nível de compressão ou melhor.

Eu entendo que o jpeg por si só é otimizado para compactação. No entanto, um grande conjunto de imagens muito semelhantes deve poder ser ainda mais comprimido ou, neste caso, semelhante às imagens originais adicionadas.

Os comandos que estou usando para criar o arquivo são:

ffmpeg -pattern_type glob -i '*.jpg' -vcodec ffv1 -level 3 -an -pass 1 -passlogfile passlog -f matroska /dev/null

ffmpeg -pattern_type glob -i '*.jpg' -vcodec ffv1 -level 3 -an -pass 2 -passlogfile passlog -f matroska ~/foo.mkv

Os arquivos de entrada são 24M no total, mas o mkv resultante é 96M (por du -h).

Os resultados da segunda passagem:

ffmpeg version N-79053-g7eedad9 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.6 (Debian 4.6.3-14+rpi1)
  configuration: --enable-cross-compile --cross-prefix= --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff
  libavutil      55. 19.100 / 55. 19.100
  libavcodec     57. 28.103 / 57. 28.103
  libavformat    57. 28.101 / 57. 28.101
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 39.102 /  6. 39.102
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
Input #0, image2, from '*.jpg':
  Duration: 00:00:21.32, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc
File '/home/pi/foo.mkv' already exists. Overwrite ? [y/N] y
[swscaler @ 0x3671f30] deprecated pixel format used, make sure you did set range correctly
Output #0, matroska, to '/home/pi/foo.mkv':
  Metadata:
    encoder         : Lavf57.28.101
    Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), yuv422p, 640x480, q=2-31, pass 2, 200 kb/s, 25 fps, 1k tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.28.103 ffv1
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> ffv1 (native))
Press [q] to stop, [?] for help
frame=  533 fps=4.2 q=-0.0 Lsize=   97815kB time=00:00:21.32 bitrate=37584.4kbits/s speed=0.168x
video:97808kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.006607%

Cada jpeg é aproximadamente 43143 bytes (por ls -al), mas executando o seguinte comando, a ferramenta informa que cada imagem é de 614400 bytes (tanto no vídeo quanto nas imagens jpeg independentes). Eu diria que este é o tamanho descomprimido da imagem (640x480x2).

ffmpeg -pattern_type glob -i '*.jpg' -f framemd5 -

os resultados abaixo são para as imagens, os mesmos tamanhos são reportados para o mkv.

ffmpeg version N-79053-g7eedad9 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.6 (Debian 4.6.3-14+rpi1)
  configuration: --enable-cross-compile --cross-prefix= --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff
  libavutil      55. 19.100 / 55. 19.100
  libavcodec     57. 28.103 / 57. 28.103
  libavformat    57. 28.101 / 57. 28.101
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 39.102 /  6. 39.102
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
Input #0, image2, from '*.jpg':
  Duration: 00:00:21.32, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc
#format: frame checksums
#version: 1
#hash: MD5
#software: Lavf57.28.101
#tb 0: 1/25
#stream#, dts,        pts, duration,     size, hash
Output #0, framemd5, to 'pipe:':
  Metadata:
    encoder         : Lavf57.28.101
    Stream #0:0: Video: rawvideo (Y42B / 0x42323459), yuvj422p, 640x480, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.28.103 rawvideo
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> rawvideo (native))
Press [q] to stop, [?] for help
0,          0,          0,        1,   614400, 2148ff8b95296f4bacc1099d13235063
0,          1,          1,        1,   614400, da330e2acd2f7d7a1e79fe79fccc90cf
0,          2,          2,        1,   614400, f55563c13a9f232ce32419fa26e37214
0,          3,          3,        1,   614400, c53d994fff0a9b26529fa8763deae520

EDITAR: A melhor compactação (e boa velocidade) veio de um contêiner das próprias imagens jpeg:

ffmpeg -pattern_type glob -i '*.jpg' -vcodec copy -an -f matroska ~/foo.mkv

O arquivo resultante foi pouco mais de 24M (vs. o 96M ffv1). Além disso, as imagens jpeg descompactadas foram de 312M, em ambos os casos elas se comprimiram razoavelmente bem. Se eu tivesse começado com algo diferente de um jpeg, o ffv1 teria sido ideal, mas no meu caso o jpeg com perdas, onde também as imagens iniciais sem perdas.

    
por user1373984 18.03.2016 / 01:29

1 resposta

0

Eu geralmente descobri que a codificação de vídeo com perdas com um codec sem perdas resulta em um tamanho de arquivo maior. O FFmpeg tem que descompactar sua entrada antes que ela possa codificar para o ffv1, então ele está trabalhando a partir da versão descompactada dos seus jpegs. O processo é descrito aqui: link

    
por 18.03.2016 / 01:49