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
e4dc1000
Commit
e4dc1000
authored
May 03, 2014
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
yuv4mpeg: split the demuxer and muxer into separate files
parent
3ef6c526
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
220 additions
and
174 deletions
+220
-174
Makefile
libavformat/Makefile
+2
-2
yuv4mpeg.h
libavformat/yuv4mpeg.h
+27
-0
yuv4mpegdec.c
libavformat/yuv4mpegdec.c
+5
-172
yuv4mpegenc.c
libavformat/yuv4mpegenc.c
+186
-0
No files found.
libavformat/Makefile
View file @
e4dc1000
...
...
@@ -355,8 +355,8 @@ OBJS-$(CONFIG_XA_DEMUXER) += xa.o
OBJS-$(CONFIG_XMV_DEMUXER)
+=
xmv.o
OBJS-$(CONFIG_XWMA_DEMUXER)
+=
xwma.o
OBJS-$(CONFIG_YOP_DEMUXER)
+=
yop.o
OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER)
+=
yuv4mpeg.o
OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER)
+=
yuv4mpeg.o
OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER)
+=
yuv4mpeg
enc
.o
OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER)
+=
yuv4mpeg
dec
.o
# external libraries
OBJS-$(CONFIG_LIBRTMP)
+=
librtmp.o
...
...
libavformat/yuv4mpeg.h
0 → 100644
View file @
e4dc1000
/*
* YUV4MPEG common definitions
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVFORMAT_YUV4MPEG_H
#define AVFORMAT_YUV4MPEG_H
#define Y4M_MAGIC "YUV4MPEG2"
#define Y4M_FRAME_MAGIC "FRAME"
#endif
/* AVFORMAT_YUV4MPEG_H */
libavformat/yuv4mpeg.c
→
libavformat/yuv4mpeg
dec
.c
View file @
e4dc1000
/*
* YUV4MPEG
format
* YUV4MPEG
demuxer
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
* This file is part of Libav.
...
...
@@ -19,184 +19,19 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/pixdesc.h"
#include "avformat.h"
#include "internal.h"
#include "yuv4mpeg.h"
#define Y4M_MAGIC "YUV4MPEG2"
#define
Y4M_FRAME_MAGIC "FRAME"
#define
Y4M_LINE_MAX 256
/* Header size increased to allow room for optional flags */
#define
MAX_YUV4_HEADER 80
#define
MAX_FRAME_HEADER 80
struct
frame_attributes
{
int
interlaced_frame
;
int
top_field_first
;
};
#if CONFIG_YUV4MPEGPIPE_MUXER
static
int
yuv4_generate_header
(
AVFormatContext
*
s
,
char
*
buf
)
{
AVStream
*
st
;
int
width
,
height
;
int
raten
,
rated
,
aspectn
,
aspectd
,
n
;
char
inter
;
const
char
*
colorspace
=
""
;
st
=
s
->
streams
[
0
];
width
=
st
->
codec
->
width
;
height
=
st
->
codec
->
height
;
av_reduce
(
&
raten
,
&
rated
,
st
->
codec
->
time_base
.
den
,
st
->
codec
->
time_base
.
num
,
(
1UL
<<
31
)
-
1
);
aspectn
=
st
->
sample_aspect_ratio
.
num
;
aspectd
=
st
->
sample_aspect_ratio
.
den
;
if
(
aspectn
==
0
&&
aspectd
==
1
)
aspectd
=
0
;
// 0:0 means unknown
inter
=
'p'
;
/* progressive is the default */
if
(
st
->
codec
->
coded_frame
&&
st
->
codec
->
coded_frame
->
interlaced_frame
)
inter
=
st
->
codec
->
coded_frame
->
top_field_first
?
't'
:
'b'
;
switch
(
st
->
codec
->
pix_fmt
)
{
case
AV_PIX_FMT_GRAY8
:
colorspace
=
" Cmono"
;
break
;
case
AV_PIX_FMT_YUV411P
:
colorspace
=
" C411 XYSCSS=411"
;
break
;
case
AV_PIX_FMT_YUV420P
:
switch
(
st
->
codec
->
chroma_sample_location
)
{
case
AVCHROMA_LOC_TOPLEFT
:
colorspace
=
" C420paldv XYSCSS=420PALDV"
;
break
;
case
AVCHROMA_LOC_LEFT
:
colorspace
=
" C420mpeg2 XYSCSS=420MPEG2"
;
break
;
default:
colorspace
=
" C420jpeg XYSCSS=420JPEG"
;
break
;
}
break
;
case
AV_PIX_FMT_YUV422P
:
colorspace
=
" C422 XYSCSS=422"
;
break
;
case
AV_PIX_FMT_YUV444P
:
colorspace
=
" C444 XYSCSS=444"
;
break
;
}
/* construct stream header, if this is the first frame */
n
=
snprintf
(
buf
,
Y4M_LINE_MAX
,
"%s W%d H%d F%d:%d I%c A%d:%d%s
\n
"
,
Y4M_MAGIC
,
width
,
height
,
raten
,
rated
,
inter
,
aspectn
,
aspectd
,
colorspace
);
return
n
;
}
static
int
yuv4_write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
{
AVStream
*
st
=
s
->
streams
[
pkt
->
stream_index
];
AVIOContext
*
pb
=
s
->
pb
;
AVPicture
*
picture
;
int
*
first_pkt
=
s
->
priv_data
;
int
width
,
height
,
h_chroma_shift
,
v_chroma_shift
;
int
i
;
char
buf2
[
Y4M_LINE_MAX
+
1
];
char
buf1
[
20
];
uint8_t
*
ptr
,
*
ptr1
,
*
ptr2
;
picture
=
(
AVPicture
*
)
pkt
->
data
;
/* for the first packet we have to output the header as well */
if
(
*
first_pkt
)
{
*
first_pkt
=
0
;
if
(
yuv4_generate_header
(
s
,
buf2
)
<
0
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Error. YUV4MPEG stream header write failed.
\n
"
);
return
AVERROR
(
EIO
);
}
else
{
avio_write
(
pb
,
buf2
,
strlen
(
buf2
));
}
}
/* construct frame header */
snprintf
(
buf1
,
sizeof
(
buf1
),
"%s
\n
"
,
Y4M_FRAME_MAGIC
);
avio_write
(
pb
,
buf1
,
strlen
(
buf1
));
width
=
st
->
codec
->
width
;
height
=
st
->
codec
->
height
;
ptr
=
picture
->
data
[
0
];
for
(
i
=
0
;
i
<
height
;
i
++
)
{
avio_write
(
pb
,
ptr
,
width
);
ptr
+=
picture
->
linesize
[
0
];
}
if
(
st
->
codec
->
pix_fmt
!=
AV_PIX_FMT_GRAY8
)
{
// Adjust for smaller Cb and Cr planes
av_pix_fmt_get_chroma_sub_sample
(
st
->
codec
->
pix_fmt
,
&
h_chroma_shift
,
&
v_chroma_shift
);
// Shift right, rounding up
width
=
-
(
-
width
>>
h_chroma_shift
);
height
=
-
(
-
height
>>
v_chroma_shift
);
ptr1
=
picture
->
data
[
1
];
ptr2
=
picture
->
data
[
2
];
for
(
i
=
0
;
i
<
height
;
i
++
)
{
/* Cb */
avio_write
(
pb
,
ptr1
,
width
);
ptr1
+=
picture
->
linesize
[
1
];
}
for
(
i
=
0
;
i
<
height
;
i
++
)
{
/* Cr */
avio_write
(
pb
,
ptr2
,
width
);
ptr2
+=
picture
->
linesize
[
2
];
}
}
return
0
;
}
static
int
yuv4_write_header
(
AVFormatContext
*
s
)
{
int
*
first_pkt
=
s
->
priv_data
;
if
(
s
->
nb_streams
!=
1
)
return
AVERROR
(
EIO
);
if
(
s
->
streams
[
0
]
->
codec
->
codec_id
!=
AV_CODEC_ID_RAWVIDEO
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"ERROR: Only rawvideo supported.
\n
"
);
return
AVERROR_INVALIDDATA
;
}
if
(
s
->
streams
[
0
]
->
codec
->
pix_fmt
==
AV_PIX_FMT_YUV411P
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Warning: generating rarely used 4:1:1 YUV "
"stream, some mjpegtools might not work.
\n
"
);
}
else
if
((
s
->
streams
[
0
]
->
codec
->
pix_fmt
!=
AV_PIX_FMT_YUV420P
)
&&
(
s
->
streams
[
0
]
->
codec
->
pix_fmt
!=
AV_PIX_FMT_YUV422P
)
&&
(
s
->
streams
[
0
]
->
codec
->
pix_fmt
!=
AV_PIX_FMT_GRAY8
)
&&
(
s
->
streams
[
0
]
->
codec
->
pix_fmt
!=
AV_PIX_FMT_YUV444P
))
{
av_log
(
s
,
AV_LOG_ERROR
,
"ERROR: yuv4mpeg only handles yuv444p, "
"yuv422p, yuv420p, yuv411p and gray pixel formats. "
"Use -pix_fmt to select one.
\n
"
);
return
AVERROR
(
EIO
);
}
*
first_pkt
=
1
;
return
0
;
}
AVOutputFormat
ff_yuv4mpegpipe_muxer
=
{
.
name
=
"yuv4mpegpipe"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"YUV4MPEG pipe"
),
.
mime_type
=
""
,
.
extensions
=
"y4m"
,
.
priv_data_size
=
sizeof
(
int
),
.
audio_codec
=
AV_CODEC_ID_NONE
,
.
video_codec
=
AV_CODEC_ID_RAWVIDEO
,
.
write_header
=
yuv4_write_header
,
.
write_packet
=
yuv4_write_packet
,
.
flags
=
AVFMT_RAWPICTURE
,
};
#endif
/* Header size increased to allow room for optional flags */
#define MAX_YUV4_HEADER 80
#define MAX_FRAME_HEADER 80
static
int
yuv4_read_header
(
AVFormatContext
*
s
)
{
char
header
[
MAX_YUV4_HEADER
+
10
];
// Include headroom for
...
...
@@ -427,7 +262,6 @@ static int yuv4_probe(AVProbeData *pd)
return
0
;
}
#if CONFIG_YUV4MPEGPIPE_DEMUXER
AVInputFormat
ff_yuv4mpegpipe_demuxer
=
{
.
name
=
"yuv4mpegpipe"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"YUV4MPEG pipe"
),
...
...
@@ -437,4 +271,3 @@ AVInputFormat ff_yuv4mpegpipe_demuxer = {
.
read_packet
=
yuv4_read_packet
,
.
extensions
=
"y4m"
,
};
#endif
libavformat/yuv4mpegenc.c
0 → 100644
View file @
e4dc1000
/*
* YUV4MPEG muxer
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/pixdesc.h"
#include "avformat.h"
#include "internal.h"
#include "yuv4mpeg.h"
#define Y4M_LINE_MAX 256
static
int
yuv4_generate_header
(
AVFormatContext
*
s
,
char
*
buf
)
{
AVStream
*
st
;
int
width
,
height
;
int
raten
,
rated
,
aspectn
,
aspectd
,
n
;
char
inter
;
const
char
*
colorspace
=
""
;
st
=
s
->
streams
[
0
];
width
=
st
->
codec
->
width
;
height
=
st
->
codec
->
height
;
av_reduce
(
&
raten
,
&
rated
,
st
->
codec
->
time_base
.
den
,
st
->
codec
->
time_base
.
num
,
(
1UL
<<
31
)
-
1
);
aspectn
=
st
->
sample_aspect_ratio
.
num
;
aspectd
=
st
->
sample_aspect_ratio
.
den
;
if
(
aspectn
==
0
&&
aspectd
==
1
)
aspectd
=
0
;
// 0:0 means unknown
inter
=
'p'
;
/* progressive is the default */
if
(
st
->
codec
->
coded_frame
&&
st
->
codec
->
coded_frame
->
interlaced_frame
)
inter
=
st
->
codec
->
coded_frame
->
top_field_first
?
't'
:
'b'
;
switch
(
st
->
codec
->
pix_fmt
)
{
case
AV_PIX_FMT_GRAY8
:
colorspace
=
" Cmono"
;
break
;
case
AV_PIX_FMT_YUV411P
:
colorspace
=
" C411 XYSCSS=411"
;
break
;
case
AV_PIX_FMT_YUV420P
:
switch
(
st
->
codec
->
chroma_sample_location
)
{
case
AVCHROMA_LOC_TOPLEFT
:
colorspace
=
" C420paldv XYSCSS=420PALDV"
;
break
;
case
AVCHROMA_LOC_LEFT
:
colorspace
=
" C420mpeg2 XYSCSS=420MPEG2"
;
break
;
default:
colorspace
=
" C420jpeg XYSCSS=420JPEG"
;
break
;
}
break
;
case
AV_PIX_FMT_YUV422P
:
colorspace
=
" C422 XYSCSS=422"
;
break
;
case
AV_PIX_FMT_YUV444P
:
colorspace
=
" C444 XYSCSS=444"
;
break
;
}
/* construct stream header, if this is the first frame */
n
=
snprintf
(
buf
,
Y4M_LINE_MAX
,
"%s W%d H%d F%d:%d I%c A%d:%d%s
\n
"
,
Y4M_MAGIC
,
width
,
height
,
raten
,
rated
,
inter
,
aspectn
,
aspectd
,
colorspace
);
return
n
;
}
static
int
yuv4_write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
{
AVStream
*
st
=
s
->
streams
[
pkt
->
stream_index
];
AVIOContext
*
pb
=
s
->
pb
;
AVPicture
*
picture
;
int
*
first_pkt
=
s
->
priv_data
;
int
width
,
height
,
h_chroma_shift
,
v_chroma_shift
;
int
i
;
char
buf2
[
Y4M_LINE_MAX
+
1
];
char
buf1
[
20
];
uint8_t
*
ptr
,
*
ptr1
,
*
ptr2
;
picture
=
(
AVPicture
*
)
pkt
->
data
;
/* for the first packet we have to output the header as well */
if
(
*
first_pkt
)
{
*
first_pkt
=
0
;
if
(
yuv4_generate_header
(
s
,
buf2
)
<
0
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Error. YUV4MPEG stream header write failed.
\n
"
);
return
AVERROR
(
EIO
);
}
else
{
avio_write
(
pb
,
buf2
,
strlen
(
buf2
));
}
}
/* construct frame header */
snprintf
(
buf1
,
sizeof
(
buf1
),
"%s
\n
"
,
Y4M_FRAME_MAGIC
);
avio_write
(
pb
,
buf1
,
strlen
(
buf1
));
width
=
st
->
codec
->
width
;
height
=
st
->
codec
->
height
;
ptr
=
picture
->
data
[
0
];
for
(
i
=
0
;
i
<
height
;
i
++
)
{
avio_write
(
pb
,
ptr
,
width
);
ptr
+=
picture
->
linesize
[
0
];
}
if
(
st
->
codec
->
pix_fmt
!=
AV_PIX_FMT_GRAY8
)
{
// Adjust for smaller Cb and Cr planes
av_pix_fmt_get_chroma_sub_sample
(
st
->
codec
->
pix_fmt
,
&
h_chroma_shift
,
&
v_chroma_shift
);
// Shift right, rounding up
width
=
-
(
-
width
>>
h_chroma_shift
);
height
=
-
(
-
height
>>
v_chroma_shift
);
ptr1
=
picture
->
data
[
1
];
ptr2
=
picture
->
data
[
2
];
for
(
i
=
0
;
i
<
height
;
i
++
)
{
/* Cb */
avio_write
(
pb
,
ptr1
,
width
);
ptr1
+=
picture
->
linesize
[
1
];
}
for
(
i
=
0
;
i
<
height
;
i
++
)
{
/* Cr */
avio_write
(
pb
,
ptr2
,
width
);
ptr2
+=
picture
->
linesize
[
2
];
}
}
return
0
;
}
static
int
yuv4_write_header
(
AVFormatContext
*
s
)
{
int
*
first_pkt
=
s
->
priv_data
;
if
(
s
->
nb_streams
!=
1
)
return
AVERROR
(
EIO
);
if
(
s
->
streams
[
0
]
->
codec
->
codec_id
!=
AV_CODEC_ID_RAWVIDEO
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"ERROR: Only rawvideo supported.
\n
"
);
return
AVERROR_INVALIDDATA
;
}
if
(
s
->
streams
[
0
]
->
codec
->
pix_fmt
==
AV_PIX_FMT_YUV411P
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Warning: generating rarely used 4:1:1 YUV "
"stream, some mjpegtools might not work.
\n
"
);
}
else
if
((
s
->
streams
[
0
]
->
codec
->
pix_fmt
!=
AV_PIX_FMT_YUV420P
)
&&
(
s
->
streams
[
0
]
->
codec
->
pix_fmt
!=
AV_PIX_FMT_YUV422P
)
&&
(
s
->
streams
[
0
]
->
codec
->
pix_fmt
!=
AV_PIX_FMT_GRAY8
)
&&
(
s
->
streams
[
0
]
->
codec
->
pix_fmt
!=
AV_PIX_FMT_YUV444P
))
{
av_log
(
s
,
AV_LOG_ERROR
,
"ERROR: yuv4mpeg only handles yuv444p, "
"yuv422p, yuv420p, yuv411p and gray pixel formats. "
"Use -pix_fmt to select one.
\n
"
);
return
AVERROR
(
EIO
);
}
*
first_pkt
=
1
;
return
0
;
}
AVOutputFormat
ff_yuv4mpegpipe_muxer
=
{
.
name
=
"yuv4mpegpipe"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"YUV4MPEG pipe"
),
.
mime_type
=
""
,
.
extensions
=
"y4m"
,
.
priv_data_size
=
sizeof
(
int
),
.
audio_codec
=
AV_CODEC_ID_NONE
,
.
video_codec
=
AV_CODEC_ID_RAWVIDEO
,
.
write_header
=
yuv4_write_header
,
.
write_packet
=
yuv4_write_packet
,
.
flags
=
AVFMT_RAWPICTURE
,
};
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