Bug 1003712: Codec availability support and prioritization r=ehugg

This commit is contained in:
Randell Jesup 2014-06-04 14:52:32 -04:00
parent 0e3d803a91
commit a520439607
6 changed files with 110 additions and 36 deletions

View File

@ -7,6 +7,7 @@
#define OMXCodecWrapper_h_
#include <gui/Surface.h>
#include <utils/RefBase.h>
#include <stagefright/foundation/ABuffer.h>
#include <stagefright/foundation/AMessage.h>
#include <stagefright/MediaCodec.h>

View File

@ -43,6 +43,7 @@
#ifdef MOZ_WEBRTC_OMX
#include "OMXVideoCodec.h"
#include "OMXCodecWrapper.h"
#endif
extern "C" {
@ -88,6 +89,7 @@ using namespace CSF;
VcmSIPCCBinding * VcmSIPCCBinding::gSelf = nullptr;
int VcmSIPCCBinding::gAudioCodecMask = 0;
int VcmSIPCCBinding::gVideoCodecMask = 0;
int VcmSIPCCBinding::gVideoCodecGmpMask = 0;
nsIThread *VcmSIPCCBinding::gMainThread = nullptr;
nsIEventTarget *VcmSIPCCBinding::gSTSThread = nullptr;
nsCOMPtr<nsIPrefBranch> VcmSIPCCBinding::gBranch = nullptr;
@ -224,6 +226,12 @@ void VcmSIPCCBinding::setVideoCodecs(int codecMask)
VcmSIPCCBinding::gVideoCodecMask = codecMask;
}
void VcmSIPCCBinding::addVideoCodecsGmp(int codecMask)
{
CSFLogDebug(logTag, "ADDING VIDEO: %d", codecMask);
VcmSIPCCBinding::gVideoCodecGmpMask |= codecMask;
}
int VcmSIPCCBinding::getAudioCodecs()
{
return VcmSIPCCBinding::gAudioCodecMask;
@ -234,6 +242,35 @@ int VcmSIPCCBinding::getVideoCodecs()
return VcmSIPCCBinding::gVideoCodecMask;
}
int VcmSIPCCBinding::getVideoCodecsGmp()
{
return VcmSIPCCBinding::gVideoCodecGmpMask;
}
int VcmSIPCCBinding::getVideoCodecsHw()
{
// Check to see if what HW codecs are available (not in use) at this moment.
// Note that streaming video decode can reserve a decoder
// XXX See bug 1018791 Implement W3 codec reservation policy
// Note that currently, OMXCodecReservation needs to be held by an sp<> because it puts
// 'this' into an sp<EventListener> to talk to the resource reservation code
#ifdef MOZ_WEBRTC_OMX
android::sp<android::OMXCodecReservation> encode = new android::OMXCodecReservation(true);
android::sp<android::OMXCodecReservation> decode = new android::OMXCodecReservation(false);
// Currently we just check if they're available right now, which will fail if we're
// trying to call ourself, for example. It will work for most real-world cases, like
// if we try to add a person to a 2-way call to make a 3-way mesh call
if (encode->ReserveOMXCodec() && decode->ReserveOMXCodec()) {
CSFLogDebug( logTag, "%s: H264 hardware codec available", __FUNCTION__);
return VCM_CODEC_RESOURCE_H264;
}
#endif
return 0;
}
void VcmSIPCCBinding::setMainThread(nsIThread *thread)
{
gMainThread = thread;
@ -2727,9 +2764,26 @@ int vcmGetVideoCodecList(int request_type)
//return codecMask;
return VCM_CODEC_RESOURCE_H264;
#else
int codecMask = VcmSIPCCBinding::getVideoCodecs();
CSFLogDebug(logTag, "GetVideoCodecList returning %X", codecMask);
// Control if H264 is available and priority:
// If hardware codecs are available (VP8 or H264), use those as a preferred codec
// (question: on all platforms?)
// If OpenH264 is available, use that at lower priority to VP8
// (question: platform software or OS-unknown-impl codecs? (Win8.x, etc)
// Else just use VP8 software
int codecMask;
switch (request_type) {
case VCM_DSP_FULLDUPLEX_HW:
codecMask = VcmSIPCCBinding::getVideoCodecsHw();
break;
case VCM_DSP_FULLDUPLEX_GMP:
codecMask = VcmSIPCCBinding::getVideoCodecsGmp();
break;
default: // VCM_DSP_FULLDUPLEX
codecMask = VcmSIPCCBinding::getVideoCodecs();
break;
}
CSFLogDebug(logTag, "GetVideoCodecList returning %X", codecMask);
return codecMask;
#endif
}

View File

@ -58,9 +58,12 @@ namespace CSF
static void setAudioCodecs(int codecMask);
static void setVideoCodecs(int codecMask);
static void addVideoCodecsGmp(int codecMask);
static int getAudioCodecs();
static int getVideoCodecs();
static int getVideoCodecsGmp();
static int getVideoCodecsHw();
static void setMainThread(nsIThread *thread);
static nsIThread *getMainThread();
@ -81,6 +84,7 @@ namespace CSF
MediaProviderObserver *mediaProviderObserver;
static int gAudioCodecMask;
static int gVideoCodecMask;
static int gVideoCodecGmpMask;
static nsIThread *gMainThread;
static nsIEventTarget *gSTSThread;
static nsCOMPtr<nsIPrefBranch> gBranch;

View File

@ -593,6 +593,33 @@ config_get_video_max_fr(const rtp_ptype codec)
return 0;
}
uint16_t
sip_config_video_add_codecs (rtp_ptype aSupportedCodecs[],
uint16_t supportedCodecsLen,
uint16_t codec_mask)
{
uint16_t count = 0;
// All things being equal, prefer VP8 > H.264 p1 > H.264 p0 -> H.263
if ( codec_mask & VCM_CODEC_RESOURCE_VP8) {
aSupportedCodecs[count] = RTP_VP8;
count++;
}
if ( codec_mask & VCM_CODEC_RESOURCE_H264) {
if (vcmGetVideoMaxSupportedPacketizationMode() == 1) {
aSupportedCodecs[count] = RTP_H264_P1;
count++;
}
aSupportedCodecs[count] = RTP_H264_P0;
count++;
}
if ( codec_mask & VCM_CODEC_RESOURCE_H263) {
aSupportedCodecs[count] = RTP_H263;
count++;
}
return count;
}
/*
* sip_config_local_supported_codecs_get()
*
@ -604,6 +631,8 @@ sip_config_video_supported_codecs_get (rtp_ptype aSupportedCodecs[],
{
uint16_t count = 0;
int codec_mask;
int hw_codec_mask = vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX_HW);
int gmp_codec_mask = vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX_GMP);
if ( isOffer ) {
codec_mask = vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX);
@ -613,38 +642,17 @@ sip_config_video_supported_codecs_get (rtp_ptype aSupportedCodecs[],
//codec_mask = vcmGetVideoCodecList(DSP_ENCODEONLY);
codec_mask = vcmGetVideoCodecList(VCM_DSP_IGNORE);
}
#ifdef WEBRTC_GONK
if ( codec_mask & VCM_CODEC_RESOURCE_H264) {
if (vcmGetVideoMaxSupportedPacketizationMode() == 1) {
aSupportedCodecs[count] = RTP_H264_P1;
count++;
}
aSupportedCodecs[count] = RTP_H264_P0;
count++;
}
if ( codec_mask & VCM_CODEC_RESOURCE_VP8) {
aSupportedCodecs[count] = RTP_VP8;
count++;
}
#else
// Apply video codecs with VP8 first on non gonk
if ( codec_mask & VCM_CODEC_RESOURCE_VP8) {
aSupportedCodecs[count] = RTP_VP8;
count++;
}
if ( codec_mask & VCM_CODEC_RESOURCE_H264) {
if (vcmGetVideoMaxSupportedPacketizationMode() == 1) {
aSupportedCodecs[count] = RTP_H264_P1;
count++;
}
aSupportedCodecs[count] = RTP_H264_P0;
count++;
}
#endif
if ( codec_mask & VCM_CODEC_RESOURCE_H263) {
aSupportedCodecs[count] = RTP_H263;
count++;
}
// prefer HW codecs over SW
count = sip_config_video_add_codecs(aSupportedCodecs,
supportedCodecsLen, hw_codec_mask);
// Now add any codecs that weren't in the initial list
codec_mask &= ~hw_codec_mask;
count += sip_config_video_add_codecs(&aSupportedCodecs[count],
supportedCodecsLen, codec_mask);
// Now add any GMP codecs that aren't already in
gmp_codec_mask &= ~(hw_codec_mask | codec_mask);
count += sip_config_video_add_codecs(&aSupportedCodecs[count],
supportedCodecsLen, gmp_codec_mask);
return count;
}

View File

@ -63,6 +63,8 @@
#define VCM_DSP_ENCODEONLY 1
#define VCM_DSP_FULLDUPLEX 2
#define VCM_DSP_IGNORE 3
#define VCM_DSP_FULLDUPLEX_HW 4 // HW codecs
#define VCM_DSP_FULLDUPLEX_GMP 5 // GMP-loaded codecs
#define CC_KFACTOR_STAT_LEN (256)

View File

@ -558,6 +558,11 @@ bool VCMCodecDataBase::SupportsRenderScheduling() const {
if (current_dec_is_external_) {
const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem(
receive_codec_.plType);
if (!ext_item) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding, VCMId(id_),
"Unknown payload type: %u", receive_codec_.plType);
return false;
}
render_timing = ext_item->internal_render_timing;
}
return render_timing;