Go to the documentation of this file.
30 #define MAX_SYNC_SIZE 100000
35 int pes2 = (p[3] & 0xC0) == 0x80 &&
36 (p[4] & 0xC0) != 0x40 &&
37 ((p[4] & 0xC0) == 0x00 ||
38 (p[4] & 0xC0) >> 2 == (p[6] & 0xF0));
40 for (p += 3; p <
end && *p == 0xFF; p++) ;
41 if ((*p & 0xC0) == 0x40)
44 if ((*p & 0xF0) == 0x20)
45 pes1 = p[0] & p[2] & p[4] & 1;
46 else if ((*p & 0xF0) == 0x30)
47 pes1 = p[0] & p[2] & p[4] & p[5] & p[7] & p[9] & 1;
56 return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
63 int sys = 0, pspack = 0, priv1 = 0, vid = 0;
64 int audio = 0, invalid = 0, score = 0;
69 if ((
code & 0xffffff00) == 0x100) {
86 else if (
code == 0x1fd && pes) vid++;
94 if (vid + audio > invalid + 1)
100 if (sys > invalid && sys * 9 <= pspack * 10)
103 if (pspack > invalid && (priv1 + vid + audio) * 10 >= pspack * 9)
106 if ((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys &&
107 !pspack && p->
buf_size > 2048 && vid + audio > invalid)
136 if (!memcmp(
"IMKH",
buffer, 4)) {
138 }
else if (!memcmp(
"Sofdec",
buffer, 6)) {
160 unsigned int state, v;
163 state = *header_state;
170 if (
state == 0x000001) {
180 *header_state =
state;
193 int psm_length, ps_info_length, es_map_length;
204 es_map_length = psm_length - ps_info_length - 10;
207 while (es_map_length >= 4) {
209 unsigned char es_id =
avio_r8(pb);
216 es_map_length -= 4 + es_info_length;
219 return 2 + psm_length;
226 int64_t *ppos,
int *pstart_code,
227 int64_t *ppts, int64_t *pdts)
231 int pes_ext, ext2_len, id_ext, skip;
268 if (bytesread !=
len) {
273 p = memchr(ps2buf,
'S',
len - 5);
276 m->
sofdec = !memcmp(p+1,
"ofdec", 5);
281 if (
len == 980 && ps2buf[0] == 0) {
283 uint32_t startpts =
AV_RB32(ps2buf + 0x0d);
284 uint32_t endpts =
AV_RB32(ps2buf + 0x11);
285 uint8_t hours = ((ps2buf[0x19] >> 4) * 10) + (ps2buf[0x19] & 0x0f);
286 uint8_t mins = ((ps2buf[0x1a] >> 4) * 10) + (ps2buf[0x1a] & 0x0f);
287 uint8_t secs = ((ps2buf[0x1b] >> 4) * 10) + (ps2buf[0x1b] & 0x0f);
292 (ps2buf[0x19] & 0x0f) < 10 &&
293 (ps2buf[0x1a] & 0x0f) < 10 &&
294 (ps2buf[0x1b] & 0x0f) < 10 &&
296 }
else if (
len == 1018 && ps2buf[0] == 1) {
298 uint8_t hours = ((ps2buf[0x1d] >> 4) * 10) + (ps2buf[0x1d] & 0x0f);
299 uint8_t mins = ((ps2buf[0x1e] >> 4) * 10) + (ps2buf[0x1e] & 0x0f);
300 uint8_t secs = ((ps2buf[0x1f] >> 4) * 10) + (ps2buf[0x1f] & 0x0f);
305 (ps2buf[0x1d] & 0x0f) < 10 &&
306 (ps2buf[0x1e] & 0x0f) < 10 &&
307 (ps2buf[0x1f] & 0x0f) < 10);
330 }
else if (!m->
dvd) {
342 if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
343 (startcode >= 0x1e0 && startcode <= 0x1ef) ||
344 (startcode == 0x1bd) ||
346 (startcode == 0x1fd)))
366 if ((
c & 0xc0) == 0x40) {
372 if ((
c & 0xe0) == 0x20) {
380 }
else if ((
c & 0xc0) == 0x80) {
385 if (header_len >
len)
396 if (
flags & 0x3f && header_len == 0) {
405 skip = (pes_ext >> 4) & 0xb;
407 if (pes_ext & 0x40 || skip > header_len) {
414 if (pes_ext & 0x01) {
417 if ((ext2_len & 0x7f) > 0) {
419 if ((id_ext & 0x80) == 0)
420 startcode = ((startcode & 0xff) << 8) | id_ext;
440 if (startcode == 0x0b) {
456 for (
i = 0;
i <
s->nb_streams;
i++) {
457 if (startcode ==
s->streams[
i]->id &&
466 *pstart_code = startcode;
477 int len, startcode,
i, es_type,
ret;
479 int request_probe= 0;
482 int64_t
pts, dts, dummy_pos;
489 if (startcode >= 0x80 && startcode <= 0xcf) {
497 if (startcode >= 0xb0 && startcode <= 0xbf) {
501 }
else if (startcode >= 0xa0 && startcode <= 0xaf) {
512 for (
i = 0;
i <
s->nb_streams;
i++) {
514 if (st->
id == startcode)
544 }
else if (m->
imkh_cctv && es_type == 0x91) {
547 }
else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
548 static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
549 unsigned char buf[8];
553 if (!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
561 }
else if (startcode >= 0x1c0 && startcode <= 0x1df) {
567 }
else if (m->
imkh_cctv && startcode == 0x1c0 &&
len > 80) {
575 }
else if (startcode >= 0x80 && startcode <= 0x87) {
578 }
else if ((startcode >= 0x88 && startcode <= 0x8f) ||
579 (startcode >= 0x98 && startcode <= 0x9f)) {
583 }
else if (startcode >= 0xa0 && startcode <= 0xaf) {
590 }
else if (startcode >= 0xb0 && startcode <= 0xbf) {
593 }
else if (startcode >= 0xc0 && startcode <= 0xcf) {
597 }
else if (startcode >= 0x20 && startcode <= 0x3f) {
600 }
else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
628 if (startcode >= 0xa0 && startcode <= 0xaf) {
648 return (
ret < 0) ?
ret : 0;
652 int64_t *ppos, int64_t pos_limit)
668 if (startcode ==
s->streams[stream_index]->id &&
676 pos, dts, dts / 90000.0);
692 #if CONFIG_VOBSUB_DEMUXER
699 #define REF_STRING "# VobSub index file,"
700 #define MAX_LINE_SIZE 2048
702 typedef struct VobSubDemuxContext {
707 } VobSubDemuxContext;
711 if (!strncmp(p->
buf, REF_STRING,
sizeof(REF_STRING) - 1))
718 VobSubDemuxContext *vobsub =
s->priv_data;
721 for (
i = 0;
i <
s->nb_streams;
i++)
730 int i,
ret = 0, header_parsed = 0, langidx = 0;
731 VobSubDemuxContext *vobsub =
s->priv_data;
741 if (!vobsub->sub_name) {
744 if (!vobsub->sub_name) {
748 fname_len = strlen(vobsub->sub_name);
749 ext = vobsub->sub_name - 3 + fname_len;
750 if (fname_len < 4 || *(ext - 1) !=
'.') {
752 "to guess the associated .SUB file\n");
755 memcpy(ext, !strncmp(ext,
"IDX", 3) ?
"SUB" :
"sub", 3);
764 if (!vobsub->sub_ctx) {
788 if (!strncmp(
line,
"id:", 3)) {
789 if (sscanf(
line,
"id: %63[^,], index: %u",
id, &stream_id) != 2) {
791 "assuming 'id: und, index: 0'\n",
line);
809 }
else if (!strncmp(
line,
"timestamp:", 10)) {
812 int64_t
pos, timestamp;
813 const char *p =
line + 10;
815 if (stream_id == -1) {
821 if (!st || st->
id != stream_id) {
836 if (sscanf(p,
"%02d:%02d:%02d:%03d, filepos: %"SCNx64,
837 &hh, &mm, &
ss, &ms, &
pos) != 5) {
839 "abort parsing\n",
line);
843 timestamp = (hh*3600LL + mm*60LL +
ss) * 1000LL + ms + delay;
852 sub->
pts = timestamp;
855 }
else if (!strncmp(
line,
"alt:", 4)) {
856 const char *p =
line + 4;
864 }
else if (!strncmp(
line,
"delay:", 6)) {
865 int sign = 1, hh = 0, mm = 0,
ss = 0, ms = 0;
866 const char *p =
line + 6;
870 if (*p ==
'-' || *p ==
'+') {
871 sign = *p ==
'-' ? -1 : 1;
874 sscanf(p,
"%d:%d:%d:%d", &hh, &mm, &
ss, &ms);
875 delay = ((hh*3600LL + mm*60LL +
ss) * 1000LL + ms) * sign;
877 }
else if (!strncmp(
line,
"langidx:", 8)) {
878 const char *p =
line + 8;
880 if (sscanf(p,
"%d", &langidx) != 1)
883 }
else if (!header_parsed) {
892 for (
i = 0;
i <
s->nb_streams;
i++) {
894 vobsub->q[
i].keep_duplicates = 1;
902 for (
i = 0;
i <
s->nb_streams;
i++) {
912 vobsub_read_close(
s);
919 VobSubDemuxContext *vobsub =
s->priv_data;
922 int ret, psize, total_read = 0,
i;
924 int64_t min_ts = INT64_MAX;
926 for (
i = 0;
i <
s->nb_streams;
i++) {
959 int n, to_read, startcode;
961 int64_t old_pos =
avio_tell(pb), new_pos;
970 to_read =
ret & 0xffff;
972 pkt_size =
ret + (new_pos - old_pos);
975 if (total_read + pkt_size > psize)
977 total_read += pkt_size;
990 }
while (total_read < psize);
996 int64_t min_ts, int64_t ts, int64_t max_ts,
int flags)
998 VobSubDemuxContext *vobsub =
s->priv_data;
1003 if (stream_index == -1 &&
s->nb_streams != 1) {
1013 for (
i = 0;
i <
s->nb_streams;
i++) {
1015 min_ts, ts, max_ts,
flags);
1022 if (stream_index == -1)
1025 min_ts, ts, max_ts,
flags);
1033 static const AVClass vobsub_demuxer_class = {
1043 .priv_data_size =
sizeof(VobSubDemuxContext),
1047 .read_seek2 = vobsub_read_seek,
1050 .extensions =
"idx",
1051 .priv_class = &vobsub_demuxer_class,
#define AV_LOG_WARNING
Something somehow does not look correct.
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
#define SYSTEM_HEADER_START_CODE
static int mpegps_read_packet(AVFormatContext *s, AVPacket *pkt)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
enum AVMediaType codec_type
General type of the encoded data.
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
#define STREAM_TYPE_AUDIO_AAC
static int64_t ff_parse_pes_pts(const uint8_t *buf)
Parse MPEG-PES five-byte timestamp.
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
This struct describes the properties of an encoded stream.
#define AVERROR_EOF
End of file.
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
#define AV_CH_LAYOUT_MONO
int nb_subs
number of subtitles packets
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
int av_grow_packet(AVPacket *pkt, int grow_by)
Increase packet size, correctly zeroing padding.
static av_cold int end(AVCodecContext *avctx)
#define STREAM_TYPE_AUDIO_MPEG1
static int find_next_start_code(AVIOContext *pb, int *size_ptr, int32_t *header_state)
#define AV_LOG_VERBOSE
Detailed information.
int buf_size
Size of buf except extra allocated bytes.
int64_t avio_size(AVIOContext *s)
Get the filesize.
#define STREAM_TYPE_AUDIO_MPEG2
int current_sub_idx
current position for the read packet callback
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add an index entry into a sorted list.
static av_cold int read_close(AVFormatContext *ctx)
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
static double val(void *priv, double ch)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
@ AV_ROUND_UP
Round toward +infinity.
AVInputFormat ff_mpegps_demuxer
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
#define ss(width, name, subs,...)
int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Update current_sub_idx to emulate a seek.
unsigned int avio_rb32(AVIOContext *s)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define PROGRAM_STREAM_MAP
#define STREAM_TYPE_AUDIO_AC3
#define STREAM_TYPE_VIDEO_MPEG4
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
static int64_t get_pts(AVIOContext *pb, int c)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
enum AVStreamParseType need_parsing
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
#define STREAM_TYPE_VIDEO_MPEG1
static int64_t fsize(FILE *f)
int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt)
Generic read_packet() callback for subtitles demuxers using this queue system.
#define AVERROR_DEMUXER_NOT_FOUND
Demuxer not found.
@ SUB_SORT_POS_TS
sort by position, then timestamps
@ AVDISCARD_ALL
discard all
static int mpegps_read_header(AVFormatContext *s)
AVCodecParameters * codecpar
Codec parameters associated with this stream.
#define LIBAVUTIL_VERSION_INT
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally hours
static int read_header(FFV1Context *f)
Describe the class of an AVClass context structure.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
static int check_pes(const uint8_t *p, const uint8_t *end)
Rational number (pair of numerator and denominator).
@ AV_CODEC_ID_DVD_SUBTITLE
const char * av_default_item_name(void *ptr)
Return the context name.
This structure contains the data a format has to probe a file.
AVPacket * ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, const uint8_t *event, size_t len, int merge)
Insert a new subtitle event.
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
int sample_rate
Audio only.
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
AVCodecID
Identify the syntax and semantics of the bitstream.
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
const OptionDef options[]
unsigned int avio_rb24(AVIOContext *s)
unsigned char psm_es_type[256]
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static int check_pack_header(const uint8_t *buf)
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
#define STREAM_TYPE_VIDEO_HEVC
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
static AVRational av_make_q(int num, int den)
Create an AVRational.
#define AV_NOPTS_VALUE
Undefined timestamp value.
void ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q)
Set missing durations, sort subtitles by PTS (and then byte position), and drop duplicated events.
static const uint8_t header[24]
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
int avio_r8(AVIOContext *s)
#define STREAM_TYPE_VIDEO_MPEG2
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q)
Remove and destroy all the subtitles packets.
ff_const59 AVInputFormat * av_find_input_format(const char *short_name)
Find AVInputFormat based on the short name of the input format.
#define i(width, name, range_min, range_max)
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
#define AV_TIME_BASE
Internal time base represented as integer.
AVPacket * subs
array of subtitles packets
@ AV_ROUND_DOWN
Round toward -infinity.
#define xf(width, name, var, range_min, range_max, subs,...)
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
int ff_get_line(AVIOContext *s, char *buf, int maxlen)
Read a whole line of text from AVIOContext.
int id
Format-specific stream ID.
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
unsigned int avio_rb16(AVIOContext *s)
static AVInputFormat * iformat
void av_bprintf(AVBPrint *buf, const char *fmt,...)
#define AV_INPUT_BUFFER_PADDING_SIZE
static long mpegps_psm_parse(MpegDemuxContext *m, AVIOContext *pb)
Extract stream types from a program stream map According to ISO/IEC 13818-1 ('MPEG-2 Systems') table ...
#define FF_ARRAY_ELEMS(a)
int index
stream index in AVFormatContext
#define STREAM_TYPE_VIDEO_H264
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
int request_probe
stream probing state -1 -> probing finished 0 -> no probing requested rest -> perform probing with re...
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
char * av_strdup(const char *s)
Duplicate a string.
@ AV_ROUND_PASS_MINMAX
Flag telling rescaling functions to pass INT64_MIN/MAX through unchanged, avoiding special cases for ...
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
This structure stores compressed data.
static int mpegps_read_pes_header(AVFormatContext *s, int64_t *ppos, int *pstart_code, int64_t *ppts, int64_t *pdts)
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
int64_t pos
byte position in stream, -1 if unknown
static int mpegps_probe(const AVProbeData *p)
uint64_t channel_layout
Audio only.
#define flags(name, subs,...)
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.