// libtheora won't read the entire buffer we give it at once, so we have to // repeatedly submit it... static int submit_stats(AVCodecContext *avctx) { #ifdef TH_ENCCTL_2PASS_IN TheoraContext *h = avctx->priv_data; int bytes; if (!h->stats) { if (!avctx->stats_in) { av_log(avctx, AV_LOG_ERROR, "No statsfile for second pass\n"); return -1; } h->stats_size = strlen(avctx->stats_in) * 3/4; h->stats = av_malloc(h->stats_size); h->stats_size = av_base64_decode(h->stats, avctx->stats_in, h->stats_size); } while (h->stats_size - h->stats_offset > 0) { bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_IN, h->stats + h->stats_offset, h->stats_size - h->stats_offset); if (bytes < 0) { av_log(avctx, AV_LOG_ERROR, "Error submitting stats\n"); return -1; } if (!bytes) return 0; h->stats_offset += bytes; } return 0; #else av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n"); return -1; #endif }
int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) { int ret = 0; if (av_strstart(p, "pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,", &p)) { AVIOContext pb; RTSPState *rt = s->priv_data; AVDictionary *opts = NULL; int len = strlen(p) * 6 / 8; char *buf = av_mallocz(len); av_base64_decode(buf, p, len); if (rtp_asf_fix_header(buf, len) < 0) av_log(s, AV_LOG_ERROR, "Failed to fix invalid RTSP-MS/ASF min_pktsize\n"); init_packetizer(&pb, buf, len); if (rt->asf_ctx) { avformat_close_input(&rt->asf_ctx); } if (!(rt->asf_ctx = avformat_alloc_context())) return AVERROR(ENOMEM); rt->asf_ctx->pb = &pb; av_dict_set(&opts, "no_resync_search", "1", 0); ret = avformat_open_input(&rt->asf_ctx, "", &ff_asf_demuxer, &opts); av_dict_free(&opts); if (ret < 0) return ret; av_dict_copy(&s->metadata, rt->asf_ctx->metadata, 0); rt->asf_pb_pos = avio_tell(&pb); av_free(buf); rt->asf_ctx->pb = NULL; } return ret; }
int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) { int ret = 0; if (av_strstart(p, "pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,", &p)) { ByteIOContext pb; RTSPState *rt = s->priv_data; int len = strlen(p) * 6 / 8; char *buf = av_mallocz(len); av_base64_decode(buf, p, len); if (rtp_asf_fix_header(buf, len) < 0) av_log(s, AV_LOG_ERROR, "Failed to fix invalid RTSP-MS/ASF min_pktsize\n"); init_packetizer(&pb, buf, len); if (rt->asf_ctx) { av_close_input_stream(rt->asf_ctx); rt->asf_ctx = NULL; } ret = av_open_input_stream(&rt->asf_ctx, &pb, "", &asf_demuxer, NULL); if (ret < 0) return ret; av_metadata_copy(&s->metadata, rt->asf_ctx->metadata, 0); rt->asf_pb_pos = url_ftell(&pb); av_free(buf); rt->asf_ctx->pb = NULL; } return ret; }
static av_cold int data_open(URLContext *h, const char *uri, int flags) { DataContext *dc = h->priv_data; const char *data, *opt, *next; char *ddata; int ret, base64 = 0; size_t in_size; /* data:content/type[;base64],payload */ av_strstart(uri, "data:", &uri); data = strchr(uri, ','); if (!data) { av_log(h, AV_LOG_ERROR, "No ',' delimiter in URI\n"); return AVERROR(EINVAL); } opt = uri; while (opt < data) { next = av_x_if_null(memchr(opt, ';', data - opt), data); if (opt == uri) { if (!memchr(opt, '/', next - opt)) { /* basic validity check */ av_log(h, AV_LOG_ERROR, "Invalid content-type '%.*s'\n", (int)(next - opt), opt); return AVERROR(EINVAL); } av_log(h, AV_LOG_VERBOSE, "Content-type: %.*s\n", (int)(next - opt), opt); } else { if (!av_strncasecmp(opt, "base64", next - opt)) { base64 = 1; } else { av_log(h, AV_LOG_VERBOSE, "Ignoring option '%.*s'\n", (int)(next - opt), opt); } } opt = next + 1; } data++; in_size = strlen(data); if (base64) { size_t out_size = 3 * (in_size / 4) + 1; if (out_size > INT_MAX || !(ddata = av_malloc(out_size))) return AVERROR(ENOMEM); if ((ret = av_base64_decode(ddata, data, out_size)) < 0) { av_free(ddata); av_log(h, AV_LOG_ERROR, "Invalid base64 in URI\n"); return ret; } dc->data = dc->tofree = ddata; dc->size = ret; } else { dc->data = data; dc->size = in_size; } return 0; }
static unsigned char * rdt_parse_b64buf (unsigned int *target_len, const char *p) { unsigned char *target; int len = strlen(p); if (*p == '\"') { p++; len -= 2; /* skip embracing " at start/end */ } *target_len = len * 3 / 4; target = av_mallocz(*target_len + FF_INPUT_BUFFER_PADDING_SIZE); av_base64_decode(target, p, *target_len); return target; }
int ff_h264_parse_sprop_parameter_sets(AVFormatContext *s, uint8_t **data_ptr, int *size_ptr, const char *value) { char base64packet[1024]; uint8_t decoded_packet[1024]; int packet_size; while (*value) { char *dst = base64packet; while (*value && *value != ',' && (dst - base64packet) < sizeof(base64packet) - 1) { *dst++ = *value++; } *dst++ = '\0'; if (*value == ',') value++; packet_size = av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet)); if (packet_size > 0) { uint8_t *dest = av_realloc(*data_ptr, packet_size + sizeof(start_sequence) + *size_ptr + AV_INPUT_BUFFER_PADDING_SIZE); if (!dest) { av_log(s, AV_LOG_ERROR, "Unable to allocate memory for extradata!\n"); return AVERROR(ENOMEM); } *data_ptr = dest; memcpy(dest + *size_ptr, start_sequence, sizeof(start_sequence)); memcpy(dest + *size_ptr + sizeof(start_sequence), decoded_packet, packet_size); memset(dest + *size_ptr + sizeof(start_sequence) + packet_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); *size_ptr += sizeof(start_sequence) + packet_size; } } return 0; }
int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite, const char *params) { uint8_t buf[30]; ff_srtp_free(s); // RFC 4568 if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80") || !strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_80")) { s->rtp_hmac_size = s->rtcp_hmac_size = 10; } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) { s->rtp_hmac_size = s->rtcp_hmac_size = 4; } else if (!strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_32")) { // RFC 5764 section 4.1.2 s->rtp_hmac_size = 4; s->rtcp_hmac_size = 10; } else { av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n", suite); return AVERROR(EINVAL); } if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) { av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n"); return AVERROR(EINVAL); } // MKI and lifetime not handled yet s->aes = av_aes_alloc(); s->hmac = av_hmac_alloc(AV_HMAC_SHA1); if (!s->aes || !s->hmac) return AVERROR(ENOMEM); memcpy(s->master_key, buf, 16); memcpy(s->master_salt, buf + 16, 14); // RFC 3711 av_aes_init(s->aes, s->master_key, 128, 0); derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key)); derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt)); derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth)); derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key)); derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt)); derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth)); return 0; }
// Copied from vlc static unsigned char* parseH264ConfigStr( char const* configStr, unsigned int& configSize ) { char *dup, *psz; int i, i_records = 1; if( configSize ) configSize = 0; if( configStr == NULL || *configStr == '\0' ) return NULL; psz = dup = strdup( configStr ); /* Count the number of comma's */ for( psz = dup; *psz != '\0'; ++psz ) { if( *psz == ',') { ++i_records; *psz = '\0'; } } unsigned char *cfg = new unsigned char[5 * strlen(dup)]; psz = dup; for( i = 0; i < i_records; i++ ) { cfg[configSize++] = 0x00; cfg[configSize++] = 0x00; cfg[configSize++] = 0x01; configSize += av_base64_decode( (uint8_t*)&cfg[configSize], psz, 5 * strlen(dup) - 3 ); psz += strlen(psz)+1; } if( dup ) free( dup ); return cfg; }
/* ---------------- private code */ static int sdp_parse_fmtp_config_h264(AVStream * stream, PayloadContext * h264_data, char *attr, char *value) { AVCodecContext *codec = stream->codec; assert(codec->codec_id == CODEC_ID_H264); assert(h264_data != NULL); if (!strcmp(attr, "packetization-mode")) { av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value)); h264_data->packetization_mode = atoi(value); /* Packetization Mode: 0 or not present: Single NAL mode (Only nals from 1-23 are allowed) 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed. 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed. */ if (h264_data->packetization_mode > 1) av_log(codec, AV_LOG_ERROR, "Interleaved RTP mode is not supported yet."); } else if (!strcmp(attr, "profile-level-id")) { if (strlen(value) == 6) { char buffer[3]; // 6 characters=3 bytes, in hex. uint8_t profile_idc; uint8_t profile_iop; uint8_t level_idc; buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0'; profile_idc = strtol(buffer, NULL, 16); buffer[0] = value[2]; buffer[1] = value[3]; profile_iop = strtol(buffer, NULL, 16); buffer[0] = value[4]; buffer[1] = value[5]; level_idc = strtol(buffer, NULL, 16); // set the parameters... av_log(codec, AV_LOG_DEBUG, "RTP Profile IDC: %x Profile IOP: %x Level: %x\n", profile_idc, profile_iop, level_idc); h264_data->profile_idc = profile_idc; h264_data->profile_iop = profile_iop; h264_data->level_idc = level_idc; } } else if (!strcmp(attr, "sprop-parameter-sets")) { uint8_t start_sequence[]= { 0, 0, 1 }; codec->extradata_size= 0; codec->extradata= NULL; while (*value) { char base64packet[1024]; uint8_t decoded_packet[1024]; int packet_size; char *dst = base64packet; while (*value && *value != ',' && (dst - base64packet) < sizeof(base64packet) - 1) { *dst++ = *value++; } *dst++ = '\0'; if (*value == ',') value++; packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet)); if (packet_size > 0) { uint8_t *dest = av_malloc(packet_size + sizeof(start_sequence) + codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if(dest) { if(codec->extradata_size) { // av_realloc? memcpy(dest, codec->extradata, codec->extradata_size); av_free(codec->extradata); } memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence)); memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size); memset(dest+codec->extradata_size+sizeof(start_sequence)+ packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); codec->extradata= dest; codec->extradata_size+= sizeof(start_sequence)+packet_size; } else { av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!"); return AVERROR(ENOMEM); } } } av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size); } return 0; }