Adjust PTS and DTS before mp4 video creation

For the developers that use FFmpeg in their software.
Post Reply
crindu
Posts: 1
Joined: Sun Mar 18, 2018 5:17 pm

Adjust PTS and DTS before mp4 video creation

Post by crindu » Sun Mar 18, 2018 5:22 pm

I'm retrieving raw h264 compressed frames from usb camera to create an mp4 video. This is my simple code:

Code: Select all

    for(int i = 0; i<120;i++)
    {
        AVPacket pkt;
        av_init_packet(&pkt);
        ret = av_read_frame(inputFormatCtx, &pkt);
        
        pkt.pts = pkt.dts = i;
        pkt.pts = av_rescale_q(pkt.pts, inputStream->time_base, outputStream->time_base);
        pkt.dts = av_rescale_q(pkt.dts, inputStream->time_base, outputStream->time_base);
        
        ret = av_interleaved_write_frame(outputFormatCtx, &pkt);
        av_packet_unref(&pkt);
    } 
    ret = av_write_trailer(outputFormatCtx);
    
This works well. Now I would like to store these AVPackets to create the video in a second moment.
I changed my code in this way

Code: Select all

    for(int i = 0; i<120;i++){
    AVPacket pkt;
    av_init_packet(&pkt);
    ret = av_read_frame(inputFormatCtx, &pkt);
    packets.push_back(pkt);
    } 

    vector<AVPacket>::reverse_iterator it;
    int j = 0;
    for(it = packets.rbegin(); it != packets.rend(); it++){
        AVPacket n = (*it);
        n.pts = n.dts = j;
        j++;
        n.pts = av_rescale_q(n.pts, inputStream->time_base, outputStream->time_base);
        n.dts = av_rescale_q(n.dts, inputStream->time_base, outputStream->time_base); 
        ret = av_interleaved_write_frame(outputFormatCtx, &n);
        av_packet_unref(&n);
    }

    ret = av_write_trailer(outputFormatCtx);
The resulting video is not so fluid and I used ffprobe to see more details.
These are the first three frame generating with the first block of code.

Code: Select all

    [FRAME]
    media_type=video
    stream_index=0
    key_frame=1
    pkt_pts=0
    pkt_pts_time=0.000000
    pkt_dts=0
    pkt_dts_time=0.000000
    best_effort_timestamp=0
    best_effort_timestamp_time=0.000000
    pkt_duration=512
    pkt_duration_time=0.033333
    pkt_pos=48
    pkt_size=12974
    width=1920
    height=1080
    pix_fmt=yuv420p
    sample_aspect_ratio=N/A
    pict_type=I
    coded_picture_number=0
    display_picture_number=0
    interlaced_frame=0
    top_field_first=0
    repeat_pict=0
    [/FRAME]
    [FRAME]
    media_type=video
    stream_index=0
    key_frame=0
    pkt_pts=512
    pkt_pts_time=0.033333
    pkt_dts=512
    pkt_dts_time=0.033333
    best_effort_timestamp=512
    best_effort_timestamp_time=0.033333
    pkt_duration=512
    pkt_duration_time=0.033333
    pkt_pos=13022
    pkt_size=473
    width=1920
    height=1080
    pix_fmt=yuv420p
    sample_aspect_ratio=N/A
    pict_type=P
    coded_picture_number=1
    display_picture_number=0
    interlaced_frame=0
    top_field_first=0
    repeat_pict=0
    [/FRAME]
    [FRAME]
    media_type=video
    stream_index=0
    key_frame=0
    pkt_pts=1024
    pkt_pts_time=0.066667
    pkt_dts=1024
    pkt_dts_time=0.066667
    best_effort_timestamp=1024
    best_effort_timestamp_time=0.066667
    pkt_duration=512
    pkt_duration_time=0.033333
    pkt_pos=13495
    pkt_size=511
    width=1920
    height=1080
    pix_fmt=yuv420p
    sample_aspect_ratio=N/A
    pict_type=P
    coded_picture_number=2
    display_picture_number=0
    interlaced_frame=0
    top_field_first=0
    repeat_pict=0
    [/FRAME]
    
While these are the same frames created using the second block of code.

Code: Select all

    [FRAME]
    media_type=video
    stream_index=0
    key_frame=1
    pkt_pts=14848
    pkt_pts_time=0.966667
    pkt_dts=14848
    pkt_dts_time=0.966667
    best_effort_timestamp=14848
    best_effort_timestamp_time=0.966667
    pkt_duration=512
    pkt_duration_time=0.033333
    pkt_pos=757791
    pkt_size=65625
    width=1920
    height=1080
    pix_fmt=yuv420p
    sample_aspect_ratio=N/A
    pict_type=I
    coded_picture_number=58
    display_picture_number=0
    interlaced_frame=0
    top_field_first=0
    repeat_pict=0
    [/FRAME]
    [FRAME]
    media_type=video
    stream_index=0
    key_frame=0
    pkt_pts=15360
    pkt_pts_time=1.000000
    pkt_dts=15360
    pkt_dts_time=1.000000
    best_effort_timestamp=15360
    best_effort_timestamp_time=1.000000
    pkt_duration=512
    pkt_duration_time=0.033333
    pkt_pos=823416
    pkt_size=29642
    width=1920
    height=1080
    pix_fmt=yuv420p
    sample_aspect_ratio=N/A
    pict_type=P
    coded_picture_number=60
    display_picture_number=0
    interlaced_frame=0
    top_field_first=0
    repeat_pict=0
    [/FRAME]
    [FRAME]
    media_type=video
    stream_index=0
    key_frame=1
    pkt_pts=30208
    pkt_pts_time=1.966667
    pkt_dts=30208
    pkt_dts_time=1.966667
    best_effort_timestamp=30208
    best_effort_timestamp_time=1.966667
    pkt_duration=512
    pkt_duration_time=0.033333
    pkt_pos=1546454
    pkt_size=66021
    width=1920
    height=1080
    pix_fmt=yuv420p
    sample_aspect_ratio=N/A
    pict_type=I
    coded_picture_number=117
    display_picture_number=0
    interlaced_frame=0
    top_field_first=0
    repeat_pict=0
    [/FRAME]
I immediately noticed that pkt_pts_time and other fields are not starting from 0 and are not increasing linearly (respect to the 30 fps that I established). It is possible to obtain the same video writing the AVPackets in a second moment as I'm doing? Moreover the value of coded_picture_number is strange, some frames seem to be skipped. Thank you.

Post Reply