@@ -325,15 +325,15 @@ private boolean sendSPSandPPS(MediaFormat mediaFormat) {
325325 ByteBuffer bufferInfo = mediaFormat .getByteBuffer ("csd-0" );
326326 //we need an av1ConfigurationRecord with sequenceObu to work
327327 if (bufferInfo != null && bufferInfo .remaining () > 4 ) {
328- oldSps = bufferInfo ;
329- getVideoData .onVideoInfo (bufferInfo , null , null );
328+ oldSps = bufferInfo . duplicate () ;
329+ getVideoData .onVideoInfo (oldSps , null , null );
330330 return true ;
331331 }
332332 //H265
333333 } else if (type .equals (CodecUtil .H265_MIME )) {
334334 ByteBuffer bufferInfo = mediaFormat .getByteBuffer ("csd-0" );
335335 if (bufferInfo != null ) {
336- List <ByteBuffer > byteBufferList = extractVpsSpsPpsFromH265 (bufferInfo );
336+ List <ByteBuffer > byteBufferList = VideoEncoderHelper . extractVpsSpsPpsFromH265 (bufferInfo . duplicate () );
337337 oldSps = byteBufferList .get (1 );
338338 oldPps = byteBufferList .get (2 );
339339 oldVps = byteBufferList .get (0 );
@@ -345,8 +345,8 @@ private boolean sendSPSandPPS(MediaFormat mediaFormat) {
345345 ByteBuffer sps = mediaFormat .getByteBuffer ("csd-0" );
346346 ByteBuffer pps = mediaFormat .getByteBuffer ("csd-1" );
347347 if (sps != null && pps != null ) {
348- oldSps = sps ;
349- oldPps = pps ;
348+ oldSps = sps . duplicate () ;
349+ oldPps = pps . duplicate () ;
350350 oldVps = null ;
351351 getVideoData .onVideoInfo (oldSps , oldPps , oldVps );
352352 return true ;
@@ -393,108 +393,6 @@ protected MediaCodecInfo chooseEncoder(String mime) {
393393 return null ;
394394 }
395395
396- /**
397- * decode sps and pps if the encoder never call to MediaCodec.INFO_OUTPUT_FORMAT_CHANGED
398- */
399- private Pair <ByteBuffer , ByteBuffer > decodeSpsPpsFromBuffer (ByteBuffer outputBuffer , int length ) {
400- byte [] csd = new byte [length ];
401- outputBuffer .get (csd , 0 , length );
402- outputBuffer .rewind ();
403- int i = 0 ;
404- int spsIndex = -1 ;
405- int ppsIndex = -1 ;
406- while (i < length - 4 ) {
407- if (csd [i ] == 0 && csd [i + 1 ] == 0 && csd [i + 2 ] == 0 && csd [i + 3 ] == 1 ) {
408- if (spsIndex == -1 ) {
409- spsIndex = i ;
410- } else {
411- ppsIndex = i ;
412- break ;
413- }
414- }
415- i ++;
416- }
417- if (spsIndex != -1 && ppsIndex != -1 ) {
418- byte [] sps = new byte [ppsIndex ];
419- System .arraycopy (csd , spsIndex , sps , 0 , ppsIndex );
420- byte [] pps = new byte [length - ppsIndex ];
421- System .arraycopy (csd , ppsIndex , pps , 0 , length - ppsIndex );
422- return new Pair <>(ByteBuffer .wrap (sps ), ByteBuffer .wrap (pps ));
423- }
424- return null ;
425- }
426-
427- /**
428- * You need find 0 0 0 1 byte sequence that is the initiation of vps, sps and pps
429- * buffers.
430- *
431- * @param csd0byteBuffer get in mediacodec case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED
432- * @return list with vps, sps and pps
433- */
434- private List <ByteBuffer > extractVpsSpsPpsFromH265 (ByteBuffer csd0byteBuffer ) {
435- List <ByteBuffer > byteBufferList = new ArrayList <>();
436- int vpsPosition = -1 ;
437- int spsPosition = -1 ;
438- int ppsPosition = -1 ;
439- int contBufferInitiation = 0 ;
440- int length = csd0byteBuffer .remaining ();
441- byte [] csdArray = new byte [length ];
442- csd0byteBuffer .get (csdArray , 0 , length );
443- csd0byteBuffer .rewind ();
444- for (int i = 0 ; i < csdArray .length ; i ++) {
445- if (contBufferInitiation == 3 && csdArray [i ] == 1 ) {
446- if (vpsPosition == -1 ) {
447- vpsPosition = i - 3 ;
448- } else if (spsPosition == -1 ) {
449- spsPosition = i - 3 ;
450- } else {
451- ppsPosition = i - 3 ;
452- }
453- }
454- if (csdArray [i ] == 0 ) {
455- contBufferInitiation ++;
456- } else {
457- contBufferInitiation = 0 ;
458- }
459- }
460- byte [] vps = new byte [spsPosition ];
461- byte [] sps = new byte [ppsPosition - spsPosition ];
462- byte [] pps = new byte [csdArray .length - ppsPosition ];
463- for (int i = 0 ; i < csdArray .length ; i ++) {
464- if (i < spsPosition ) {
465- vps [i ] = csdArray [i ];
466- } else if (i < ppsPosition ) {
467- sps [i - spsPosition ] = csdArray [i ];
468- } else {
469- pps [i - ppsPosition ] = csdArray [i ];
470- }
471- }
472- byteBufferList .add (ByteBuffer .wrap (vps ));
473- byteBufferList .add (ByteBuffer .wrap (sps ));
474- byteBufferList .add (ByteBuffer .wrap (pps ));
475- return byteBufferList ;
476- }
477-
478- /**
479- *
480- * @param buffer key frame
481- * @return av1 ObuSequence
482- */
483- private ByteBuffer extractObuSequence (ByteBuffer buffer , MediaCodec .BufferInfo bufferInfo ) {
484- //we can only extract info from keyframes
485- if (bufferInfo .flags != MediaCodec .BUFFER_FLAG_KEY_FRAME ) return null ;
486- byte [] av1Data = new byte [buffer .remaining ()];
487- buffer .get (av1Data );
488- Av1Parser av1Parser = new Av1Parser ();
489- List <Obu > obuList = av1Parser .getObus (av1Data );
490- for (Obu obu : obuList ) {
491- if (av1Parser .getObuType (obu .getHeader ()[0 ]) == ObuType .SEQUENCE_HEADER ) {
492- return ByteBuffer .wrap (obu .getFullData ());
493- }
494- }
495- return null ;
496- }
497-
498396 @ Override
499397 protected Frame getInputFrame () throws InterruptedException {
500398 Frame frame = queue .take ();
@@ -534,7 +432,7 @@ protected void checkBuffer(@NonNull ByteBuffer byteBuffer, @NonNull MediaCodec.B
534432 fixTimeStamp (bufferInfo );
535433 if (!spsPpsSetted && type .equals (CodecUtil .H264_MIME )) {
536434 Log .i (TAG , "formatChanged not called, doing manual sps/pps extraction..." );
537- Pair <ByteBuffer , ByteBuffer > buffers = decodeSpsPpsFromBuffer (byteBuffer .duplicate (), bufferInfo .size );
435+ Pair <ByteBuffer , ByteBuffer > buffers = VideoEncoderHelper . decodeSpsPpsFromBuffer (byteBuffer .duplicate (), bufferInfo .size );
538436 if (buffers != null ) {
539437 Log .i (TAG , "manual sps/pps extraction success" );
540438 oldSps = buffers .first ;
@@ -547,7 +445,7 @@ protected void checkBuffer(@NonNull ByteBuffer byteBuffer, @NonNull MediaCodec.B
547445 }
548446 } else if (!spsPpsSetted && type .equals (CodecUtil .H265_MIME )) {
549447 Log .i (TAG , "formatChanged not called, doing manual vps/sps/pps extraction..." );
550- List <ByteBuffer > byteBufferList = extractVpsSpsPpsFromH265 (byteBuffer .duplicate ());
448+ List <ByteBuffer > byteBufferList = VideoEncoderHelper . extractVpsSpsPpsFromH265 (byteBuffer .duplicate ());
551449 if (byteBufferList .size () == 3 ) {
552450 Log .i (TAG , "manual vps/sps/pps extraction success" );
553451 oldSps = byteBufferList .get (1 );
@@ -560,7 +458,7 @@ protected void checkBuffer(@NonNull ByteBuffer byteBuffer, @NonNull MediaCodec.B
560458 }
561459 } else if (!spsPpsSetted && type .equals (CodecUtil .AV1_MIME )) {
562460 Log .i (TAG , "formatChanged not called, doing manual av1 extraction..." );
563- ByteBuffer obuSequence = extractObuSequence (byteBuffer .duplicate (), bufferInfo );
461+ ByteBuffer obuSequence = VideoEncoderHelper . extractObuSequence (byteBuffer .duplicate (), bufferInfo );
564462 if (obuSequence != null ) {
565463 oldSps = obuSequence ;
566464 getVideoData .onVideoInfo (obuSequence , null , null );
0 commit comments