int ff_parse_fmtp(AVStream *stream, PayloadContext *data, const char *p, int (*parse_fmtp)(AVStream *stream, PayloadContext *data, char *attr, char *value)) { char attr[256]; char *value; int res; int value_size = strlen(p) + 1; if (!(value = av_malloc(value_size))) { av_log(stream, AV_LOG_ERROR, "Failed to allocate data for FMTP."); return AVERROR(ENOMEM); } // remove protocol identifier while (*p && *p == ' ') p++; // strip spaces while (*p && *p != ' ') p++; // eat protocol identifier while (*p && *p == ' ') p++; // strip trailing spaces while (ff_rtsp_next_attr_and_value(&p, attr, sizeof(attr), value, value_size)) { res = parse_fmtp(stream, data, attr, value); if (res < 0 && res != AVERROR_PATCHWELCOME) { av_free(value); return res; } } av_free(value); return 0; }
static int parse_h264_sdp_line(AVFormatContext *s, int st_index, PayloadContext *h264_data, const char *line) { AVStream *stream = s->streams[st_index]; AVCodecContext *codec = stream->codec; const char *p = line; assert(h264_data->cookie == MAGIC_COOKIE); if (av_strstart(p, "framesize:", &p)) { char buf1[50]; char *dst = buf1; // remove the protocol identifier.. while (*p && *p == ' ') p++; // strip spaces. while (*p && *p != ' ') p++; // eat protocol identifier while (*p && *p == ' ') p++; // strip trailing spaces. while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) { *dst++ = *p++; } *dst = '\0'; // a='framesize:96 320-240' // set our parameters.. codec->width = atoi(buf1); codec->height = atoi(p + 1); // skip the - codec->pix_fmt = PIX_FMT_YUV420P; } else if (av_strstart(p, "fmtp:", &p)) { char attr[256]; char value[4096]; // remove the protocol identifier.. while (*p && *p == ' ') p++; // strip spaces. while (*p && *p != ' ') p++; // eat protocol identifier while (*p && *p == ' ') p++; // strip trailing spaces. /* loop on each attribute */ while (ff_rtsp_next_attr_and_value (&p, attr, sizeof(attr), value, sizeof(value))) { /* grab the codec extra_data from the config parameter of the fmtp line */ sdp_parse_fmtp_config_h264(stream, h264_data, attr, value); } } else if (av_strstart(p, "cliprect:", &p)) { // could use this if we wanted. } av_set_pts_info(stream, 33, 1, 90000); // 33 should be right, because the pts is 64 bit? (done elsewhere; this is a one time thing) return 0; // keep processing it the normal way... }