| 34 | } |
| 35 | |
| 36 | static int read_header(AVFormatContext *s) |
| 37 | { |
| 38 | AVStream *st; |
| 39 | AVRational time_base; |
| 40 | |
| 41 | avio_rl32(s->pb); // DKIF |
| 42 | avio_rl16(s->pb); // version |
| 43 | avio_rl16(s->pb); // header size |
| 44 | |
| 45 | st = avformat_new_stream(s, NULL); |
| 46 | if (!st) |
| 47 | return AVERROR(ENOMEM); |
| 48 | |
| 49 | |
| 50 | st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; |
| 51 | st->codecpar->codec_tag = avio_rl32(s->pb); |
| 52 | st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codecpar->codec_tag); |
| 53 | st->codecpar->width = avio_rl16(s->pb); |
| 54 | st->codecpar->height = avio_rl16(s->pb); |
| 55 | time_base.den = avio_rl32(s->pb); |
| 56 | time_base.num = avio_rl32(s->pb); |
| 57 | st->nb_frames = avio_rl32(s->pb); |
| 58 | avio_skip(s->pb, 4); // unused |
| 59 | |
| 60 | // Infer duration from nb_frames, in order to be backward compatible with |
| 61 | // previous IVF demuxer. |
| 62 | // It is popular to configure time_base to 1/frame_rate by IVF muxer, that |
| 63 | // the duration happens to be the same with nb_frames. See |
| 64 | // `https://chromium.googlesource.com/webm/vp8-test-vectors/+/refs/heads/main` |
| 65 | st->duration = st->nb_frames; |
| 66 | |
| 67 | ffstream(st)->need_parsing = AVSTREAM_PARSE_HEADERS; |
| 68 | |
| 69 | if (!time_base.den || !time_base.num) { |
| 70 | av_log(s, AV_LOG_ERROR, "Invalid frame rate\n"); |
| 71 | return AVERROR_INVALIDDATA; |
| 72 | } |
| 73 | |
| 74 | avpriv_set_pts_info(st, 64, time_base.num, time_base.den); |
| 75 | |
| 76 | return 0; |
| 77 | } |
| 78 | |
| 79 | static int read_packet(AVFormatContext *s, AVPacket *pkt) |
| 80 | { |
nothing calls this directly
no test coverage detected