fraunhoferhhi / vvenc

VVenC, the Fraunhofer Versatile Video Encoder
https://www.hhi.fraunhofer.de/en/departments/vca/technologies-and-solutions/h266-vvc.html
BSD 3-Clause Clear License
898 stars 158 forks source link

Concatenating problems #376

Closed thx4ever closed 1 day ago

thx4ever commented 2 months ago

Hi, im trying to encode in chunks using vvencFFapp and then concatenating with parcat from VTM repository, but it does not work correctly When i concatenate with parcat like example

parcat.exe 00000.h266 00001.h266 00002.h266 00003.h266 00004.h266 00005.h266 00006.h266 00007.h266 00008.h266 00009.h266 00010.h266 00011.h266 00012.h266 00013.h266 00014.h266 00015.h266 00016.h266 teste.266

the video become blurry after each chunk

I dont know if this problem are from parcat or from vvenc

Regards

lehmann-c commented 2 months ago

It seems that reference frames are missing after applying parcat.

Chunkwise encoding is an expert feature and has some conditions. Here are some of the major conditions:

Could you please provide the command line you are using, for the first, last and a middle segment?

adamjw24 commented 1 month ago

Inactive

thx4ever commented 1 week ago

here's my program function, it crashes the vvencFFapp

def compose_1_pass(self, a: Project, c: Chunk, output: str) -> MPCommands:
    segment_flags = []

    if c.frames == a.frames[0]:
        segment_flags.append('--segment first')
    elif c.frames == a.frames[-1]:
        segment_flags.append('--segment last')
    else:
        segment_flags.append('--segment mid')

    return [
        CommandPair(
            Encoder.compose_ffmpeg_pipe(a),
            ['vvc_encoder', '--y4m', '1', '--MTProfile', '1', '--Verbosity', 'info', '-i', '-', *a.video_params,
             '-f', str(c.frames), *segment_flags, '-b', output]
        )
    ]

def compose_2_pass(self, a: Project, c: Chunk, output: str) -> MPCommands:
    segment_flags_pass1 = []
    segment_flags_pass2 = []

    if c.frames == a.frames[0]:
        segment_flags_pass1.append('--segment first')
        segment_flags_pass2.append('--segment first')
    elif c.frames == a.frames[-1]:
        segment_flags_pass1.append('--segment last')
        segment_flags_pass2.append('--segment last')
    else:
        segment_flags_pass1.append('--segment mid')
        segment_flags_pass2.append('--segment mid')

    return [
        CommandPair(
            Encoder.compose_ffmpeg_pipe(a),
            ['vvc_encoder', '--y4m', '1', '--MTProfile', '1', '--Verbosity', 'info', '-i', '-', *a.video_params,
             '--pass', '1', *segment_flags_pass1, '-f', str(c.frames),
             '--RCStatsFile', f'{c.fpf}.log', '-b', os.devnull]
        ),
        CommandPair(
            Encoder.compose_ffmpeg_pipe(a),
            ['vvc_encoder', '--y4m', '1', '--MTProfile', '1', '--Verbosity', 'info', '-i', '-', *a.video_params,
             '--pass', '2', *segment_flags_pass2, '-f', str(c.frames),
             '--RCStatsFile', f'{c.fpf}.log', '-b', output]
        )
    ]
lehmann-c commented 1 week ago

As I wrote in my comment above, chunkwise encoding + parcat is only working for fix QP mode! You are trying to use 2pass encoding. That is not possible.

The only way to concatenate chunks when using Rate control is with ClosedGop (--DecodingRefreshType idr).

  1. encode the chunks with IDR
  2. concatenate the bitstreams (e.g. with 'cat' in linux)
thx4ever commented 1 week ago

Thats great news hope will work with --DecodingRefreshType idr :)

thx4ever commented 1 week ago

I have encoded with --DecodingRefreshType idr with 2pass and it dont give any errors, it plays correctly but cant seek in the video 1pass --TargetBitrate works but 2pass dont

adamjw24 commented 1 week ago

Its not necessary to use --DecodingRefreshType idr

We'll investigate the seeking issue, thanks

lehmann-c commented 1 week ago

I tested concatenated bitstreams that have been created by using 1pass and 2pass mode and after multiplexing it into mp4 they both are properly seekable. Playback of raw bistreams is always a player feature and is not (yet) possible or buggy as there are no timing information in the bitstream itself. So you should always use proper containers.

Feel free to have a look into gpac if you want to create mp4. I used the tool MP4Box: MP4Box --forcesync -add bitream.266 -new stream.mp4

The '--forcesync' option will give a hint for non-IDR frames that are I-Slices to be a sync point. But even without this option the streams are seekable.

How do you playback your concatenated streams? What player and decoder are you using? Have you multiplexed the bitstreams into a proper container as mp4 or ts?

thx4ever commented 1 week ago

I have encoded using segments, in normal mode it works but in segment i cant concatenate final video dont seek properly

lehmann-c commented 1 week ago

In your last comment you wrote:

I have encoded with --DecodingRefreshType idr with 2pass and it dont give any errors, it plays correctly but cant seek in the video 1pass --TargetBitrate works but 2pass dont

What did you do in particular? Did you just encode the whole video without chunks/segments? And there you could only seek when using 1pass and not for 2pass?

What do you mean with "normal mode"? What do you mean with "can´t concatenate final video?"

Would you please be more specific what you are doing and what is not working as expected?

Have you multiplexed the encoded(concatenated) video into a container? Otherwise seeking will not work properly. What player are you using?

thx4ever commented 1 week ago

In your last comment you wrote:

I have encoded with --DecodingRefreshType idr with 2pass and it dont give any errors, it plays correctly but cant seek in the video 1pass --TargetBitrate works but 2pass dont

What did you do in particular? Did you just encode the whole video without chunks/segments? And there you could only seek when using 1pass and not for 2pass?

What do you mean with "normal mode"? What do you mean with "can´t concatenate final video?"

Would you please be more specific what you are doing and what is not working as expected?

Have you multiplexed the encoded(concatenated) video into a container? Otherwise seeking will not work properly. What player are you using?

jungleboynx commented 5 days ago

I've got a related question. I've got 3 x h266/mp4 files about an hour each and concatenated them together using the usual method. mp4box -add file1.mp4 -cat file2.mp4 -cat file3.mp4 muxed-file.mp4

The files are encoded using the standard open GOP method. --qp 30 --preset fast -c yuv420 -rs 4 -t 12 --sdr sdr_709 The concatenated file plays back ok at the joins - there's no visible problem. Is this ok or is closed GOP needed for concatenated files ?

adamjw24 commented 5 days ago

I've got a related question. I've got 3 x h266/mp4 files about an hour each and concatenated them together using the usual method. mp4box -add file1.mp4 -cat file2.mp4 -cat file3.mp4 muxed-file.mp4

The files are encoded using the standard open GOP method. --qp 30 --preset fast -c yuv420 -rs 4 -t 12 --sdr sdr_709 The concatenated file plays back ok at the joins - there's no visible problem. Is this ok or is closed GOP needed for concatenated files ?

If you just used 3 separate files, you are using closed GOP at those switches. Basically, your file is now mixed closed/open GOP, which is totally fine.

jungleboynx commented 5 days ago

Thanks. Yes it works fine. I've used a similar technique in the past to speed up HEVC encoding by modifying the AVS script to encode different parts of the file on different computers and then glue the bits together.

lehmann-c commented 5 days ago
  • First I split the video into chunks based on scene change
  • Encode every chunk with same options, 2pass every chunk with same options
  • Multiplex the encoded chunks with mp4box using -cat command
  • Play the video with media player classic, it supports VVC for playing
  • When I use --TargetBitrate with 2 passes the output video has problems with seeking, it works when i use one pass with --TargetBitrate or --QP, the only problems its with encoding 2pass in chunks I have attached a video encoded with 2 passes with chunking mode Trailer.zip

Thanks, I could reproduce it now. We will take a closer look at it.

K-os commented 3 days ago

I analyzed the problem a little: the problem lies in MP4Box, which drops the PPS from the second fragment when concatenating the bitstreams, so we need to tell it to keep the parameter sets inband.

The workaround is to either produce the individual files with the PPS inband like this:

MP4Box --forcesync --xps_inband=all -add out1.266 -new out1.mp4
MP4Box --forcesync --xps_inband=all -add out2.266 -new out2.mp4
# and concatenate them
MP4Box -new cat.mp4 -add out1.mp4 -cat out2.mp4

Or, directly giving MP4Box the raw bitstreams for the concatenation and specifying --xps_inband here:

MP4Box --forcesync --xps_inband=all -new cat.mp4 -add out1.266 -cat out2.266

For some reason xps_inband does not work, when concatenating the already muxed files.

thx4ever commented 1 day ago

Issue resolved thanks :) I tested with 2pass ratecontrol and multiplexed with mp4box with your commands and it works, dont have tested in 1pass mode ratecontrol but probably works too, thanks