static int wsd_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; AVStream *st; int version; uint32_t text_offset, data_offset, channel_assign; char playback_time[AV_TIMECODE_STR_SIZE]; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avio_skip(pb, 8); version = avio_r8(pb); av_log(s, AV_LOG_DEBUG, "version: %i.%i\n", version >> 4, version & 0xF); avio_skip(pb, 11); if (version < 0x10) { text_offset = 0x80; data_offset = 0x800; avio_skip(pb, 8); } else { text_offset = avio_rb32(pb); data_offset = avio_rb32(pb); } avio_skip(pb, 4); av_timecode_make_smpte_tc_string(playback_time, avio_rb32(pb), 0); av_dict_set(&s->metadata, "playback_time", playback_time, 0); st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = s->iformat->raw_codec_id; st->codecpar->sample_rate = avio_rb32(pb) / 8; avio_skip(pb, 4); st->codecpar->channels = avio_r8(pb) & 0xF; st->codecpar->bit_rate = st->codecpar->channels * st->codecpar->sample_rate * 8LL; if (!st->codecpar->channels) return AVERROR_INVALIDDATA; avio_skip(pb, 3); channel_assign = avio_rb32(pb); if (!(channel_assign & 1)) { int i; for (i = 1; i < 32; i++) if (channel_assign & (1 << i)) st->codecpar->channel_layout |= wsd_to_av_channel_layoyt(s, i); } avio_skip(pb, 16); if (avio_rb32(pb)) avpriv_request_sample(s, "emphasis"); if (avio_seek(pb, text_offset, SEEK_SET) >= 0) { get_metadata(s, "title", 128); get_metadata(s, "composer", 128); get_metadata(s, "song_writer", 128); get_metadata(s, "artist", 128); get_metadata(s, "album", 128); get_metadata(s, "genre", 32); get_metadata(s, "date", 32); get_metadata(s, "location", 32); get_metadata(s, "comment", 512); get_metadata(s, "user", 512); } return avio_seek(pb, data_offset, SEEK_SET); }