Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
a1c69965
Commit
a1c69965
authored
Feb 23, 2014
by
Luca Barbato
Committed by
Diego Biurrun
Feb 25, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
parser: K&R formatting cosmetics
Signed-off-by:
Diego Biurrun
<
diego@biurrun.de
>
parent
ed61f3ca
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
105 additions
and
95 deletions
+105
-95
parser.c
libavcodec/parser.c
+105
-95
No files found.
libavcodec/parser.c
View file @
a1c69965
...
@@ -23,14 +23,18 @@
...
@@ -23,14 +23,18 @@
#include <stdint.h>
#include <stdint.h>
#include <string.h>
#include <string.h>
#include "parser.h"
#include "libavutil/mem.h"
#include "libavutil/mem.h"
#include "parser.h"
static
AVCodecParser
*
av_first_parser
=
NULL
;
static
AVCodecParser
*
av_first_parser
=
NULL
;
AVCodecParser
*
av_parser_next
(
AVCodecParser
*
p
){
AVCodecParser
*
av_parser_next
(
AVCodecParser
*
p
)
if
(
p
)
return
p
->
next
;
{
else
return
av_first_parser
;
if
(
p
)
return
p
->
next
;
else
return
av_first_parser
;
}
}
void
av_register_codec_parser
(
AVCodecParser
*
parser
)
void
av_register_codec_parser
(
AVCodecParser
*
parser
)
...
@@ -45,10 +49,10 @@ AVCodecParserContext *av_parser_init(int codec_id)
...
@@ -45,10 +49,10 @@ AVCodecParserContext *av_parser_init(int codec_id)
AVCodecParser
*
parser
;
AVCodecParser
*
parser
;
int
ret
;
int
ret
;
if
(
codec_id
==
AV_CODEC_ID_NONE
)
if
(
codec_id
==
AV_CODEC_ID_NONE
)
return
NULL
;
return
NULL
;
for
(
parser
=
av_first_parser
;
parser
!=
NULL
;
parser
=
parser
->
next
)
{
for
(
parser
=
av_first_parser
;
parser
!=
NULL
;
parser
=
parser
->
next
)
{
if
(
parser
->
codec_ids
[
0
]
==
codec_id
||
if
(
parser
->
codec_ids
[
0
]
==
codec_id
||
parser
->
codec_ids
[
1
]
==
codec_id
||
parser
->
codec_ids
[
1
]
==
codec_id
||
parser
->
codec_ids
[
2
]
==
codec_id
||
parser
->
codec_ids
[
2
]
==
codec_id
||
...
@@ -57,7 +61,8 @@ AVCodecParserContext *av_parser_init(int codec_id)
...
@@ -57,7 +61,8 @@ AVCodecParserContext *av_parser_init(int codec_id)
goto
found
;
goto
found
;
}
}
return
NULL
;
return
NULL
;
found
:
found:
s
=
av_mallocz
(
sizeof
(
AVCodecParserContext
));
s
=
av_mallocz
(
sizeof
(
AVCodecParserContext
));
if
(
!
s
)
if
(
!
s
)
return
NULL
;
return
NULL
;
...
@@ -77,9 +82,9 @@ AVCodecParserContext *av_parser_init(int codec_id)
...
@@ -77,9 +82,9 @@ AVCodecParserContext *av_parser_init(int codec_id)
return
NULL
;
return
NULL
;
}
}
}
}
s
->
fetch_timestamp
=
1
;
s
->
fetch_timestamp
=
1
;
s
->
pict_type
=
AV_PICTURE_TYPE_I
;
s
->
pict_type
=
AV_PICTURE_TYPE_I
;
s
->
key_frame
=
-
1
;
s
->
key_frame
=
-
1
;
s
->
convergence_duration
=
0
;
s
->
convergence_duration
=
0
;
s
->
dts_sync_point
=
INT_MIN
;
s
->
dts_sync_point
=
INT_MIN
;
s
->
dts_ref_dts_delta
=
INT_MIN
;
s
->
dts_ref_dts_delta
=
INT_MIN
;
...
@@ -87,71 +92,70 @@ AVCodecParserContext *av_parser_init(int codec_id)
...
@@ -87,71 +92,70 @@ AVCodecParserContext *av_parser_init(int codec_id)
return
s
;
return
s
;
}
}
void
ff_fetch_timestamp
(
AVCodecParserContext
*
s
,
int
off
,
int
remove
){
void
ff_fetch_timestamp
(
AVCodecParserContext
*
s
,
int
off
,
int
remove
)
{
int
i
;
int
i
;
s
->
dts
=
s
->
pts
=
AV_NOPTS_VALUE
;
s
->
dts
=
s
->
pos
=
-
1
;
s
->
pts
=
AV_NOPTS_VALUE
;
s
->
offset
=
0
;
s
->
pos
=
-
1
;
for
(
i
=
0
;
i
<
AV_PARSER_PTS_NB
;
i
++
)
{
s
->
offset
=
0
;
if
(
s
->
cur_offset
+
off
>=
s
->
cur_frame_offset
[
i
]
for
(
i
=
0
;
i
<
AV_PARSER_PTS_NB
;
i
++
)
{
&&
(
s
->
frame_offset
<
s
->
cur_frame_offset
[
i
]
||
if
(
s
->
cur_offset
+
off
>=
s
->
cur_frame_offset
[
i
]
&&
(
!
s
->
frame_offset
&&
!
s
->
next_frame_offset
))
// first field/frame
(
s
->
frame_offset
<
s
->
cur_frame_offset
[
i
]
||
&&
s
->
cur_frame_end
[
i
])
{
(
!
s
->
frame_offset
&&
!
s
->
next_frame_offset
))
&&
s
->
dts
=
s
->
cur_frame_dts
[
i
];
s
->
cur_frame_end
[
i
])
{
s
->
pts
=
s
->
cur_frame_pts
[
i
];
s
->
dts
=
s
->
cur_frame_dts
[
i
];
s
->
pos
=
s
->
cur_frame_pos
[
i
];
s
->
pts
=
s
->
cur_frame_pts
[
i
];
s
->
pos
=
s
->
cur_frame_pos
[
i
];
s
->
offset
=
s
->
next_frame_offset
-
s
->
cur_frame_offset
[
i
];
s
->
offset
=
s
->
next_frame_offset
-
s
->
cur_frame_offset
[
i
];
if
(
remove
)
if
(
remove
)
s
->
cur_frame_offset
[
i
]
=
INT64_MAX
;
s
->
cur_frame_offset
[
i
]
=
INT64_MAX
;
if
(
s
->
cur_offset
+
off
<
s
->
cur_frame_end
[
i
])
if
(
s
->
cur_offset
+
off
<
s
->
cur_frame_end
[
i
])
break
;
break
;
}
}
}
}
}
}
int
av_parser_parse2
(
AVCodecParserContext
*
s
,
int
av_parser_parse2
(
AVCodecParserContext
*
s
,
AVCodecContext
*
avctx
,
AVCodecContext
*
avctx
,
uint8_t
**
poutbuf
,
int
*
poutbuf_size
,
uint8_t
**
poutbuf
,
int
*
poutbuf_size
,
const
uint8_t
*
buf
,
int
buf_size
,
const
uint8_t
*
buf
,
int
buf_size
,
int64_t
pts
,
int64_t
dts
,
int64_t
pts
,
int64_t
dts
,
int64_t
pos
)
int64_t
pos
)
{
{
int
index
,
i
;
int
index
,
i
;
uint8_t
dummy_buf
[
FF_INPUT_BUFFER_PADDING_SIZE
];
uint8_t
dummy_buf
[
FF_INPUT_BUFFER_PADDING_SIZE
];
if
(
!
(
s
->
flags
&
PARSER_FLAG_FETCHED_OFFSET
))
{
if
(
!
(
s
->
flags
&
PARSER_FLAG_FETCHED_OFFSET
))
{
s
->
next_frame_offset
=
s
->
next_frame_offset
=
s
->
cur_offset
=
pos
;
s
->
cur_offset
=
pos
;
s
->
flags
|=
PARSER_FLAG_FETCHED_OFFSET
;
s
->
flags
|=
PARSER_FLAG_FETCHED_OFFSET
;
}
}
if
(
buf_size
==
0
)
{
if
(
buf_size
==
0
)
{
/* padding is always necessary even if EOF, so we add it here */
/* padding is always necessary even if EOF, so we add it here */
memset
(
dummy_buf
,
0
,
sizeof
(
dummy_buf
));
memset
(
dummy_buf
,
0
,
sizeof
(
dummy_buf
));
buf
=
dummy_buf
;
buf
=
dummy_buf
;
}
else
if
(
s
->
cur_offset
+
buf_size
!=
}
else
if
(
s
->
cur_offset
+
buf_size
!=
s
->
cur_frame_end
[
s
->
cur_frame_start_index
])
{
/* skip remainder packets */
s
->
cur_frame_end
[
s
->
cur_frame_start_index
])
{
/* skip remainder packets */
/* add a new packet descriptor */
/* add a new packet descriptor */
i
=
(
s
->
cur_frame_start_index
+
1
)
&
(
AV_PARSER_PTS_NB
-
1
);
i
=
(
s
->
cur_frame_start_index
+
1
)
&
(
AV_PARSER_PTS_NB
-
1
);
s
->
cur_frame_start_index
=
i
;
s
->
cur_frame_start_index
=
i
;
s
->
cur_frame_offset
[
i
]
=
s
->
cur_offset
;
s
->
cur_frame_offset
[
i
]
=
s
->
cur_offset
;
s
->
cur_frame_end
[
i
]
=
s
->
cur_offset
+
buf_size
;
s
->
cur_frame_end
[
i
]
=
s
->
cur_offset
+
buf_size
;
s
->
cur_frame_pts
[
i
]
=
pts
;
s
->
cur_frame_pts
[
i
]
=
pts
;
s
->
cur_frame_dts
[
i
]
=
dts
;
s
->
cur_frame_dts
[
i
]
=
dts
;
s
->
cur_frame_pos
[
i
]
=
pos
;
s
->
cur_frame_pos
[
i
]
=
pos
;
}
}
if
(
s
->
fetch_timestamp
){
if
(
s
->
fetch_timestamp
)
{
s
->
fetch_timestamp
=
0
;
s
->
fetch_timestamp
=
0
;
s
->
last_pts
=
s
->
pts
;
s
->
last_pts
=
s
->
pts
;
s
->
last_dts
=
s
->
dts
;
s
->
last_dts
=
s
->
dts
;
s
->
last_pos
=
s
->
pos
;
s
->
last_pos
=
s
->
pos
;
ff_fetch_timestamp
(
s
,
0
,
0
);
ff_fetch_timestamp
(
s
,
0
,
0
);
}
}
/* WARNING: the returned index can be negative */
/* WARNING: the returned index can be negative */
index
=
s
->
parser
->
parser_parse
(
s
,
avctx
,
(
const
uint8_t
**
)
poutbuf
,
poutbuf_size
,
buf
,
buf_size
);
index
=
s
->
parser
->
parser_parse
(
s
,
avctx
,
(
const
uint8_t
**
)
poutbuf
,
poutbuf_size
,
buf
,
buf_size
);
/* update the file pointer */
/* update the file pointer */
if
(
*
poutbuf_size
)
{
if
(
*
poutbuf_size
)
{
/* fill the data for the current frame */
/* fill the data for the current frame */
...
@@ -159,7 +163,7 @@ int av_parser_parse2(AVCodecParserContext *s,
...
@@ -159,7 +163,7 @@ int av_parser_parse2(AVCodecParserContext *s,
/* offset of the next frame */
/* offset of the next frame */
s
->
next_frame_offset
=
s
->
cur_offset
+
index
;
s
->
next_frame_offset
=
s
->
cur_offset
+
index
;
s
->
fetch_timestamp
=
1
;
s
->
fetch_timestamp
=
1
;
}
}
if
(
index
<
0
)
if
(
index
<
0
)
index
=
0
;
index
=
0
;
...
@@ -167,30 +171,32 @@ int av_parser_parse2(AVCodecParserContext *s,
...
@@ -167,30 +171,32 @@ int av_parser_parse2(AVCodecParserContext *s,
return
index
;
return
index
;
}
}
int
av_parser_change
(
AVCodecParserContext
*
s
,
int
av_parser_change
(
AVCodecParserContext
*
s
,
AVCodecContext
*
avctx
,
AVCodecContext
*
avctx
,
uint8_t
**
poutbuf
,
int
*
poutbuf_size
,
uint8_t
**
poutbuf
,
int
*
poutbuf_size
,
const
uint8_t
*
buf
,
int
buf_size
,
int
keyframe
){
const
uint8_t
*
buf
,
int
buf_size
,
int
keyframe
)
{
if
(
s
&&
s
->
parser
->
split
){
if
(
s
&&
s
->
parser
->
split
)
{
if
((
avctx
->
flags
&
CODEC_FLAG_GLOBAL_HEADER
)
||
(
avctx
->
flags2
&
CODEC_FLAG2_LOCAL_HEADER
)){
if
((
avctx
->
flags
&
CODEC_FLAG_GLOBAL_HEADER
)
||
int
i
=
s
->
parser
->
split
(
avctx
,
buf
,
buf_size
);
(
avctx
->
flags2
&
CODEC_FLAG2_LOCAL_HEADER
))
{
buf
+=
i
;
int
i
=
s
->
parser
->
split
(
avctx
,
buf
,
buf_size
);
buf
+=
i
;
buf_size
-=
i
;
buf_size
-=
i
;
}
}
}
}
/* cast to avoid warning about discarding qualifiers */
/* cast to avoid warning about discarding qualifiers */
*
poutbuf
=
(
uint8_t
*
)
buf
;
*
poutbuf
=
(
uint8_t
*
)
buf
;
*
poutbuf_size
=
buf_size
;
*
poutbuf_size
=
buf_size
;
if
(
avctx
->
extradata
)
{
if
(
avctx
->
extradata
)
{
if
((
keyframe
&&
(
avctx
->
flags2
&
CODEC_FLAG2_LOCAL_HEADER
)))
{
if
((
keyframe
&&
(
avctx
->
flags2
&
CODEC_FLAG2_LOCAL_HEADER
)))
{
int
size
=
buf_size
+
avctx
->
extradata_size
;
int
size
=
buf_size
+
avctx
->
extradata_size
;
*
poutbuf_size
=
size
;
*
poutbuf
=
av_malloc
(
size
+
FF_INPUT_BUFFER_PADDING_SIZE
);
*
poutbuf_size
=
size
;
*
poutbuf
=
av_malloc
(
size
+
FF_INPUT_BUFFER_PADDING_SIZE
);
memcpy
(
*
poutbuf
,
avctx
->
extradata
,
avctx
->
extradata_size
);
memcpy
(
*
poutbuf
,
avctx
->
extradata
,
avctx
->
extradata_size
);
memcpy
((
*
poutbuf
)
+
avctx
->
extradata_size
,
buf
,
buf_size
+
FF_INPUT_BUFFER_PADDING_SIZE
);
memcpy
((
*
poutbuf
)
+
avctx
->
extradata_size
,
buf
,
buf_size
+
FF_INPUT_BUFFER_PADDING_SIZE
);
return
1
;
return
1
;
}
}
}
}
...
@@ -200,7 +206,7 @@ int av_parser_change(AVCodecParserContext *s,
...
@@ -200,7 +206,7 @@ int av_parser_change(AVCodecParserContext *s,
void
av_parser_close
(
AVCodecParserContext
*
s
)
void
av_parser_close
(
AVCodecParserContext
*
s
)
{
{
if
(
s
)
{
if
(
s
)
{
if
(
s
->
parser
->
parser_close
)
if
(
s
->
parser
->
parser_close
)
s
->
parser
->
parser_close
(
s
);
s
->
parser
->
parser_close
(
s
);
av_free
(
s
->
priv_data
);
av_free
(
s
->
priv_data
);
...
@@ -208,31 +214,33 @@ void av_parser_close(AVCodecParserContext *s)
...
@@ -208,31 +214,33 @@ void av_parser_close(AVCodecParserContext *s)
}
}
}
}
int
ff_combine_frame
(
ParseContext
*
pc
,
int
next
,
const
uint8_t
**
buf
,
int
*
buf_size
)
int
ff_combine_frame
(
ParseContext
*
pc
,
int
next
,
const
uint8_t
**
buf
,
int
*
buf_size
)
{
{
if
(
pc
->
overread
)
{
if
(
pc
->
overread
)
{
av_dlog
(
NULL
,
"overread %d, state:%X next:%d index:%d o_index:%d
\n
"
,
av_dlog
(
NULL
,
"overread %d, state:%X next:%d index:%d o_index:%d
\n
"
,
pc
->
overread
,
pc
->
state
,
next
,
pc
->
index
,
pc
->
overread_index
);
pc
->
overread
,
pc
->
state
,
next
,
pc
->
index
,
pc
->
overread_index
);
av_dlog
(
NULL
,
"%X %X %X %X
\n
"
,
(
*
buf
)[
0
],
(
*
buf
)[
1
],
(
*
buf
)[
2
],
(
*
buf
)[
3
]);
av_dlog
(
NULL
,
"%X %X %X %X
\n
"
,
(
*
buf
)[
0
],
(
*
buf
)[
1
],
(
*
buf
)[
2
],
(
*
buf
)[
3
]);
}
}
/* Copy overread bytes from last frame into buffer. */
/* Copy overread bytes from last frame into buffer. */
for
(;
pc
->
overread
>
0
;
pc
->
overread
--
){
for
(;
pc
->
overread
>
0
;
pc
->
overread
--
)
pc
->
buffer
[
pc
->
index
++
]
=
pc
->
buffer
[
pc
->
overread_index
++
];
pc
->
buffer
[
pc
->
index
++
]
=
pc
->
buffer
[
pc
->
overread_index
++
];
}
/* flush remaining if EOF */
/* flush remaining if EOF */
if
(
!*
buf_size
&&
next
==
END_NOT_FOUND
){
if
(
!*
buf_size
&&
next
==
END_NOT_FOUND
)
next
=
0
;
next
=
0
;
}
pc
->
last_index
=
pc
->
index
;
pc
->
last_index
=
pc
->
index
;
/* copy into buffer end return */
/* copy into buffer end return */
if
(
next
==
END_NOT_FOUND
){
if
(
next
==
END_NOT_FOUND
)
{
void
*
new_buffer
=
av_fast_realloc
(
pc
->
buffer
,
&
pc
->
buffer_size
,
(
*
buf_size
)
+
pc
->
index
+
FF_INPUT_BUFFER_PADDING_SIZE
);
void
*
new_buffer
=
av_fast_realloc
(
pc
->
buffer
,
&
pc
->
buffer_size
,
(
*
buf_size
)
+
pc
->
index
+
FF_INPUT_BUFFER_PADDING_SIZE
);
if
(
!
new_buffer
)
if
(
!
new_buffer
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
pc
->
buffer
=
new_buffer
;
pc
->
buffer
=
new_buffer
;
memcpy
(
&
pc
->
buffer
[
pc
->
index
],
*
buf
,
*
buf_size
);
memcpy
(
&
pc
->
buffer
[
pc
->
index
],
*
buf
,
*
buf_size
);
...
@@ -240,34 +248,37 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s
...
@@ -240,34 +248,37 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s
return
-
1
;
return
-
1
;
}
}
*
buf_size
=
*
buf_size
=
pc
->
overread_index
=
pc
->
index
+
next
;
pc
->
overread_index
=
pc
->
index
+
next
;
/* append to buffer */
/* append to buffer */
if
(
pc
->
index
){
if
(
pc
->
index
)
{
void
*
new_buffer
=
av_fast_realloc
(
pc
->
buffer
,
&
pc
->
buffer_size
,
next
+
pc
->
index
+
FF_INPUT_BUFFER_PADDING_SIZE
);
void
*
new_buffer
=
av_fast_realloc
(
pc
->
buffer
,
&
pc
->
buffer_size
,
next
+
pc
->
index
+
FF_INPUT_BUFFER_PADDING_SIZE
);
if
(
!
new_buffer
)
if
(
!
new_buffer
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
pc
->
buffer
=
new_buffer
;
pc
->
buffer
=
new_buffer
;
if
(
next
>
-
FF_INPUT_BUFFER_PADDING_SIZE
)
if
(
next
>
-
FF_INPUT_BUFFER_PADDING_SIZE
)
memcpy
(
&
pc
->
buffer
[
pc
->
index
],
*
buf
,
memcpy
(
&
pc
->
buffer
[
pc
->
index
],
*
buf
,
next
+
FF_INPUT_BUFFER_PADDING_SIZE
);
next
+
FF_INPUT_BUFFER_PADDING_SIZE
);
pc
->
index
=
0
;
pc
->
index
=
0
;
*
buf
=
pc
->
buffer
;
*
buf
=
pc
->
buffer
;
}
}
/* store overread bytes */
/* store overread bytes */
for
(;
next
<
0
;
next
++
)
{
for
(;
next
<
0
;
next
++
)
{
pc
->
state
=
(
pc
->
state
<<
8
)
|
pc
->
buffer
[
pc
->
last_index
+
next
];
pc
->
state
=
(
pc
->
state
<<
8
)
|
pc
->
buffer
[
pc
->
last_index
+
next
];
pc
->
state64
=
(
pc
->
state64
<<
8
)
|
pc
->
buffer
[
pc
->
last_index
+
next
];
pc
->
state64
=
(
pc
->
state64
<<
8
)
|
pc
->
buffer
[
pc
->
last_index
+
next
];
pc
->
overread
++
;
pc
->
overread
++
;
}
}
if
(
pc
->
overread
)
{
if
(
pc
->
overread
)
{
av_dlog
(
NULL
,
"overread %d, state:%X next:%d index:%d o_index:%d
\n
"
,
av_dlog
(
NULL
,
"overread %d, state:%X next:%d index:%d o_index:%d
\n
"
,
pc
->
overread
,
pc
->
state
,
next
,
pc
->
index
,
pc
->
overread_index
);
pc
->
overread
,
pc
->
state
,
next
,
pc
->
index
,
pc
->
overread_index
);
av_dlog
(
NULL
,
"%X %X %X %X
\n
"
,
(
*
buf
)[
0
],
(
*
buf
)[
1
],(
*
buf
)[
2
],(
*
buf
)[
3
]);
av_dlog
(
NULL
,
"%X %X %X %X
\n
"
,
(
*
buf
)[
0
],
(
*
buf
)[
1
],
(
*
buf
)[
2
],
(
*
buf
)[
3
]);
}
}
return
0
;
return
0
;
...
@@ -280,16 +291,15 @@ void ff_parse_close(AVCodecParserContext *s)
...
@@ -280,16 +291,15 @@ void ff_parse_close(AVCodecParserContext *s)
av_freep
(
&
pc
->
buffer
);
av_freep
(
&
pc
->
buffer
);
}
}
int
ff_mpeg4video_split
(
AVCodecContext
*
avctx
,
int
ff_mpeg4video_split
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
const
uint8_t
*
buf
,
int
buf_size
)
{
{
int
i
;
int
i
;
uint32_t
state
=
-
1
;
uint32_t
state
=
-
1
;
for
(
i
=
0
;
i
<
buf_size
;
i
++
)
{
for
(
i
=
0
;
i
<
buf_size
;
i
++
)
{
state
=
(
state
<<
8
)
|
buf
[
i
];
state
=
(
state
<<
8
)
|
buf
[
i
];
if
(
state
==
0x1B3
||
state
==
0x1B6
)
if
(
state
==
0x1B3
||
state
==
0x1B6
)
return
i
-
3
;
return
i
-
3
;
}
}
return
0
;
return
0
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment