[FFmpeg-devel] & vs. &&
Benoit Fouet
benoit.fouet
Mon Oct 12 18:41:20 CEST 2009
On 2009-10-12 17:22, Benoit Fouet wrote:
> On 2009-10-12 16:22, Reimar D?ffinger wrote:
>> On Mon, Oct 12, 2009 at 02:36:58PM +0100, John Cox wrote:
>>
>>> Hi
>>>
>>>
>>>> Hi,
>>>>
>>>> I (well, gcc) have (has) seen some weirdness on the use of & vs. && in
>>>> our codebase:
>>>>
>>>> first one:
>>>> libavformat/aviobuf.c:593: warning: suggest parentheses around operand
>>>> of ?!? or change ?&? to ?&&? or ?!? to ?~?
>>>> =========== ><8 ===========
>>>> int url_resetbuf(ByteIOContext *s, int flags)
>>>> {
>>>> URLContext *h = s->opaque;
>>>> if ((flags & URL_RDWR) || (h && h->flags != flags && !h->flags &
>>>> URL_RDWR))
>>>> return AVERROR(EINVAL);
>>>> =========== 8>< ===========
>>>>
>>>> I don't understand what the intent of the test is, but am quite sure it
>>>> is wrong, !h->flags & URL_RDWR being always false.
>>>> I'd naively think the correct way would be to remove the '!', but am not
>>>> sure.
>>>>
>>> I admit to not having read the surrounding code but I'd have thought the intent
>>> was:
>>>
>>> if ((flags & URL_RDWR) || (h && h->flags != flags && !(h->flags &
>>> URL_RDWR)))
>>>
>> Yes.
>>
>>
>>> giving:
>>>
>>> if ((flags & URL_RDWR) || (h && h->flags != flags))
>>>
>>> as the replacement code
>>>
>> Huh? That would do something different than intended I think. It should
>> be possible to reset/reopen a read-write file both as read-only and as
>> write-only, which above code wouldn't allow.
>>
>
> thanks for the explanation.
>
> So, I have a patch now:
> Index: libavformat/aviobuf.c
> ===================================================================
> --- libavformat/aviobuf.c (revision 20209)
> +++ libavformat/aviobuf.c (working copy)
> @@ -590,7 +590,7 @@ int url_setbufsize(ByteIOContext *s, int
> int url_resetbuf(ByteIOContext *s, int flags)
> {
> URLContext *h = s->opaque;
> - if ((flags & URL_RDWR) || (h && h->flags != flags && !h->flags &
> URL_RDWR))
> + if ((flags & URL_RDWR) || (h && h->flags != flags && !(h->flags &
> URL_RDWR)))
> return AVERROR(EINVAL);
>
> if (flags & URL_WRONLY) {
>
>
> This is crashing the following command line on my machine (triggered by
> make test), can anybody reproduce ?
>
> $ gdb --args ./ffmpeg_g -v 0 -y -flags +bitexact -dct fastint -idct
> simple -sws_flags +accurate_rnd+bitexact -t 1 -qscale 10 -f image2
> -vcodec pgmyuv -i ./tests/vsynth1/%02d.pgm -f s16le -i
> ././tests/data/asynth1.sw -acodec mp2
> ././tests/data/b-lavf.nut
>
The problem seems to be in the handling of buf_end.
When entering put_buffer() from libavformat/nutenc.c:389, the
ByteIOContext is as follows:
{buffer = 0xa465324 "\003",
buffer_size = 1024,
buf_ptr = 0xa465324 "\003",
buf_end = 0x0,
opaque = 0xa465310,
read_packet = 0,
write_packet = 0x806a580 <dyn_buf_write>,
seek = 0x806a4f0 <dyn_buf_seek>,
pos = 89,
must_flush = 0,
eof_reached = 0,
write_flag = 0,
is_streamed = 0,
max_packet_size = 0,
checksum = 0,
checksum_ptr = 0x0,
update_checksum = 0,
error = 0,
read_pause = 0,
read_seek = 0}
I don't really have time to investigate a lot but the fact that buf_end
is not set seems to be our problem here, making the test len > size
fail, because len is negative, and doing a memcpy with a negative len
(which is often a bad idea :) )
Index: libavformat/aviobuf.c
===================================================================
@@ -108,7 +108,7 @@ void put_buffer(ByteIOContext *s, const
while (size > 0) {
len = (s->buf_end - s->buf_ptr);
if (len > size) /* here, len is < 0 */
len = size;
memcpy(s->buf_ptr, buf, len);
s->buf_ptr += len;
Ben
More information about the ffmpeg-devel
mailing list