Newest 'ffmpeg' Questions - Stack Overflow
Les articles publiés sur le site
-
Assigning of dts values to encoded packets
24 mars, par AlexI have a dump of H264-encoded data, which I need to put in mp4 container. I verified the validity of the encoded data by using mp4box utility against it. The mp4 file created by mp4box contained a proper 17 seconds long video. It is interesting that if I try ffmpeg to achieve the same, the resulting video is 34 seconds long and rather crappy (probably ffmpeg tries to decode video and then encode it, which results in the loss of video quality?) Anyway, for my project I can't use command line approach and need to come up wit a programmatic way to embed the data in the mp4 container.
Below is the code I use (I removed error checking for brevity. During execution all the calls succeed):
AVFormatContext* pInputFormatContext = avformat_alloc_context(); avformat_open_input(&pInputFormatContext, "Data.264", NULL, NULL); avformat_find_stream_info(pInputFormatContext, NULL); AVRational* pTime_base = &pInputFormatContext->streams[0]->time_base; int nFrameRate = pInputFormatContext->streams[0]->r_frame_rate.num / pFormatCtx->streams[0]->r_frame_rate.den; int nWidth = pInputFormatContext->streams[0]->codecpar->width; int nHeight = pInputFormatContext->streams[0]->codecpar->height; // nWidth = 1920, nHeight = 1080, nFrameRate = 25 // Create output objects AVFormatContext* pOutputFormatContext = NULL; avformat_alloc_output_context2(&pOutputFormatContext, NULL, NULL, "Destination.mp4"); AVCodec* pVideoCodec = avcodec_find_encoder(pOutputFormatContext->oformat->video_codec/*AV_CODEC_ID_264*/); AVStream* pOutputStream = avformat_new_stream(pOutputFormatContext, NULL); pOutputStream->id = pOutputFormatContext->nb_streams - 1; AVCodecContext* pCodecContext = avcodec_alloc_context3(pVideoCodec); switch (pVideoCodec->type) { case AVMEDIA_TYPE_VIDEO: pCodecContext->codec_id = codec_id; pCodecContext->bit_rate = 400000; /* Resolution must be a multiple of two. */ pCodecContext->width = nFrameWidth; pCodecContext->height = nFrameHeight; /* timebase: This is the fundamental unit of time (in seconds) in terms * of which frame timestamps are represented. For fixed-fps content, * timebase should be 1/framerate and timestamp increments should be * identical to 1. */ pOutputStream->time_base.num = 1; pOutputStream->time_base.den = nFrameRate; pCodecContext->time_base = pOutputStream->time_base; pCodecContext->gop_size = 12; /* emit one intra frame every twelve frames at most */ pCodecContext->pix_fmt = STREAM_PIX_FMT; break; default: break; } /* copy the stream parameters to the muxer */ avcodec_parameters_from_context(pOutputStream->codecpar, pCodecContext); avio_open(&pOutputFormatContext->pb, "Destination.mp4", AVIO_FLAG_WRITE); // Start writing AVDictionary* pDict = NULL; avformat_write_header(pOutputFormatContext, &pDict); // Process packets AVPacket packet; int64_t nCurrentDts = 0; int64_t nDuration = 0; int nReadResult = 0; while (nReadResult == 0) { nReadResult = av_read_frame(m_pInputFormatContext, &packet); // At this point, packet.dts == AV_NOPTS_VALUE. // The duration field of the packet contains valid data packet.flags |= AV_PKT_FLAG_KEY; nDuration = packet.duration; packet.dts = nCurrentDts; packet.dts = av_rescale_q(nCurrentDts, pOutputFormatContext->streams[0]->codec->time_base, pOutputFormatContext->streams[0]->time_base); av_interleaved_write_frame(pOutputFormatContext, &packet); nCurrentDts += nDuration; nDuration += packet.duration; av_free_packet(&packet); } av_write_trailer(pOutputFormatContext);
The properties for the Destination.mp4 file I receive indicate it is about 1 hour long with frame rate 0. I am sure the culprit is in the way I calculate dts values for each packet and use av_rescale_q(), but I do not have sufficient understanding of the avformat library to figure out the proper way to do it. Any help will be appreciated!
-
FFmpeg - What does non monotonically increasing dts mean ?
24 mars, par Mukund ManikarnikeObservations - Part - I
I saw a suggestion elsewhere to run the following command to see if there's something wrong with my .mp4.
ffmpeg -v error -i ~/Desktop/5_minute_sync_output_15mn.mp4 -f null - 2>error.log
When I run the above command, I see a whole bunch of the logs on the lines of what's shown below.
Application provided invalid, non monotonically increasing dts to muxer in stream 0: 15635 >= 15635
This, from searching and reading up quite a bit, I understand that the decoding timestamp isn't in sequential order.
Observations - Part II
But, inspecting the frames of the same mp4 using the following command and some post processing, I don't see
pkt_dts
within the frames_info json being out of order for either of the video or audio streams.ffprobe -loglevel panic -of json -show_frames ~/Desktop/5_minute_sync_output_15mn.mp4
This makes me doubt my initial understanding in Observations - Part - I
Are these 2 things not related? Any help on this will be greatly appreciated.
-
ffmpeg remove Non-Monotonous DTS frames
24 mars, par MiGu3XIs it possible to stream copy a .ts file to another .ts file by removing the Non-Monotonous DTS frames? These frames usually also have a smaller resolution than the video I am trying to copy. I attempted this with VideoReDo but it did not work and I cannot seem to make it work.
Also, the MediaInfo for the video after remixed to Matrosks shows this:
Video ID : 1 Format : AVC Format/Info : Advanced Video Codec Format profile : High@L3.2 Format settings : CABAC / 2 Ref Frames Format settings, CABAC : Yes Format settings, RefFrames : 2 frames Codec ID : V_MPEG4/ISO/AVC Duration : 2 h 35 min Nominal bit rate : 6 000 kb/s Width : 896 pixels Original width : 1 280 pixels Height : 504 pixels Original height : 720 pixels Display aspect ratio : 16:9 Frame rate mode : Constant Frame rate : 30.000 FPS Original frame rate : 60.000 FPS Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Bits/(Pixel*Frame) : 0.443 Writing library : x264 core 148 r2579M 73ae2d1 Encoding settings : cabac=1 / ref=2 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=2 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=0 / me_range=16 / chroma_me=1 / trellis=0 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=0 / threads=4 / lookahead_threads=1 / sliced_threads=0 / nr=250 / decimate=1 / interlaced=0 / bluray_compat=0 / stitchable=1 / constrained_intra=0 / bframes=0 / weightp=1 / keyint=122 / keyint_min=12 / scenecut=40 / intra_refresh=0 / rc_lookahead=10 / rc=2pass / mbtree=1 / bitrate=6000 / ratetol=1.0 / qcomp=0.60 / qpmin=5 / qpmax=69 / qpstep=4 / cplxblur=20.0 / qblur=0.5 / ip_ratio=1.40 / aq=1:1.00 Default : Yes Forced : No
Thanks for the help!
-
How to set pts, dts and duration in ffmpeg library ?
24 mars, par hsleeI want to pack some compressed video packets(h.264) to ".mp4" container. One word, Muxing, no decoding and no encoding. And I have no idea how to set pts, dts and duration.
- I get the packets with "pcap" library.
- I removed headers before compressed video data show up. e.g. Ethernet, VLAN.
- I collected data until one frame and decoded it for getting information of data. e.g. width, height. (I am not sure that it is necessary)
- I initialized output context, stream and codec context.
- I started to receive packets with "pcap" library again. (now for muxing)
- I made one frame and put that data in AVPacket structure.
- I try to set PTS, DTS and duration. (I think here is wrong part, not sure though)
*7-1. At the first frame, I saved time(msec) with packet header structure.
*7-2. whenever I made one frame, I set parameters like this : PTS(current time - start time), DTS(same PTS value), duration(current PTS - before PTS)
I think it has some error because :
I don't know how far is suitable long for dts from pts.
At least, I think duration means how long time show this frame from now to next frame, so It should have value(next PTS - current PTS), but I can not know the value next PTS at that time.
It has I-frame only.
// make input context for decoding AVFormatContext *&ic = gInputContext; ic = avformat_alloc_context(); AVCodec *cd = avcodec_find_decoder(AV_CODEC_ID_H264); AVStream *st = avformat_new_stream(ic, cd); AVCodecContext *cc = st->codec; avcodec_open2(cc, cd, NULL); // make packet and decode it after collect packets is be one frame gPacket.stream_index = 0; gPacket.size = gPacketLength[0]; gPacket.data = gPacketData[0]; gPacket.pts = AV_NOPTS_VALUE; gPacket.dts = AV_NOPTS_VALUE; gPacket.flags = AV_PKT_FLAG_KEY; avcodec_decode_video2(cc, gFrame, &got_picture, &gPacket); // I checked automatically it initialized after "avcodec_decode_video2" // put some info that I know that not initialized cc->time_base.den = 90000; cc->time_base.num = 1; cc->bit_rate = 2500000; cc->gop_size = 1; // make output context with input context AVFormatContext *&oc = gOutputContext; avformat_alloc_output_context2(&oc, NULL, NULL, filename); AVFormatContext *&ic = gInputContext; AVStream *ist = ic->streams[0]; AVCodecContext *&icc = ist->codec; AVStream *ost = avformat_new_stream(oc, icc->codec); AVCodecContext *occ = ost->codec; avcodec_copy_context(occ, icc); occ->flags |= CODEC_FLAG_GLOBAL_HEADER; avio_open(&(oc->pb), filename, AVIO_FLAG_WRITE); // repeated part for muxing AVRational Millisecond = { 1, 1000 }; gPacket.stream_index = 0; gPacket.data = gPacketData[0]; gPacket.size = gPacketLength[0]; gPacket.pts = av_rescale_rnd(pkthdr->ts.tv_sec * 1000 / + pkthdr->ts.tv_usec / 1000 / - gStartTime, Millisecond.den, ost->time_base.den, / (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); gPacket.dts = gPacket.pts; gPacket.duration = gPacket.pts - gPrev; gPacket.flags = AV_PKT_FLAG_KEY; gPrev = gPacket.pts; av_interleaved_write_frame(gOutputContext, &gPacket);
Expected and actual results is a .mp4 video file that can play.
-
Non-monotonous DTS after 26:30:02.81 recording time
24 mars, par michaI record an hls stream and after 26:30:02.81 there come the message:
[http @ 0x558330f5ba80] Opening 'http://de-origin-live-be-01.3qsdn.com:8081/3279/996191_PwxkbnqRThCDGXVr/l_94_95438333_16449.ts?nimblesessionid=2106' for reading frame=2289669 fps= 24 q=-1.0 size=25056768kB time=26:30:02.81 bitrate=2151.6kbits/s speed= 1x [mpegts @ 0x558330f07280] Invalid timestamps stream=0, pts=10378, dts=8589926250, size=11200 [mpegts @ 0x558330f07280] Invalid timestamps stream=0, pts=2908, dts=8589929940, size=3407 [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:0; previous: 8586744840, current: -3185972; changing to 8586744841. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598864, current: -1698561; changing to 4579598865. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598865, current: -1697537; changing to 4579598866. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598866, current: -1696513; changing to 4579598867. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:0; previous: 8586744841, current: -3182282; changing to 8586744842. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598867, current: -1695489; changing to 4579598868. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598868, current: -1694465; changing to 4579598869. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598869, current: -1693441; changing to 4579598870. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:0; previous: 8586744842, current: -3178502; changing to 8586744843. This may result in incorrect timestamps in the output file. [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:0; previous: 8586744843, current: -3174722; changing to 8586744844. This may result in incorrect timestamps in the output file.
There is no more video written to the file at this time but ffmpeg is not stopping. If i stop it manual after 30 hours the file is only 26 hours 30 minutes long.
How to reproduce:
ffmpeg -progress recorder.progress -reconnect 1 -user_agent 'sdn/1.0' -i http://source/playlist.m3u8 -codec copy -bsf:a aac_adtstoasc record.mp4 ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1) configuration: --disable-debug --disable-doc --disable-ffplay --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-libass --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libx265 --enable-libxvid --enable-libx264 --enable-nonfree --enable-openssl --enable-libfdk_aac --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-postproc --enable-small --enable-version3 --enable-libbluray --enable-demuxer=dash --enable-decoder=hevc --enable-libxml2 --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib --extra-libs=-ldl --prefix=/opt/ffmpeg libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100