Android HW H264: append SPS/PPS at the start of key frame [chromium/src : master]

2,463 views
Skip to first unread message

Weiyong Yao (Gerrit)

unread,
Oct 10, 2017, 6:15:47 PM10/10/17
to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Chris Watkins, Commit Bot, chromium...@chromium.org

Hi watk@, please help to take a look at this. Thanks!

View Change

    To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: master
    Gerrit-MessageType: comment
    Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
    Gerrit-Change-Number: 710454
    Gerrit-PatchSet: 1
    Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
    Gerrit-Reviewer: Chris Watkins <wa...@chromium.org>
    Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
    Gerrit-CC: Commit Bot <commi...@chromium.org>
    Gerrit-Comment-Date: Tue, 10 Oct 2017 22:15:41 +0000
    Gerrit-HasComments: No
    Gerrit-HasLabels: No

    Chris Watkins (Gerrit)

    unread,
    Oct 10, 2017, 9:20:31 PM10/10/17
    to Frank Liberato, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Weiyong Yao

    Chris Watkins would like Frank Liberato to review this change.

    View Change

    Android HW H264: append SPS/PPS at the start of key frame

    Android MediaCodec will generate a seperate config frame containing
    SPS/PPS at beginning of encoding H264 stream and the following key
    frames won't have SPS/PPS any more, while other SW/HW H264 encoder
    implementations will generate key frames with SPS/PPS always.
    Recently WebRTC requires the H264 IDR/keyframe to contain SPS/PPS to
    start decoder. Then the H264 intercommunication is broken between
    Android and other platforms.

    To fix this, append SPS/PPS at the start of H264 keyframe on Android.

    Bug:761336
    Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
    ---
    M media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
    1 file changed, 90 insertions(+), 17 deletions(-)


    To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: master
    Gerrit-MessageType: newchange
    Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
    Gerrit-Change-Number: 710454
    Gerrit-PatchSet: 1
    Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
    Gerrit-Reviewer: Chris Watkins <wa...@chromium.org>
    Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>

    Chris Watkins (Gerrit)

    unread,
    Oct 10, 2017, 9:20:32 PM10/10/17
    to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

    I took a look but I'll pass the final review to liberato@ as I've moved teams now.

    View Change

    6 comments:

    To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: master
    Gerrit-MessageType: comment
    Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
    Gerrit-Change-Number: 710454
    Gerrit-PatchSet: 1
    Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
    Gerrit-Reviewer: Chris Watkins <wa...@chromium.org>
    Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
    Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
    Gerrit-CC: Commit Bot <commi...@chromium.org>
    Gerrit-Comment-Date: Wed, 11 Oct 2017 01:20:22 +0000
    Gerrit-HasComments: Yes
    Gerrit-HasLabels: No

    Weiyong Yao (Gerrit)

    unread,
    Oct 11, 2017, 5:02:37 PM10/11/17
    to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

    Thanks watk@! All comments are addressed or answered.

    liberato@, please take a look. Thanks!

    View Change

    6 comments:

      • Why are we no longer using our mOutputBuffer array?

      • Is there a reason this no longer catches IllegalState?

      • This function is a private one now and will be called by queueOutputBuffer() only with a try-catch around, which will handle the exception.
        Added a comment for it.

      • Patch Set #1, Line 481: = MediaCodecStatu

      • Declaration can move closer to usage.

      • Naming style not consistent here

      • Does this need to update mLastPresentationTimeUs?

      • Done

      • Patch Set #1, Line 553: position(outputBu

        I'm worried about doubling the memory consumed by output buffers. […]

        Sorry I didn't get you. Could you please help to elaborate it?
        The purpose is to append configData at the beginning of a key frame (appending config to the end of key frame won't work). Using two Bytebuffer may be the simplest method, I suppose.

    To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: master
    Gerrit-MessageType: comment
    Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
    Gerrit-Change-Number: 710454
    Gerrit-PatchSet: 2
    Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
    Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
    Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
    Gerrit-CC: Commit Bot <commi...@chromium.org>
    Gerrit-Comment-Date: Wed, 11 Oct 2017 21:02:33 +0000
    Gerrit-HasComments: Yes
    Gerrit-HasLabels: No

    Frank Liberato (Gerrit)

    unread,
    Oct 11, 2017, 6:31:50 PM10/11/17
    to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Commit Bot, chromium...@chromium.org

    sorry for the delay.

    at a high level, this seems like it's adding some very specific functionality to MediaCodecBridge, that might be specific to WebRTC. it also might affect the decoder cases, with all the changes to how output buffers are managed. at least, it's not immediately obvious to me that it doesn't. :)

    is there another option, like exposing the few things (is_config_frame), and handling all of it in a wrapper class? might even be a native wrapper class, since DequeueOutputInfo makes it that far and could be expanded to include whatever other fields you need to expose.

    thanks
    -fl

    View Change

      To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: chromium/src
      Gerrit-Branch: master
      Gerrit-MessageType: comment
      Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
      Gerrit-Change-Number: 710454
      Gerrit-PatchSet: 2
      Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
      Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
      Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
      Gerrit-CC: Commit Bot <commi...@chromium.org>
      Gerrit-Comment-Date: Wed, 11 Oct 2017 22:31:44 +0000
      Gerrit-HasComments: No
      Gerrit-HasLabels: No

      Weiyong Yao (Gerrit)

      unread,
      Oct 11, 2017, 7:46:32 PM10/11/17
      to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

      Patch Set 2:

      sorry for the delay.

      at a high level, this seems like it's adding some very specific functionality to MediaCodecBridge, that might be specific to WebRTC. it also might affect the decoder cases, with all the changes to how output buffers are managed. at least, it's not immediately obvious to me that it doesn't. :)

      is there another option, like exposing the few things (is_config_frame), and handling all of it in a wrapper class? might even be a native wrapper class, since DequeueOutputInfo makes it that far and could be expanded to include whatever other fields you need to expose.

      thanks
      -fl

      Yes I was bothered by the fact the MediaCodecBridge serves multiple functionalities too, video encoder/video decoder/audio decoder. I did think about to do the appending job in android_video_encode_accelerator.cc or media_codec_bridge_impl.cc. (Even I wanted to split the MediaCodecBridge.java into several files, which is not trivial though :) )
      But it's still a better idea to do the appending stuff in MediaCodecBridge.java.
      It's encoder's job to have SPS/PPS in IDR/Keyframe according to the spec, as all other H264 encoder implementations (SW/HW) on other platforms do, except MediaCodec on Android. So it's a more natural thinking to do the job in encoder implementation before outputting to native. Also people will realize this problem more easily by checking this java file, comparing with other encoder implementations.

      So I prefer to get it done in java level. The affection to decoding side is almost zero, expect dequeuing output into local buffers first.

      Please let me know if you have more concerns.


      View Change

        To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: chromium/src
        Gerrit-Branch: master
        Gerrit-MessageType: comment
        Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
        Gerrit-Change-Number: 710454
        Gerrit-PatchSet: 2
        Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
        Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
        Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
        Gerrit-CC: Commit Bot <commi...@chromium.org>
        Gerrit-Comment-Date: Wed, 11 Oct 2017 23:46:28 +0000
        Gerrit-HasComments: No
        Gerrit-HasLabels: No

        Frank Liberato (Gerrit)

        unread,
        Oct 11, 2017, 8:24:21 PM10/11/17
        to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Commit Bot, chromium...@chromium.org

        It's encoder's job to have SPS/PPS in IDR/Keyframe according to the spec

        have you opened a bug with android? if not, please consider doing so.

        if they do fix it in a future release of android, then this code gets more complicated -- we'll want to be able to turn this back off at runtime depending on the version.

        i'm fairly sure that we want to keep the java side as simple as possible, especially for the common case. if we start forcing MediaCodec to transfer decoded frames back to chrome, performance won't be so good.

        is it possible to subclass / wrap the java side just for the encoder? that might avoid much of the complexity you mention with the native side, but still keep the decoder path simple.

        WDYT?

        thanks
        -fl

        -fl

        View Change

        2 comments:

        • File media/base/android/java/src/org/chromium/media/MediaCodecBridge.java:

          • Patch Set #2, Line 528: codecOutputBuffer = getMediaCodecOutputBuffer(index);

            i'm not at all sure that this is safe for decoding. we usually connect MediaCodec to an Android Surface, and never touch the decoded data directly. we just move the index around.

            doing this might cause all sorts of copying of data. i base that on some work i did a year or so ago, where i tried to do something with the buffer data. that's more than just the copy that you're making explicitly below.

            plus, it's almost certainly not going to work as intended if this is a secure decoder (e.g., for protected content).

          • Patch Set #2, Line 555: frameBuffer.put(codecOutputBuffer);

            this can be an enormous amount of data.

        To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: chromium/src
        Gerrit-Branch: master
        Gerrit-MessageType: comment
        Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
        Gerrit-Change-Number: 710454
        Gerrit-PatchSet: 2
        Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
        Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
        Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
        Gerrit-CC: Commit Bot <commi...@chromium.org>
        Gerrit-Comment-Date: Thu, 12 Oct 2017 00:24:14 +0000
        Gerrit-HasComments: Yes
        Gerrit-HasLabels: No

        Weiyong Yao (Gerrit)

        unread,
        Oct 12, 2017, 12:58:23 PM10/12/17
        to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

        Patch Set 2:

        (2 comments)

        It's encoder's job to have SPS/PPS in IDR/Keyframe according to the spec

        have you opened a bug with android? if not, please consider doing so.

        if they do fix it in a future release of android, then this code gets more complicated -- we'll want to be able to turn this back off at runtime depending on the version.

        i'm fairly sure that we want to keep the java side as simple as possible, especially for the common case. if we start forcing MediaCodec to transfer decoded frames back to chrome, performance won't be so good.

        is it possible to subclass / wrap the java side just for the encoder? that might avoid much of the complexity you mention with the native side, but still keep the decoder path simple.

        WDYT?

        thanks
        -fl

        -fl

        Thanks so much for the comments!
        Totally agree with you. I'll see if I can move encoder part into a separate file in this cl. And if needed, split encoder and decode completely in a follow cl. WDYT?

        View Change

          To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: chromium/src
          Gerrit-Branch: master
          Gerrit-MessageType: comment
          Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
          Gerrit-Change-Number: 710454
          Gerrit-PatchSet: 2
          Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
          Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
          Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
          Gerrit-CC: Commit Bot <commi...@chromium.org>
          Gerrit-Comment-Date: Thu, 12 Oct 2017 16:58:06 +0000
          Gerrit-HasComments: No
          Gerrit-HasLabels: No

          Weiyong Yao (Gerrit)

          unread,
          Oct 13, 2017, 5:14:20 PM10/13/17
          to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

          Hi liberato@, please help to check if this is in the right direction.
          I subclass MediaCodecEncoder out of MedicaCodecBright and override several methods needed to restore H264 for webRTC.
          This can be a good base to make MediaCodecEncoder totally independent. If it's the plan, I can file an issue and start looking into it in a separate cl soon.

          View Change

            To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: chromium/src
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
            Gerrit-Change-Number: 710454
            Gerrit-PatchSet: 4
            Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
            Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
            Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
            Gerrit-CC: Commit Bot <commi...@chromium.org>
            Gerrit-Comment-Date: Fri, 13 Oct 2017 21:14:13 +0000
            Gerrit-HasComments: No
            Gerrit-HasLabels: No

            Frank Liberato (Gerrit)

            unread,
            Oct 13, 2017, 6:07:20 PM10/13/17
            to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Commit Bot, chromium...@chromium.org

            Patch Set 4:

            Hi liberato@, please help to check if this is in the right direction.

            thanks for taking the time with this. i think that it's moving in the right direction. there's quite a bit of duplicate code that can probably be shared between Bridge and Encoder.

            This can be a good base to make MediaCodecEncoder totally independent.

            i'm not sure that we want them to be independent. almost all of the encoder would be a duplicate of the decoder. MediaCodecBridge just needs to allow subclasses to override how buffers are handled, and let the subclass check for config frames.

            thanks
            -fl

            View Change

            3 comments:

            • File media/base/android/java/src/org/chromium/media/MediaCodecBridge.java:

            • File media/base/android/java/src/org/chromium/media/MediaCodecEncoder.java:

              • Patch Set #4, Line 42: private static class EncoderDequeueOutputResult extends DequeueOutputResult {

                why does this need to be subclassed?

              • Patch Set #4, Line 149:

                if (indexOrStatus >= 0) {
                boolean isConfigFrame = (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0;
                if (isConfigFrame) {
                Log.i(TAG,
                "Config frame generated. Offset: " + info.offset
                + ". Size: " + info.size);
                codecOutputBuffer = getMediaCodecOutputBuffer(indexOrStatus);
                codecOutputBuffer.position(info.offset);
                codecOutputBuffer.limit(info.offset + info.size);

                mConfigData = ByteBuffer.allocateDirect(info.size);
                mConfigData.put(codecOutputBuffer);
                // Log few SPS header bytes to check profile and level.
                StringBuilder spsData = new StringBuilder();
                for (int i = 0; i < (info.size < 8 ? info.size : 8); i++) {
                spsData.append(Integer.toHexString(mConfigData.get(i) & 0xff)).append(" ");
                }
                Log.i(TAG, spsData.toString());
                mConfigData.rewind();
                // Release buffer back.
                mMediaCodec.releaseOutputBuffer(indexOrStatus, false);
                // Query next output.
                indexOrStatus = mMediaCodec.dequeueOutputBuffer(info, timeoutUs);
                }
                }

                there's a lot of duplicated code here. would it be possible to make the encoder subclass much lighter?

                for example, we might have protected methods to handle just this part, that MediaCodecBridge.dequeueOutputBuffer calls. the default implementation in MediaCodecBridge would be empty. something like processConfigFrame(), that's called right after mMediaCodec.dequeueOutputBuffer if the index >= 0.

                the encoder subclass would do buffer management like it does now, as well.

                then the encoder is a very small class.

            To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: chromium/src
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
            Gerrit-Change-Number: 710454
            Gerrit-PatchSet: 4
            Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
            Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
            Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
            Gerrit-CC: Commit Bot <commi...@chromium.org>
            Gerrit-Comment-Date: Fri, 13 Oct 2017 22:07:14 +0000
            Gerrit-HasComments: Yes
            Gerrit-HasLabels: No

            Weiyong Yao (Gerrit)

            unread,
            Oct 17, 2017, 12:37:14 PM10/17/17
            to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

            I moved lots of codes in previous patch because I was still thinking about a separate encoder class. Since that's not the plan, the MediaCodecEncoder can be much lighter. Please take a look at the latest patch. Thanks!

            View Change

            3 comments:

              • "protected", to give access to subclasses but not others. here and elsewhere.

              • why does this need to be subclassed?

              • I was thinking about moving more codes into MediaCodecEncoder, for the proposed separation.
                Since we don't want to do it, there is no need to override this and dequeueOutputBuffer any more.

              • there's a lot of duplicated code here. […]

                Done

            To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: chromium/src
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
            Gerrit-Change-Number: 710454
            Gerrit-PatchSet: 6
            Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
            Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
            Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
            Gerrit-CC: Commit Bot <commi...@chromium.org>
            Gerrit-Comment-Date: Tue, 17 Oct 2017 16:37:04 +0000
            Gerrit-HasComments: Yes
            Gerrit-HasLabels: No

            Frank Liberato (Gerrit)

            unread,
            Oct 17, 2017, 5:04:19 PM10/17/17
            to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Commit Bot, chromium...@chromium.org

            this is coming along nicely. overall approach seems good.

            -fl

            View Change

            8 comments:


              • if (indexOrStatus >= 0) {
                boolean isConfigFrame = (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0;
                if (isConfigFrame) {

              •                     Log.d(TAG, "Config frame generated. Offset: %d, size: %d", info.offset,


              • info.size);
                codecOutputBuffer = getMediaCodecOutputBuffer(indexOrStatus);
                codecOutputBuffer.position(info.offset);
                codecOutputBuffer.limit(info.offset + info.size);

                mConfigData = ByteBuffer.allocateDirect(info.size);
                mConfigData.put(codecOutputBuffer);
                // Log few SPS header bytes to check profile and level.
                StringBuilder spsData = new StringBuilder();
                for (int i = 0; i < (info.size < 8 ? info.size : 8); i++) {
                spsData.append(Integer.toHexString(mConfigData.get(i) & 0xff)).append(" ");
                }

              •                     Log.i(TAG, "spsData: %s", spsData.toString());


              • mConfigData.rewind();
                // Release buffer back.
                mMediaCodec.releaseOutputBuffer(indexOrStatus, false);
                // Query next output.
                indexOrStatus = mMediaCodec.dequeueOutputBuffer(info, timeoutUs);
                }
                }

              •             if (indexOrStatus >= 0) {


              • codecOutputBuffer = getMediaCodecOutputBuffer(indexOrStatus);
                codecOutputBuffer.position(info.offset);
                codecOutputBuffer.limit(info.offset + info.size);

              •                 // Check key frame flag.
                boolean isKeyFrame = (info.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0;
                if (isKeyFrame) {
                Log.d(TAG, "Key frame generated");
                }
                final ByteBuffer frameBuffer;
                if (isKeyFrame && mMime.equals(MimeTypes.VIDEO_H264)) {
                Log.d(TAG, "Appending config frame of size %d to output buffer with size %d",
                mConfigData.capacity(), info.size);
                // For H.264 encoded key frame append SPS and PPS NALs at the start.
                frameBuffer = ByteBuffer.allocateDirect(mConfigData.capacity() + info.size);
                frameBuffer.put(mConfigData);
                info.offset = 0;
                info.size += mConfigData.capacity();
                } else {
                frameBuffer = ByteBuffer.allocateDirect(info.offset + info.size);
                frameBuffer.position(info.offset);
                }
                frameBuffer.put(codecOutputBuffer);
                frameBuffer.rewind();
                mOutputBuffers.put(indexOrStatus, frameBuffer.duplicate());
                }
                } catch (IllegalStateException e) {
                Log.e(TAG, "Failed to dequeue output buffer", e);
                }

                this could use a few more high-level comments.

              • Patch Set #6, Line 121: private ByteBuffer getMediaCodecOutputBuffer(int index) {

                is this different than "return super.getOutputBuffer(index)", maybe with a throw?

            To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: chromium/src
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
            Gerrit-Change-Number: 710454
            Gerrit-PatchSet: 6
            Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
            Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
            Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
            Gerrit-CC: Commit Bot <commi...@chromium.org>
            Gerrit-Comment-Date: Tue, 17 Oct 2017 21:04:14 +0000
            Gerrit-HasComments: Yes
            Gerrit-HasLabels: No

            Weiyong Yao (Gerrit)

            unread,
            Oct 18, 2017, 12:49:57 PM10/18/17
            to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

            All comments are addressed/answered. PTAL!

            View Change

            8 comments:

              • please add some detail about why.

              • please comment what this is.

              • can be moved to @25, or not.

              • should this also check for H264, so that it's not bothering to copy config frames that it won't use?

              • Done

              • Patch Set #6, Line 108: info.size += mConfigData.capacity();

                rather than doing the copy if it's not a keyframe or if it's not h264, could you just put codecOutpu […]

                Done

              • ected int dequeueOutputBufferInternal(MediaCodec.BufferInfo info, long timeoutUs) {
                int indexOrStatus = -1;



              • try {
                indexOrStatus = mMediaCodec.dequeueOutputBuffer(info, timeoutUs);

                ByteBuffer codecOutputBuffer = null;
                if (indexOrStatus >= 0) {
                boolean isConfigFrame = (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0;

              •                 if (isConfigFrame && mMime.equals(MimeTypes.VIDEO_H264)) {

              •                     frameBuffer.put(codecOutputBuffer);
                frameBuffer.rewind();


              • info.offset = 0;
                info.size += mConfigData.capacity();

              •                     mOutputBuffers.put(indexOrStatus, frameBuffer.duplicate());
                } else {
                mOutputBuffers.put(indexOrStatus, codecOutputBuffer.duplicate());
                }
                }
                }

              • this could use a few more high-level comments.

              • Done

              • Patch Set #6, Line 121: // Call this function with catching IllegalStateException.

                is this different than "return super. […]

                Done

            To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: chromium/src
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
            Gerrit-Change-Number: 710454
            Gerrit-PatchSet: 7
            Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
            Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
            Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
            Gerrit-CC: Commit Bot <commi...@chromium.org>
            Gerrit-Comment-Date: Wed, 18 Oct 2017 16:49:53 +0000
            Gerrit-HasComments: Yes
            Gerrit-HasLabels: No

            Frank Liberato (Gerrit)

            unread,
            Oct 18, 2017, 1:51:18 PM10/18/17
            to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Commit Bot, chromium...@chromium.org

            one other thing: is it possible to extend media_codec_bridge_unittest to include a test for this behavior? it already does something quite similar for decoding.

            thanks
            -fl

            View Change

            3 comments:

              • Not sure about this. Currently only H264 encoder is enabled on Android. […]

                that's a good question.

                as it's written, the subclass is specifically checking for H264 anyway. it's doing nothing functionally differently than MediaCodecBridge unless the format matches. i don't think there's an advantage to running the extra code for any other format given that those guards are there.

                i think that we should go all the way to one side or the other. my suggestion is to remove the format guards in the encoder subclass, and then either (a) instantiate the new encoder only for H264, or (b) instantiate the new encoder for all cases when we're encoding.

                i'll agree with whichever you think is the right thing to do. is it safe to "if we get a config frame, then prepend SPS/PPS"?

            • File media/base/android/java/src/org/chromium/media/MediaCodecEncoder.java:

              • Patch Set #7, Line 109: duplicate()

                since this is a new buffer that's not used anymore, i think that you don't need to duplicate() here.

                please note that i might misunderstand what duplicate() does, so i might simply be making bad suggestions. :)

              • Patch Set #7, Line 111: duplicate()

                what happens if one doesn't call duplicate()? this one seems more complicated than @109.

                is duplicate() just to provide a different "current offset" to two holders of the object, sharing the same underlying data?

            To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: chromium/src
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
            Gerrit-Change-Number: 710454
            Gerrit-PatchSet: 7
            Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
            Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
            Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
            Gerrit-CC: Commit Bot <commi...@chromium.org>
            Gerrit-Comment-Date: Wed, 18 Oct 2017 17:51:14 +0000
            Gerrit-HasComments: Yes
            Gerrit-HasLabels: No

            Weiyong Yao (Gerrit)

            unread,
            Oct 18, 2017, 5:39:18 PM10/18/17
            to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

            Thanks for the reminding! I only noticed there are test cases for audio decoding in media_codec_bridge_impl_unittest.cc in the past. Good to find the case for video decoding.
            I'm headache on how to add auto tests for HW H264 on Android now. Extending media_codec_bridge_impl_unittest.cc is a good start. Can I do it in a following cl (just filed https://crbug.com/776122 for it) soon?

            View Change

            3 comments:

              • since this is a new buffer that's not used anymore, i think that you don't need to duplicate() here. […]

                Done

                sorry, it's my misunderstanding to duplicate() here.

              • what happens if one doesn't call duplicate()? this one seems more complicated than @109. […]

                Done

            To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: chromium/src
            Gerrit-Branch: master
            Gerrit-MessageType: comment
            Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
            Gerrit-Change-Number: 710454
            Gerrit-PatchSet: 8
            Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
            Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
            Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
            Gerrit-CC: Commit Bot <commi...@chromium.org>
            Gerrit-Comment-Date: Wed, 18 Oct 2017 21:39:13 +0000
            Gerrit-HasComments: Yes
            Gerrit-HasLabels: No

            Frank Liberato (Gerrit)

            unread,
            Oct 18, 2017, 6:01:12 PM10/18/17
            to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Commit Bot, chromium...@chromium.org

            Can I do it in a following cl

            yes.

            lgtm.

            thanks
            -fl

            Patch set 8:Code-Review +1

            View Change

              To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: chromium/src
              Gerrit-Branch: master
              Gerrit-MessageType: comment
              Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
              Gerrit-Change-Number: 710454
              Gerrit-PatchSet: 8
              Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
              Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
              Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
              Gerrit-CC: Commit Bot <commi...@chromium.org>
              Gerrit-Comment-Date: Wed, 18 Oct 2017 22:01:07 +0000
              Gerrit-HasComments: No
              Gerrit-HasLabels: Yes

              Weiyong Yao (Gerrit)

              unread,
              Oct 18, 2017, 8:27:11 PM10/18/17
              to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

              Patch set 8:Commit-Queue +2

              View Change

                To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: chromium/src
                Gerrit-Branch: master
                Gerrit-MessageType: comment
                Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
                Gerrit-Change-Number: 710454
                Gerrit-PatchSet: 8
                Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
                Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
                Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
                Gerrit-CC: Commit Bot <commi...@chromium.org>
                Gerrit-Comment-Date: Thu, 19 Oct 2017 00:27:06 +0000
                Gerrit-HasComments: No
                Gerrit-HasLabels: Yes

                Commit Bot (Gerrit)

                unread,
                Oct 19, 2017, 2:10:44 AM10/19/17
                to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, chromium...@chromium.org
                Try jobs failed on following builders:
                win7_chromium_rel_ng on master.tryserver.chromium.win (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.win/builders/win7_chromium_rel_ng/builds/21777)

                View Change

                  To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-Project: chromium/src
                  Gerrit-Branch: master
                  Gerrit-MessageType: comment
                  Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
                  Gerrit-Change-Number: 710454
                  Gerrit-PatchSet: 8
                  Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
                  Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
                  Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
                  Gerrit-CC: Commit Bot <commi...@chromium.org>
                  Gerrit-Comment-Date: Thu, 19 Oct 2017 06:10:41 +0000
                  Gerrit-HasComments: No
                  Gerrit-HasLabels: No

                  Weiyong Yao (Gerrit)

                  unread,
                  Oct 20, 2017, 12:23:22 PM10/20/17
                  to avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, Commit Bot, chromium...@chromium.org

                  Patch set 8:Commit-Queue +2

                  View Change

                    To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

                    Gerrit-Project: chromium/src
                    Gerrit-Branch: master
                    Gerrit-MessageType: comment
                    Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
                    Gerrit-Change-Number: 710454
                    Gerrit-PatchSet: 8
                    Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
                    Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
                    Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
                    Gerrit-CC: Commit Bot <commi...@chromium.org>
                    Gerrit-Comment-Date: Fri, 20 Oct 2017 16:23:18 +0000
                    Gerrit-HasComments: No
                    Gerrit-HasLabels: Yes

                    Commit Bot (Gerrit)

                    unread,
                    Oct 20, 2017, 12:28:35 PM10/20/17
                    to Weiyong Yao, avayvo...@chromium.org, feature-me...@chromium.org, mlamouri+w...@chromium.org, Frank Liberato, chromium...@chromium.org

                    Commit Bot merged this change.

                    View Change

                    Approvals: Frank Liberato: Looks good to me Weiyong Yao: Commit
                    Android HW H264: append SPS/PPS at the start of key frame

                    Android MediaCodec will generate a seperate config frame containing
                    SPS/PPS at beginning of encoding H264 stream and the following key
                    frames won't have SPS/PPS any more, while other SW/HW H264 encoder
                    implementations will generate key frames with SPS/PPS always.
                    Recently WebRTC requires the H264 IDR/keyframe to contain SPS/PPS to
                    start decoder. Then the H264 intercommunication is broken between
                    Android and other platforms.

                    To fix this, append SPS/PPS at the start of H264 keyframe on Android.

                    Bug: 761336
                    Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
                    Reviewed-on: https://chromium-review.googlesource.com/710454
                    Reviewed-by: Frank Liberato <libe...@chromium.org>
                    Commit-Queue: Weiyong Yao <brav...@chromium.org>
                    Cr-Commit-Position: refs/heads/master@{#510459}
                    ---
                    M media/base/android/BUILD.gn
                    M media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
                    A media/base/android/java/src/org/chromium/media/MediaCodecEncoder.java
                    3 files changed, 150 insertions(+), 8 deletions(-)


                    To view, visit change 710454. To unsubscribe, or for help writing mail filters, visit settings.

                    Gerrit-Project: chromium/src
                    Gerrit-Branch: master
                    Gerrit-MessageType: merged
                    Gerrit-Change-Id: Ifb6b27f4448186dc4d7411921c556cf57d74068e
                    Gerrit-Change-Number: 710454
                    Gerrit-PatchSet: 9
                    Gerrit-Owner: Weiyong Yao <brav...@chromium.org>
                    Gerrit-Reviewer: Commit Bot <commi...@chromium.org>
                    Gerrit-Reviewer: Frank Liberato <libe...@chromium.org>
                    Gerrit-Reviewer: Weiyong Yao <brav...@chromium.org>
                    Reply all
                    Reply to author
                    Forward
                    0 new messages