Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assumes correct SPS/PPS #2

Closed
Syd76 opened this issue Dec 1, 2018 · 33 comments
Closed

Assumes correct SPS/PPS #2

Syd76 opened this issue Dec 1, 2018 · 33 comments

Comments

@Syd76
Copy link

Syd76 commented Dec 1, 2018

for work on Nvidia embedded Jetson solution ,
i switch off MINIMP4_TRANSCODE_SPS_ID and fix compilation.

  • offset is good on uint64.
  • 40Go / 2hours for a MP4 file but unreadable.

So, i cant make a readable files with more than 4Go ... Beyond that , in MediaInfo , isTruncated status become TRUE and the file is unreadable into VLC/Mplayer.

I forgot something in code ?

@lieff
Copy link
Owner

lieff commented Dec 1, 2018

Thanks for the issue :)
Can you try -D_FILE_OFFSET_BITS=64 (and check that fseek supports 64bit offsets).
If 64bit offsets is supported but still does not work, try sequential_mode = 1 to check if only one mode is broken.

@Syd76
Copy link
Author

Syd76 commented Dec 1, 2018

the callback use int fseeko(FILE *stream, off_t offset, int whence)
i check fseeko on 64bit and trace write_pos value , i can make 40Go file ... but i cant read that..
i go try sequential_mode=1 next day.

@lieff
Copy link
Owner

lieff commented Dec 1, 2018

For fseeko -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE is correct switches I think. Sample app may produce 40Gb file without 64bit seek support, depending if it fails on offsets >32bit or wraps.

@Syd76
Copy link
Author

Syd76 commented Dec 1, 2018

sequential_mode = 1 works on i7 / ubuntu 64bits
i see a memory arrangement with sequential_mode = 1 , but i'm not an expert on MP4/h264 muxing. what's difference between sequential_mode = 1 and sequential_mode = 0 ?
Can i use sequential_mode = 1 for an encoder which use correct SPS/PPS ID's ?

@lieff
Copy link
Owner

lieff commented Dec 1, 2018

Thanks for testing :) sequential_mode = 1 is what you need then. This two modes have following differences:
sequential_mode = 1 guarantees that write/seek always goes forward and never goes back, i.e. streaming move. It also creates BOX_mdat atom per sample and less efficient.

sequential_mode = 0 writes all data to one big BOX_mdat and needs going back to update it's size (stored near beginning of file) when write to mp4 is finished. Here we have overflow, because minimp4 do not support writing BOX_mdat > 4Gb:

    if (!mux->sequential_mode_flag)
    {
        // update size of mdat box.
        // The only point, which requires random file access.
        // This can be avoided using "till eof" size code, but in this case indexes must be
        // written before the mdat....
        WRITE_4(mux->write_pos - sizeof(box_ftyp));
        WRITE_4(BOX_mdat);
        mux->write_callback(sizeof(box_ftyp), base, p-base, mux->token);
        p = base;
    }

I think I'm insert assert here...

@lieff
Copy link
Owner

lieff commented Dec 1, 2018

Also this two modes have noting to do with SPS/PPS, but mp4 stores SPS/PPS per track and do not support changing it in the middle of stream on fly. That's MINIMP4_TRANSCODE_SPS_ID is for: some hardware encoders changes SPS/PPS ids on fly despite fact that different id point to same copy of SPS/PPS (otherwise stream can't be correctly stored in mp4 at all). When enabled, it transcodes SPS/PPS ids so it always point to copy included in track metadata.

@Syd76
Copy link
Author

Syd76 commented Dec 1, 2018

Thank for your explains !!!
I go to enable sequential_mode and check Nvidia Encoder for SPS/PPS asap ;)

@lieff
Copy link
Owner

lieff commented Dec 3, 2018

Theoretically, we can create BOX_mdat > 4G for sequential_mode = 0, but problem is, that we must reserve space for it and I'm not sure that use 64bit size encoding for 32bit is right thing to do, some demuxers may support only 32bit.

@Syd76
Copy link
Author

Syd76 commented Dec 3, 2018

I can capture in h264 file and build a MP4 file with MINIMP4 . that's work for read :
sequential_mode = 0 , MINIMP4_TRANSCODE_SPS_ID = 0 and MINIMP4_ALLOW_64BIT = 1

I replace code in case MINIMP4_TRANSCODE_SPS_ID == 0 with :
`
payload_type = nal[0] & 31;

        switch (payload_type) {
            case 7:
                
                MP4E__set_sps(h->mux, h->mux_track_id, nal, sizeof_nal);
                h->need_pps = 1;
                h->need_idr = 1;
                break;
            case 8:
                if (h->mux_track_id == -1)
                    return 0;
                MP4E__set_pps(h->mux, h->mux_track_id, nal, sizeof_nal);

                h->need_pps = 0;
                break;
            case 5:
                if (h->mux_track_id == -1)
                    return 0;
                h->need_idr = 0;

                // flow through
            default:
                if (h->mux_track_id == -1)
                    return 0;
                
                
                 if (!h->need_pps && !h->need_idr)
                 {
                    unsigned char *tmp = (unsigned char *)malloc(4 + sizeof_nal);
                    if (tmp)
                    {
                        tmp[0] = (unsigned char)(sizeof_nal >> 24);
                        tmp[1] = (unsigned char)(sizeof_nal >> 16);
                        tmp[2] = (unsigned char)(sizeof_nal >>  8);
                        tmp[3] = (unsigned char)(sizeof_nal);
                        
                        
                        memcpy(tmp + 4, nal, sizeof_nal);
                        MP4E__put_sample(h->mux, h->mux_track_id, tmp,  4+sizeof_nal, timeStamp90kHz_next , payload_type == 5 ); // 
                        free(tmp);
                    }
                }
                break;
        }

`
That's use one track id.

But, if i muxing with minimp4 a h264 buffer from capture into MP4 file there are an error message in vlc or avidemux: "sps_id 32 out of range" and "extradataSize:33" , and i cant read than more 4Go.

[[decoderFFH264] 13:11:11-539 [lavc] Initializing H264 decoder with 33 extradata
[adm_lavLogCallback] 13:11:11-539 [lavc] The 'vismv' option is deprecated, see the codecview filter instead.
[adm_lavLogCallback] 13:11:11-539 [lavc] sps_id 32 out of range
[adm_lavLogCallback] 13:11:11-539 [lavc] SPS decoding failure, trying again after escaping the NAL
[adm_lavLogCallback] 13:11:11-539 [lavc] sps_id 32 out of range
[adm_lavLogCallback] 13:11:11-539 [lavc] Decoding sps 1 from avcC failed

@lieff
Copy link
Owner

lieff commented Dec 3, 2018

That's expected, sps_id=32 encoded in slice headers. But in track metadata contains only one SPS/PPS arrived first (and probably sps_id=0). That's exactly problem described above and looks like MINIMP4_TRANSCODE_SPS_ID=1 is needed for this encoder. Does it works with MINIMP4_TRANSCODE_SPS_ID=1 sequential_mode = 1 without any modifications?

@lieff
Copy link
Owner

lieff commented Dec 3, 2018

After 8d91f27 sequential_mode=0 should work with >4Gb too.

@Syd76
Copy link
Author

Syd76 commented Dec 3, 2018

When i used MINIMP4_TRANSCODE_SPS_ID = 1 , there are a buffer error :

#0 0x0000007fb7b19528 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 #1 0x0000007fb7b1a9e0 in __GI_abort () at abort.c:89 #2 0x0000007fb7b12c04 in __assert_fail_base (fmt=0x7fb7bff290 "%s%s%s:%u: %s%sAssertion%s' failed.\n%n", assertion=assertion@entry=0x7fb7f95ba8 "n > 0 && n <= 16",
file=file@entry=0x7fb7f958c8 "./src/minimp4.cpp", line=line@entry=1262,
function=function@entry=0x7fb7f962c0 <show_bits(bit_reader_t*, int)::PRETTY_FUNCTION> "unsigned int show_bits(bit_reader_t*, int)") at assert.c:92
#3 0x0000007fb7b12cac in __GI___assert_fail (assertion=0x7fb7f95ba8 "n > 0 && n <= 16", file=0x7fb7f958c8 "./src/minimp4.cpp", line=1262,
function=0x7fb7f962c0 <show_bits(bit_reader_t*, int)::PRETTY_FUNCTION> "unsigned int show_bits(bit_reader_t*, int)") at assert.c:101
#4 0x0000007fb7f6bd04 in show_bits (bs=0x7f6d530408, n=33) at ./src/minimp4.cpp:1262
#5 0x0000007fb7f6be58 in get_bits (bs=0x7f6d530408, n=33) at ./src/minimp4.cpp:1282
#6 0x0000007fb7f6c084 in ue_bits (bs=0x7f6d530408) at ./src/minimp4.cpp:1332
#7 0x0000007fb7f6c93c in change_sps_id (bs=0x7f6d530408, bd=0x7f6d5303d8, new_id=0, old_id=0x7f6d5303c0) at ./src/minimp4.cpp:1544
#8 0x0000007fb7f6cc60 in transcode_nalu (h=0x469200, src=0x7f580021f0 "gd\f)", nalu_bytes=4, dst=0x7f58000940 "g!") at ./src/minimp4.cpp:1617
#9 0x0000007fb7f6d304 in mp4_h264_write_nal (h=0x469200, nal=0x7f6400c014 "gd\f)\254,\250\003\300\004>@", length=8, timeStamp90kHz_next=9000)
at ./src/minimp4.cpp:1783
`

@Syd76
Copy link
Author

Syd76 commented Dec 3, 2018

nice job , that's works with options :

  • EDIT => ### MINIMP4_TRANSCODE_SPS_ID=0
  • EDIT => ### sequential_mode = 0 or 1
  • Modification for sps encoder.

I can read the video file (4.2Go) with VLC.

Only a VLC warning in start:

[h264 @ 0x7f6c7cc57d80] illegal POC type 10
[h264 @ 0x7f6c7cc57d80] sps_id 32 out of range
[h264 @ 0x7f6c7cc57d80] illegal POC type 10

problems in "Picture Order Count" for first frame, may be something to unsuitable on my modification.

But i cant open file with avidemux

Assert failed :0
at line 589, file /home/syd/usr/share/avidemux_2.7.0/avidemux_core/ADM_coreVideoCodec/src/ADM_ffmp43.cpp
ADM_backTrack
ADM_coreCodecGetDecoder(unsigned int, unsigned int, unsigned int, unsigned int, unsigned char*, unsigned int)
ADM_EditorSegment::addReferenceVideo(_VIDEOS*)
ADM_Composer::addFile(char const*)
A_openVideo(char const*)
avidemux3_qt5() [0x48e342]
automation()
QMetaObject::activate(QObject*, int, int, void**)
QTimer::timerEvent(QTimerEvent*)
QObject::event(QEvent*)
QApplicationPrivate::notify_helper(QObject*, QEvent*)
QApplication::notify(QObject*, QEvent*)
QCoreApplication::notifyInternal(QObject*, QEvent*)
QTimerInfoList::activateTimers()
g_main_context_dispatch
g_main_context_iteration
QEventDispatcherGlib::processEvents(QFlagsQEventLoop::ProcessEventsFlag)
QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag)
QCoreApplication::exec()
UI_RunApp()
startAvidemux(int, char**)
main
__libc_start_main
_start

with a Window Warning "codec : internal error opening AV_CODEC_ID_H264"

@lieff
Copy link
Owner

lieff commented Dec 3, 2018

Can you attach sample h264 elementary stream that shows the problem?

@Syd76
Copy link
Author

Syd76 commented Dec 4, 2018

i try git clone with MINIMP4_TRANSCODE_SPS_ID=1 , sequential_mode = 0
left-20181204_0844.zip
there a a crash.

In my code , with MINIMP4_TRANSCODE_SPS_ID = 0, i can make more than 4 Go ( sequence 1 or 0 ) , but , VLC read last frame before 4Go. For example, 40Mbits/s ... after 15 minutes, we can see another frame (like a freeze). But, i can open , read and see the time in bottom .

Log VLC after read more than 4Go ( ~ 4.2 go ) :

[h264 @ 0x7f8b60e5fa80] AVC: nal size 1253811430
[h264 @ 0x7f8b60e5fa80] AVC: nal size 1253811430
[h264 @ 0x7f8b60e5fa80] no frame!
[h264 @ 0x7f8b60d77f80] AVC: nal size -1752346598
[h264 @ 0x7f8b60d77f80] AVC: nal size -1752346598

Last day , it's was MINIMP4_TRANSCODE_SPS_ID=0 , not MINIMP4_TRANSCODE_SPS_ID=1

@lieff
Copy link
Owner

lieff commented Dec 4, 2018

Thanks for testing again :)
Problem in your stream is zeros at the end of nals, add1655 should fix it. And now I can open resulting file using avidemux.

@Syd76
Copy link
Author

Syd76 commented Dec 4, 2018

yes, the function remove_nal_escapes return 0 due buffer problems. i drop buffers and open with avidemux.
Thanks

@Syd76
Copy link
Author

Syd76 commented Dec 4, 2018

Amazing, MINIMP4_TRANSCODE_SPS_ID=1 ans sequence = 0 ... i have an error from id SPS.
In change_sps_id function , ue_bits return 33 !!!

Line in git :
L2169 : transcode_nalu ...
L2000 : int cb = change_sps_id(bst, bdt, 0, &old_id);
L1927 : sps_id = ue_bits(bs); // max = 31

here , we have sizeof_nal = 4.

unfortunely , i cant reproduct this in a 264 file.

#0 0x0000007fb7b18528 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x0000007fb7b199e0 in __GI_abort () at abort.c:89
#2 0x0000007fb7b11c04 in __assert_fail_base (fmt=0x7fb7bfe290 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x7fb7f96118 "n > 0 && n <= 16",
file=file@entry=0x7fb7f95e20 "./src/minimp4.cpp", line=line@entry=1225,
function=function@entry=0x7fb7f96c38 <show_bits::PRETTY_FUNCTION> "unsigned int show_bits(bit_reader_t*, int)") at assert.c:92
#3 0x0000007fb7b11cac in __GI___assert_fail (assertion=0x7fb7f96118 "n > 0 && n <= 16", file=0x7fb7f95e20 "./src/minimp4.cpp", line=1225,
function=0x7fb7f96c38 <show_bits::PRETTY_FUNCTION> "unsigned int show_bits(bit_reader_t*, int)") at assert.c:101
#4 0x0000007fb7f6aed8 in show_bits (bs=0x7f6cd2f408, n=33) at ./src/minimp4.cpp:1225
#5 0x0000007fb7f6b02c in get_bits (bs=0x7f6cd2f408, n=33) at ./src/minimp4.cpp:1245
#6 0x0000007fb7f6b268 in ue_bits (bs=0x7f6cd2f408) at ./src/minimp4.cpp:1297
#7 0x0000007fb7f6bb30 in change_sps_id (bs=0x7f6cd2f408, bd=0x7f6cd2f3d8, new_id=0, old_id=0x7f6cd2f3c0) at ./src/minimp4.cpp:1511
#8 0x0000007fb7f6be54 in transcode_nalu (h=0x469200, src=0x7f580020e0 "gd\f)", nalu_bytes=4, dst=0x7f58000940 "g ") at ./src/minimp4.cpp:1584
#9 0x0000007fb7f6c56c in mp4_h264_write_nal (h=0x469200, nal=0x7f440009c4 "gd\f)\254,\250\003\300\004>@", length=8, timeStamp90kHz_next=9000)
at ./src/minimp4.cpp:1768
#10 0x0000007fb7f3083c in Nv_MJPEG_Encoder_HEVC::write_HEVC_Context (this=0x45ba20, _ctx=0x468a90, _frame=0x7f440008c0)
at ./src/Nv_MJPEG_Encoder_HEVC.cpp:7619

@Syd76
Copy link
Author

Syd76 commented Dec 4, 2018

THX .... i think that i found for SPS error out of rang ( 33 > 31 ) ... that's a NvVideoEncoder setting profile : set to HIGH.
So , _MINIMP4_TRANSCODE_SPS_ID = 1 doesn't crash !!!

@lieff
Copy link
Owner

lieff commented Dec 4, 2018

Nice :) I will try to check big files as well.

@Syd76
Copy link
Author

Syd76 commented Dec 4, 2018

I add free buffer in cas :

`

        if( !sizeof_nal )
        {
            free(nal1);
            free(nal2);
            return 0;
        }

`

MINIMP4_TRANSCODE_SPS_ID = 1 and Sequence = 0 , there are a freeze image in VLC with message :

[h264 @ 0x7fe444def5c0] AVC: nal size -492798288
[h264 @ 0x7fe444def5c0] AVC: nal size -492798288
[h264 @ 0x7fe444def5c0] no frame!
[h264 @ 0x7fe444d07ac0] AVC: nal size -1061128795
[h264 @ 0x7fe444d07ac0] AVC: nal size -1061128795
[h264 @ 0x7fe444d07ac0] no frame!
[h264 @ 0x7fe444d60680] AVC: nal size 2006677627
[h264 @ 0x7fe444d60680] AVC: nal size 2006677627
[h264 @ 0x7fe444d60680] no frame!

I think is last image before the 4.2 Go.

MINIMP4_TRANSCODE_SPS_ID = 1 and Sequence = 1 have same issu

lieff added a commit that referenced this issue Dec 4, 2018
@lieff
Copy link
Owner

lieff commented Dec 4, 2018

Thanks :) Fixed the leak.

@Syd76
Copy link
Author

Syd76 commented Dec 4, 2018

It's more me who thank you !!!

Have you an idea for read big files ? I can read first 4.2Go on big file. All other frames after this was mark go away like vlc message , but scrollbar time run always.

[h264 @ 0x7fe444def5c0] AVC: nal size -492798288
[h264 @ 0x7fe444def5c0] no frame!

@lieff
Copy link
Owner

lieff commented Dec 4, 2018

Here 64bit indexes support cced14d . Now I'm able to seek large files.

@Syd76
Copy link
Author

Syd76 commented Dec 4, 2018

nice job !!!! ... i make big MP4 file with sample left-20181204_0844.zip (loop in minimp4_test.c for duplicate h264 buffer)... and, that's work well ;)
Tomorrow , i try with camera .... i thinks that will be good ! :)

This is a tiny application is great job for small soc and embedded system 🥇

@lieff
Copy link
Owner

lieff commented Dec 5, 2018

Can you check that High Profile works too? If it's not, can you attach sample stream?

@Syd76
Copy link
Author

Syd76 commented Dec 5, 2018

i think left-20181204_0844.zip is on 10fps, 4k , profile HIGH and level 4.0 , i will to test too on 5.1 for next nigth

@lieff
Copy link
Owner

lieff commented Dec 5, 2018

I'm about

THX .... i think that i found for SPS error out of rang ( 33 > 31 ) ... that's a NvVideoEncoder setting profile : set to HIGH.

left-20181204_0844.zip do not have such problem.
This can be issue with sps rbsp encoding. Or that was error not HP related?

@Syd76
Copy link
Author

Syd76 commented Dec 5, 2018

sps id from encoding was solve with good parameters settings on Hardware HEVC (encoder like sps enable option --' ).
Today , that's ok ! And this seems to work in level 5.1. ( profile HIGH)

@lieff
Copy link
Owner

lieff commented Dec 5, 2018

Good :) I guess everything solved then.

@Syd76
Copy link
Author

Syd76 commented Dec 5, 2018

🥇

Yep ... nice job !!!

@Syd76
Copy link
Author

Syd76 commented Dec 6, 2018

Last nightly, tests have work well in level 5.1 , and have produced readable big files !!!

That's solved ;)

@lieff
Copy link
Owner

lieff commented Dec 20, 2018

Closing then.

@lieff lieff closed this as completed Dec 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants