github.com/bluenviron/mediacommon@v1.9.3/pkg/codecs/h264/dts_extractor_test.go (about)

     1  package h264
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func TestDTSExtractor(t *testing.T) {
    11  	type sample struct {
    12  		au  [][]byte
    13  		dts time.Duration
    14  		pts time.Duration
    15  	}
    16  
    17  	for _, ca := range []struct {
    18  		name     string
    19  		sequence []sample
    20  	}{
    21  		{
    22  			"with timing info",
    23  			[]sample{
    24  				{
    25  					[][]byte{
    26  						{ // SPS
    27  							0x67, 0x64, 0x00, 0x28, 0xac, 0xd9, 0x40, 0x78,
    28  							0x02, 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00,
    29  							0x04, 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60,
    30  							0xc6, 0x58,
    31  						},
    32  						{ // IDR
    33  							0x65, 0x88, 0x84, 0x00, 0x33, 0xff,
    34  						},
    35  					},
    36  					333333333 * time.Nanosecond,
    37  					333333333 * time.Nanosecond,
    38  				},
    39  				{
    40  					[][]byte{{0x41, 0x9a, 0x21, 0x6c, 0x45, 0xff}},
    41  					366666666 * time.Nanosecond,
    42  					366666666 * time.Nanosecond,
    43  				},
    44  				{
    45  					[][]byte{{0x41, 0x9a, 0x42, 0x3c, 0x21, 0x93}},
    46  					400000000 * time.Nanosecond,
    47  					400000000 * time.Nanosecond,
    48  				},
    49  				{
    50  					[][]byte{{0x41, 0x9a, 0x63, 0x49, 0xe1, 0x0f}},
    51  					433333333 * time.Nanosecond,
    52  					433333333 * time.Nanosecond,
    53  				},
    54  				{
    55  					[][]byte{{0x41, 0x9a, 0x86, 0x49, 0xe1, 0x0f}},
    56  					434333333 * time.Nanosecond,
    57  					533333333 * time.Nanosecond,
    58  				},
    59  				{
    60  					[][]byte{{0x41, 0x9e, 0xa5, 0x42, 0x7f, 0xf9}},
    61  					435333333 * time.Nanosecond,
    62  					500000000 * time.Nanosecond,
    63  				},
    64  				{
    65  					[][]byte{{0x01, 0x9e, 0xc4, 0x69, 0x13, 0xff}},
    66  					466666666 * time.Nanosecond,
    67  					466666666 * time.Nanosecond,
    68  				},
    69  				{
    70  					[][]byte{{0x41, 0x9a, 0xc8, 0x4b, 0xa8, 0x42}},
    71  					499999999 * time.Nanosecond,
    72  					600000000 * time.Nanosecond,
    73  				},
    74  				{
    75  					[][]byte{
    76  						{ // IDR
    77  							0x65, 0x88, 0x84, 0x00, 0x33, 0xff,
    78  						},
    79  					},
    80  					533333332 * time.Nanosecond,
    81  					599999999 * time.Nanosecond,
    82  				},
    83  			},
    84  		},
    85  		{
    86  			"no timing info",
    87  			[]sample{
    88  				{
    89  					[][]byte{
    90  						{ // SPS
    91  							0x27, 0x64, 0x00, 0x20, 0xac, 0x52, 0x18, 0x0f,
    92  							0x01, 0x17, 0xef, 0xff, 0x00, 0x01, 0x00, 0x01,
    93  							0x6a, 0x02, 0x02, 0x03, 0x6d, 0x85, 0x6b, 0xde,
    94  							0xf8, 0x08,
    95  						},
    96  						{ // IDR
    97  							0x25, 0xb8, 0x08, 0x02, 0x1f, 0xff,
    98  						},
    99  					},
   100  					850000000 * time.Nanosecond,
   101  					850000000 * time.Nanosecond,
   102  				},
   103  				{
   104  					[][]byte{{0x21, 0xe1, 0x05, 0xc7, 0x38, 0xbf}},
   105  					866666667 * time.Nanosecond,
   106  					866666667 * time.Nanosecond,
   107  				},
   108  				{
   109  					[][]byte{{0x21, 0xe2, 0x09, 0xa1, 0xce, 0x0b}},
   110  					883333334 * time.Nanosecond,
   111  					883333334 * time.Nanosecond,
   112  				},
   113  				{
   114  					[][]byte{{0x21, 0xe3, 0x0d, 0xb1, 0xce, 0x02}},
   115  					900000000 * time.Nanosecond,
   116  					900000000 * time.Nanosecond,
   117  				},
   118  				{
   119  					[][]byte{{0x21, 0xe4, 0x11, 0x90, 0x73, 0x80}},
   120  					916666667 * time.Nanosecond,
   121  					916666667 * time.Nanosecond,
   122  				},
   123  				{
   124  					[][]byte{{0x21, 0xe5, 0x19, 0x0e, 0x70, 0x01}},
   125  					917666667 * time.Nanosecond,
   126  					950000000 * time.Nanosecond,
   127  				},
   128  				{
   129  					[][]byte{{0x01, 0xa9, 0x85, 0x7c, 0x93, 0xff}},
   130  					933333334 * time.Nanosecond,
   131  					933333334 * time.Nanosecond,
   132  				},
   133  				{
   134  					[][]byte{{0x21, 0xe6, 0x1d, 0x0e, 0x70, 0x01}},
   135  					950000000 * time.Nanosecond,
   136  					966666667 * time.Nanosecond,
   137  				},
   138  				{
   139  					[][]byte{{0x21, 0xe7, 0x21, 0x0e, 0x70, 0x01}},
   140  					966666667 * time.Nanosecond,
   141  					983333334 * time.Nanosecond,
   142  				},
   143  				{
   144  					[][]byte{{0x21, 0xe8, 0x25, 0x0e, 0x70, 0x01}},
   145  					983333333 * time.Nanosecond,
   146  					1000000000 * time.Nanosecond,
   147  				},
   148  				{
   149  					[][]byte{{0x21, 0xe9, 0x29, 0x0e, 0x70, 0x01}},
   150  					1000000000 * time.Nanosecond,
   151  					1016666667 * time.Nanosecond,
   152  				},
   153  				{
   154  					[][]byte{{0x21, 0xea, 0x31, 0x0e, 0x70, 0x01}},
   155  					1016666666 * time.Nanosecond,
   156  					1050000000 * time.Nanosecond,
   157  				},
   158  				{
   159  					[][]byte{{0x01, 0xaa, 0xcb, 0x7c, 0x93, 0xff}},
   160  					1033333334 * time.Nanosecond,
   161  					1033333334 * time.Nanosecond,
   162  				},
   163  			},
   164  		},
   165  		{
   166  			"poc increment = 1",
   167  			[]sample{
   168  				{
   169  					[][]byte{
   170  						{ // SPS
   171  							0x67, 0x64, 0x00, 0x2a, 0xac, 0x2c, 0x6a, 0x81,
   172  							0xe0, 0x08, 0x9f, 0x96, 0x6e, 0x02, 0x02, 0x02,
   173  							0x80, 0x00, 0x03, 0x84, 0x00, 0x00, 0xaf, 0xc8,
   174  							0x02,
   175  						},
   176  						{ // IDR
   177  							0x65, 0xb8, 0x00, 0x00, 0x0b, 0xc8,
   178  						},
   179  					},
   180  					61 * time.Millisecond,
   181  					61 * time.Millisecond,
   182  				},
   183  				{
   184  					[][]byte{{0x61, 0xe0, 0x20, 0x00, 0x39, 0x37}},
   185  					101 * time.Millisecond,
   186  					101 * time.Millisecond,
   187  				},
   188  				{
   189  					[][]byte{{0x61, 0xe0, 0x40, 0x00, 0x59, 0x37}},
   190  					141 * time.Millisecond,
   191  					141 * time.Millisecond,
   192  				},
   193  				{
   194  					[][]byte{{0x61, 0xe0, 0x60, 0x00, 0x79, 0x37}},
   195  					181 * time.Millisecond,
   196  					181 * time.Millisecond,
   197  				},
   198  			},
   199  		},
   200  		{
   201  			"B-frames after IDR (OBS 29.1.3 QuickSync on Windows)",
   202  			[]sample{
   203  				{
   204  					[][]byte{
   205  						{ // SPS
   206  							0x27, 0x64, 0x00, 0x2a, 0xac, 0x2d, 0x90, 0x07,
   207  							0x80, 0x22, 0x7e, 0x5c, 0x05, 0xa8, 0x08, 0x08,
   208  							0x0a, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00,
   209  							0x03, 0x00, 0xf1, 0xd0, 0x80, 0x04, 0xc4, 0x80,
   210  							0x00, 0x09, 0x89, 0x68, 0xde, 0xf7, 0xc1, 0xda,
   211  							0x1c, 0x31, 0x92,
   212  						},
   213  						{ // IDR
   214  							0x65, 0x88, 0x80, 0x14, 0x3, 0xff, 0xde, 0x8, 0xe4, 0x74,
   215  						},
   216  					},
   217  					1916 * time.Millisecond,
   218  					1916 * time.Millisecond,
   219  				},
   220  				{ // b-frame
   221  					[][]byte{{0x41, 0x9e, 0x3, 0xe4, 0x3f, 0x0, 0x0, 0x3, 0x0, 0x0}},
   222  					1917 * time.Millisecond,
   223  					1883 * time.Millisecond,
   224  				},
   225  				{ // b-frame
   226  					[][]byte{{0x1, 0x9e, 0x5, 0xd4, 0x7f, 0x0, 0x0, 0x3, 0x0, 0x0}},
   227  					1918 * time.Millisecond,
   228  					1867 * time.Millisecond,
   229  				},
   230  				{ // p-frame
   231  					[][]byte{{0x1, 0x9e, 0x5, 0xf4, 0x7f, 0x0, 0x0, 0x3, 0x0, 0x0}},
   232  					1919 * time.Millisecond,
   233  					1899 * time.Millisecond,
   234  				},
   235  				{ // p-frame
   236  					[][]byte{{0x1, 0x9e, 0x5, 0xf4, 0x7f, 0x0, 0x0, 0x3, 0x0, 0x0}},
   237  					1920 * time.Millisecond,
   238  					1983 * time.Millisecond,
   239  				},
   240  			},
   241  		},
   242  		{
   243  			"mbs_only_flag = 0",
   244  			[]sample{
   245  				{
   246  					[][]byte{
   247  						{ // SPS
   248  							0x67, 0x4d, 0x40, 0x28, 0xab, 0x60, 0x3c, 0x02,
   249  							0x23, 0xef, 0x01, 0x10, 0x00, 0x00, 0x03, 0x00,
   250  							0x10, 0x00, 0x00, 0x03, 0x03, 0x2e, 0x94, 0x00,
   251  							0x35, 0x64, 0x06, 0xb2, 0x85, 0x08, 0x0e, 0xe2,
   252  							0xc5, 0x22, 0xc0,
   253  						},
   254  						{0x68, 0xca, 0x41, 0xf2},                                     // PPS
   255  						{0x6, 0x0, 0x6, 0x85, 0x7e, 0x40, 0x0, 0x0, 0x10, 0x1},       // SEI
   256  						{0x65, 0x88, 0x82, 0x80, 0x1f, 0xff, 0xfb, 0xf0, 0xa2, 0x88}, // IDR
   257  						{0x6, 0x1, 0x2, 0x4, 0x24, 0x80},                             // SEI
   258  						{0x41, 0x9a, 0xc, 0x1c, 0x2f, 0xe4, 0xed, 0x23, 0xb5, 0x63},  // non-IDR
   259  					},
   260  					0,
   261  					0,
   262  				},
   263  				{
   264  					[][]byte{
   265  						{0x6, 0x1, 0x2, 0x8, 0x14, 0x80},                             // SEI
   266  						{0x41, 0x9a, 0x18, 0x2a, 0x1f, 0xeb, 0x2f, 0xa2, 0xb1, 0x7e}, // non-IDR
   267  					},
   268  					40 * time.Millisecond,
   269  					40 * time.Millisecond,
   270  				},
   271  				{
   272  					[][]byte{
   273  						{0x6, 0x1, 0x2, 0xc, 0x24, 0x80},                            // SEI
   274  						{0x41, 0x9a, 0x1c, 0x3a, 0xf, 0xfa, 0x55, 0xc2, 0x55, 0xea}, // non-IDR
   275  					},
   276  					80 * time.Millisecond,
   277  					80 * time.Millisecond,
   278  				},
   279  			},
   280  		},
   281  		{
   282  			"Log2MaxPicOrderCntLsbMinus4 = 12",
   283  			[]sample{
   284  				{
   285  					[][]byte{
   286  						{ // SPS
   287  							0x67, 0x42, 0xc0, 0x1e, 0x8c, 0x8d, 0x40, 0x50, 0x17, 0xfc, 0xb0, 0x0f, 0x08, 0x84, 0x6a,
   288  						},
   289  						{ // PPS
   290  							0x68, 0xce, 0x3c, 0x80,
   291  						},
   292  						{ // IDR
   293  							0x65, 0x88, 0x80, 0x14, 0x3, 0xff, 0xde, 0x8, 0xe4, 0x74,
   294  						},
   295  					},
   296  					0,
   297  					0,
   298  				},
   299  				{
   300  					[][]byte{
   301  						{0x61, 0x00, 0xf0, 0xe0, 0x00, 0x40, 0x00, 0xbe, 0x47, 0x9b}, // non-IDR
   302  					},
   303  					40 * time.Millisecond,
   304  					40 * time.Millisecond,
   305  				},
   306  			},
   307  		},
   308  	} {
   309  		t.Run(ca.name, func(t *testing.T) {
   310  			ex := NewDTSExtractor()
   311  			for _, sample := range ca.sequence {
   312  				dts, err := ex.Extract(sample.au, sample.pts)
   313  				require.NoError(t, err)
   314  				require.Equal(t, sample.dts, dts)
   315  			}
   316  		})
   317  	}
   318  }
   319  
   320  func FuzzDTSExtractor(f *testing.F) {
   321  	ex := NewDTSExtractor()
   322  	f.Fuzz(func(_ *testing.T, b []byte, p uint64) {
   323  		if len(b) < 1 {
   324  			return
   325  		}
   326  		ex.Extract([][]byte{ //nolint:errcheck
   327  			{ // SPS
   328  				0x27, 0x64, 0x00, 0x20, 0xac, 0x52, 0x18, 0x0f,
   329  				0x01, 0x17, 0xef, 0xff, 0x00, 0x01, 0x00, 0x01,
   330  				0x6a, 0x02, 0x02, 0x03, 0x6d, 0x85, 0x6b, 0xde,
   331  				0xf8, 0x08,
   332  			},
   333  			b,
   334  		}, time.Duration(p))
   335  	})
   336  }