// H.264 bitstream without start codes.
sp<MetaData> setAVCFormat(AVCodecContext *avctx)
{
    ALOGV("AVC");

	CHECK_EQ(avctx->codec_id, AV_CODEC_ID_H264);
	CHECK_GT(avctx->extradata_size, 0);
	CHECK_EQ(avctx->extradata[0], 1); //configurationVersion

    if (avctx->width == 0 || avctx->height == 0) {
         int32_t width, height;
         sp<ABuffer> seqParamSet = new ABuffer(avctx->extradata_size - 8);
         memcpy(seqParamSet->data(), avctx->extradata + 8, avctx->extradata_size - 8);
         FindAVCDimensions(seqParamSet, &width, &height);
         avctx->width  = width;
         avctx->height = height;
     }

    sp<MetaData> meta = new MetaData;
    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
    meta->setData(kKeyAVCC, kTypeAVCC, avctx->extradata, avctx->extradata_size);

	return meta;
}
sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
    const uint8_t *data = accessUnit->data();
    size_t size = accessUnit->size();

    sp<ABuffer> seqParamSet = FindNAL(data, size, 7, NULL);
    if (seqParamSet == NULL) {
        return NULL;
    }

    int32_t width, height;
    FindAVCDimensions(seqParamSet, &width, &height);

    size_t stopOffset;
    sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset);
    CHECK(picParamSet != NULL);

    size_t csdSize =
        1 + 3 + 1 + 1
        + 2 * 1 + seqParamSet->size()
        + 1 + 2 * 1 + picParamSet->size();

    sp<ABuffer> csd = new ABuffer(csdSize);
    uint8_t *out = csd->data();

    *out++ = 0x01;  // configurationVersion
    memcpy(out, seqParamSet->data() + 1, 3);  // profile/level...

    uint8_t profile = out[0];
    uint8_t level = out[2];

    out += 3;
    *out++ = (0x3f << 2) | 1;  // lengthSize == 2 bytes
    *out++ = 0xe0 | 1;

    *out++ = seqParamSet->size() >> 8;
    *out++ = seqParamSet->size() & 0xff;
    memcpy(out, seqParamSet->data(), seqParamSet->size());
    out += seqParamSet->size();

    *out++ = 1;

    *out++ = picParamSet->size() >> 8;
    *out++ = picParamSet->size() & 0xff;
    memcpy(out, picParamSet->data(), picParamSet->size());

#if 0
    LOGI("AVC seq param set");
    hexdump(seqParamSet->data(), seqParamSet->size());
#endif

    sp<MetaData> meta = new MetaData;
    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);

    meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
    meta->setInt32(kKeyWidth, width);
    meta->setInt32(kKeyHeight, height);

    LOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)",
         width, height, AVCProfileToString(profile), level / 10, level % 10);

    return meta;
}
Пример #3
0
sp<ABuffer> MakeAVCCodecSpecificData(
        const sp<ABuffer> &accessUnit, int32_t *width, int32_t *height,
        int32_t *sarWidth, int32_t *sarHeight) {
    const uint8_t *data = accessUnit->data();
    size_t size = accessUnit->size();

    sp<ABuffer> seqParamSet = FindNAL(data, size, 7);
    if (seqParamSet == NULL) {
        return NULL;
    }

    FindAVCDimensions(
            seqParamSet, width, height, sarWidth, sarHeight);

    sp<ABuffer> picParamSet = FindNAL(data, size, 8);
    CHECK(picParamSet != NULL);

    size_t csdSize =
        1 + 3 + 1 + 1
        + 2 * 1 + seqParamSet->size()
        + 1 + 2 * 1 + picParamSet->size();

    sp<ABuffer> csd = new ABuffer(csdSize);
    uint8_t *out = csd->data();

    *out++ = 0x01;  // configurationVersion
    memcpy(out, seqParamSet->data() + 1, 3);  // profile/level...

    uint8_t profile = out[0];
    uint8_t level = out[2];

    out += 3;
    *out++ = (0x3f << 2) | 1;  // lengthSize == 2 bytes
    *out++ = 0xe0 | 1;

    *out++ = seqParamSet->size() >> 8;
    *out++ = seqParamSet->size() & 0xff;
    memcpy(out, seqParamSet->data(), seqParamSet->size());
    out += seqParamSet->size();

    *out++ = 1;

    *out++ = picParamSet->size() >> 8;
    *out++ = picParamSet->size() & 0xff;
    memcpy(out, picParamSet->data(), picParamSet->size());

#if 0
    ALOGI("AVC seq param set");
    hexdump(seqParamSet->data(), seqParamSet->size());
#endif


    if (sarWidth != nullptr && sarHeight != nullptr) {
        if ((*sarWidth > 0 && *sarHeight > 0) && (*sarWidth != 1 || *sarHeight != 1)) {
            ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d) "
                    "SAR %d : %d",
                    *width,
                    *height,
                    AVCProfileToString(profile),
                    level / 10,
                    level % 10,
                    *sarWidth,
                    *sarHeight);
        } else {
            // We treat *:0 and 0:* (unspecified) as 1:1.
            *sarWidth = 0;
            *sarHeight = 0;
            ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)",
                    *width,
                    *height,
                    AVCProfileToString(profile),
                    level / 10,
                    level % 10);
        }
    }

    return csd;
}