player_type AmSuperPlayer::SuperGetPlayerType(char *type,int videos,int audios) { int ret; char value[PROPERTY_VALUE_MAX]; bool amplayer_enabed=PropIsEnable("media.amplayer.enable"); if(amplayer_enabed && type!=NULL) { bool audio_all,no_audiofile; if(audios==0 && videos==0){ /*parser get type but have not finised get videos and audios*/ if(match_codecs(type,"mpeg,mpegts,rtsp"))/*some can't parser stream info in header parser*/ return AMLOGIC_PLAYER; } if (match_codecs(type, "webm,vp8,vp6")) return STAGEFRIGHT_PLAYER; if(videos>0) return AMLOGIC_PLAYER; audio_all=PropIsEnable("media.amplayer.audio-all"); if(audios>0 && audio_all ) return AMLOGIC_PLAYER; ret=property_get("media.amplayer.enable-acodecs",value,NULL); if(ret>0 && match_codecs(type,value)){ return AMLOGIC_PLAYER; } } if(match_codecs(type,"midi,mmf,mdi")) return SONIVOX_PLAYER; if(match_codecs(type,"m4a")) { ret=property_get("media.amsuperplayer.m4aplayer",value,NULL); if (ret>0) { LOGI("media.amsuperplayer.m4aplayer=%s\n",value); return Str2PlayerType(value); } } if (PropIsEnable("media.stagefright.enable-player")) { return STAGEFRIGHT_PLAYER; } return STAGEFRIGHT_PLAYER; }
/** * performs the following operations at 200 OK time (early neg <-> late neg): * * - alters the callee's 200 OK message (adds the final decided codec) * - alters the caller's SDP (in memory), so it can be attached @ ACK * - opens transcoding sessions on the card if necessary * * Note: assumes all streams are on corresponding positions in both SDPs */ static int process_session(struct sip_msg *msg, struct sngtc_info *info, str *src, str *dst, struct sdp_session_cell *s1, struct sdp_session_cell *s2) { struct sdp_stream_cell *sm1, *sm2; struct sngtc_session_list *tc_session; struct sngtc_codec_request request; struct sngtc_codec_reply *reply = NULL; struct codec_pair pair; struct lump *lump, *nl; struct in_addr addr; int rc = 0, ret, tc_on = 0; int idx; char buf[INET_ADDRSTRLEN]; str repl; if (s1->next && s2->next) rc = process_session(msg, info, src, dst, s1->next, s2->next); else if (s1->next || s2->next) LM_ERR("endpoints have a different number of SDP sessions" " - choosing min number\n"); if (rc != 0) goto out; tc_session = info->sessions; for (idx = MAX_STREAMS - 1, sm1 = s1->streams, sm2 = s2->streams; sm1 && sm2; sm1 = sm1->next, sm2 = sm2->next, idx--) { ret = match_codecs(sm1, sm2, &pair); codec_matches[idx] = pair; switch (ret) { case SNGTC_OFF: LM_DBG("NO NEED FOR TRANSCODING\n"); /* delete codecs from 200 OK; write endpoint A codec */ /* ip and port stay the same */ lump = remove_sdp_stream_attrs(msg, sm2); if (!lump) { LM_ERR("failed to clear sdp codecs\n"); return SNGTC_SDP_ERR; } LM_DBG("sdp stream:\n"); print_sdp_stream(sm2, L_DBG); ret = write_sdp_stream_attr(msg, lump, pair.att2, NULL); if (ret != 0) { LM_ERR("failed to write sdp stream codec\n"); return ret; } break; case SNGTC_ON: tc_on = 1; if (is_processed(info)) goto use_existing_sessions; LM_DBG("TRANSCODING ([%d] %.*s:%.*s <--> [%d] %.*s:%.*s)\n", pair.tc1, s1->ip_addr.len, s1->ip_addr.s, sm1->port.len, sm1->port.s, pair.tc2, s2->ip_addr.len, s2->ip_addr.s, sm2->port.len, sm2->port.s); memset(&request, 0, sizeof(request)); request.usr_priv = NULL; /* Codec, ms, IP and port for side A */ request.a.codec_id = pair.tc1; request.a.ms = 0; sprintf(buf, "%.*s", s1->ip_addr.len, s1->ip_addr.s); ret = inet_pton(AF_INET, buf, &addr); if (ret != 1) { LM_ERR("failed to convert ip %s to binary form (%d)\n", s1->ip_addr.s, ret); return SNGTC_ERR; } request.a.host_ip = htonl(addr.s_addr); request.a.host_netmask = (unsigned int)-1; if (str2int(&sm1->port, &request.a.host_udp_port) != 0) LM_ERR("Failed to parse integer stored in port str '%.*s'\n", sm1->port.len, sm1->port.s); /* Codec, ms, IP and port for side B */ request.b.codec_id = pair.tc2; request.b.ms = 0; sprintf(buf, "%.*s", s2->ip_addr.len, s2->ip_addr.s); ret = inet_pton(AF_INET, buf, &addr); if (ret != 1) { LM_ERR("failed to convert ip %.*s to binary form (%d)\n", s2->ip_addr.len, s2->ip_addr.s, ret); return SNGTC_ERR; } request.b.host_ip = htonl(addr.s_addr); request.b.host_netmask = (unsigned int)-1; if (str2int(&sm2->port, &request.b.host_udp_port) != 0) LM_ERR("Failed to parse integer stored in port str '%.*s'\n", sm2->port.len, sm2->port.s); LM_DBG("Transcoding request: %d:%d <--> %d:%d\n", request.a.host_ip, request.a.host_udp_port, request.b.host_ip, request.b.host_udp_port); reply = create_transcoding_session(&request, info); if (!reply) { LM_ERR("Failed to create a transcoding session on the card\n"); return SNGTC_TC_ERR; } use_existing_sessions: LM_DBG("NEW TC SESSION!\n"); if (is_processed(info)) { reply = tc_session->reply; tc_session = tc_session->next; } codec_matches[idx].reply = reply; /** * delete codecs from 200 OK * write the common codec * replace IP with ip of Sangoma card * replace port with endpoint A newly opened port on card */ lump = remove_sdp_stream_attrs(msg, sm2); if (!lump) { LM_ERR("failed to clear sdp codecs\n"); return SNGTC_SDP_ERR; } nl = del_lump(msg, s2->ip_addr.s - msg->buf, s2->ip_addr.len, 0); if (!nl) { LM_ERR("failed to add del lump\n"); return SNGTC_ERR; } if (pkg_str_dup(&repl, &card_ip_b) != 0) { LM_ERR("failed to dup in pkg mem\n"); return SNGTC_ERR; } if (!insert_new_lump_after(nl, repl.s, repl.len, HDR_OTHER_T)) { LM_ERR("failed to insert lump with codec result\n"); return SNGTC_ERR; } if (replace_sdp_stream_port(msg, sm2, reply->a.codec_udp_port) != 0) { LM_ERR("failed to rewrite sdp stream port\n"); return SNGTC_ERR; } if (write_sdp_stream_attr(msg, lump, pair.att1, reply) != 0) { LM_ERR("failed to write sdp stream codecs\n"); return SNGTC_ERR; } break; case SNGTC_UNSUP_CODECS: LM_ERR("endpoints have no common codecs and at least one side " "contains only unsupported Sangoma codecs\n"); LM_ERR("caller:\n"); print_sdp_stream(sm1, L_ERR); LM_ERR("callee:\n"); print_sdp_stream(sm2, L_ERR); return SNGTC_SDP_ERR; case SNGTC_BAD_SDP: LM_ERR("received bogus sdp with no attributes\n"); LM_ERR("caller:\n"); print_sdp_stream(sm1, L_ERR); LM_ERR("callee:\n"); print_sdp_stream(sm2, L_ERR); return SNGTC_SDP_ERR; } } if (tc_on) { LM_DBG("transcoding: ON\n"); memcpy(dst->s + dst->len, src->s, s1->ip_addr.s - src->s); dst->len += s1->ip_addr.s - src->s; dst->len += sprintf(dst->s + dst->len, "%.*s", card_ip_a.len, card_ip_a.s); src->s += s1->ip_addr.s - src->s + s1->ip_addr.len; } else LM_DBG("transcoding: OFF\n"); rc |= process_stream(s1->streams, s2->streams, src, dst, MAX_STREAMS - 1); out: return rc; }