Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
VideoLAN
x264
Commits
058c3be5
Commit
058c3be5
authored
Mar 08, 2006
by
Loren Merritt
Browse files
cosmetics: muxers -> muxers.c
git-svn-id:
svn://svn.videolan.org/x264/trunk@460
df754926-b1dd-0310-bc7b-ec298dee348c
parent
a34eec24
Changes
4
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
058c3be5
...
...
@@ -64,14 +64,14 @@ libx264.a: .depend $(OBJS) $(OBJASM)
ar rc libx264.a
$(OBJS)
$(OBJASM)
ranlib libx264.a
x264$(EXE)
:
libx264.a
x264.o matroska.o
$(CC)
-o
$@
x264.o matroska.o libx264.a
$(LDFLAGS)
x264$(EXE)
:
x264.o matroska.o
muxers.o libx264.a
$(CC)
-o
$@
$+
$(LDFLAGS)
x264vfw.dll
:
libx264.a $(wildcard vfw/*.c vfw/*.h)
make
-C
vfw/build/cygwin
checkasm
:
tools/checkasm.o libx264.a
$(CC)
-o
$@
$
<
libx264.a
$(LDFLAGS)
$(CC)
-o
$@
$
+
$(LDFLAGS)
common/amd64/*.o
:
common/amd64/amd64inc.asm
common/i386/*.o
:
common/i386/i386inc.asm
...
...
@@ -81,7 +81,7 @@ common/i386/*.o: common/i386/i386inc.asm
.depend
:
config.mak
rm
-f
.depend
# Hacky - because gcc 2.9x doesn't have -MT
$(foreach
SRC,
$(SRCS)
x264.c
matroska.c,
(
echo
-n
"`dirname $(SRC)`/"
&&
$(CC)
$(CFLAGS)
$(SRC)
-MM
-g0
)
1>>
.depend;)
$(foreach
SRC,
$(SRCS)
x264.c
matroska.c
muxers.c
,
(
echo
-n
"`dirname $(SRC)`/"
&&
$(CC)
$(CFLAGS)
$(SRC)
-MM
-g0
)
1>>
.depend;)
config.mak
:
$(wildcard .svn/entries */.svn/entries */*/.svn/entries)
./configure
$(CONFIGURE_ARGS)
...
...
muxers.c
0 → 100644
View file @
058c3be5
/*****************************************************************************
* muxers.c: h264 file i/o plugins
*****************************************************************************
* Copyright (C) 2003-2006 x264 project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
#include
<stdio.h>
#include
<string.h>
#include
"common/common.h"
#include
"x264.h"
#include
"matroska.h"
#include
"muxers.h"
#ifndef _MSC_VER
#include
"config.h"
#endif
#ifdef AVIS_INPUT
#include
<windows.h>
#include
<vfw.h>
#endif
#ifdef MP4_OUTPUT
#include
<gpac/isomedia.h>
#endif
/* raw 420 yuv file operation */
int
open_file_yuv
(
char
*
psz_filename
,
hnd_t
*
p_handle
,
x264_param_t
*
p_param
)
{
if
((
*
p_handle
=
fopen
(
psz_filename
,
"rb"
))
==
NULL
)
return
-
1
;
return
0
;
}
int
get_frame_total_yuv
(
hnd_t
handle
,
int
i_width
,
int
i_height
)
{
FILE
*
f
=
(
FILE
*
)
handle
;
int
i_frame_total
=
0
;
if
(
!
fseek
(
f
,
0
,
SEEK_END
)
)
{
uint64_t
i_size
=
ftell
(
f
);
fseek
(
f
,
0
,
SEEK_SET
);
i_frame_total
=
(
int
)(
i_size
/
(
i_width
*
i_height
*
3
/
2
));
}
return
i_frame_total
;
}
int
read_frame_yuv
(
x264_picture_t
*
p_pic
,
hnd_t
handle
,
int
i_frame
,
int
i_width
,
int
i_height
)
{
static
int
prev_frame
=
-
1
;
FILE
*
f
=
(
FILE
*
)
handle
;
if
(
i_frame
!=
prev_frame
+
1
)
if
(
fseek
(
f
,
(
uint64_t
)
i_frame
*
i_width
*
i_height
*
3
/
2
,
SEEK_SET
)
)
return
-
1
;
if
(
fread
(
p_pic
->
img
.
plane
[
0
],
1
,
i_width
*
i_height
,
f
)
<=
0
||
fread
(
p_pic
->
img
.
plane
[
1
],
1
,
i_width
*
i_height
/
4
,
f
)
<=
0
||
fread
(
p_pic
->
img
.
plane
[
2
],
1
,
i_width
*
i_height
/
4
,
f
)
<=
0
)
return
-
1
;
prev_frame
=
i_frame
;
return
0
;
}
int
close_file_yuv
(
hnd_t
handle
)
{
if
(
handle
==
NULL
)
return
0
;
return
fclose
((
FILE
*
)
handle
);
}
/* avs/avi input file support under cygwin */
#ifdef AVIS_INPUT
int
gcd
(
int
a
,
int
b
)
{
int
c
;
while
(
1
)
{
c
=
a
%
b
;
if
(
!
c
)
return
b
;
a
=
b
;
b
=
c
;
}
}
int
open_file_avis
(
char
*
psz_filename
,
hnd_t
*
p_handle
,
x264_param_t
*
p_param
)
{
AVISTREAMINFO
info
;
PAVISTREAM
p_avi
=
NULL
;
int
i
;
*
p_handle
=
NULL
;
AVIFileInit
();
if
(
AVIStreamOpenFromFile
(
&
p_avi
,
psz_filename
,
streamtypeVIDEO
,
0
,
OF_READ
,
NULL
)
)
{
AVIFileExit
();
return
-
1
;
}
if
(
AVIStreamInfo
(
p_avi
,
&
info
,
sizeof
(
AVISTREAMINFO
))
)
{
AVIStreamRelease
(
p_avi
);
AVIFileExit
();
return
-
1
;
}
// check input format
if
(
info
.
fccHandler
!=
MAKEFOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
))
{
fprintf
(
stderr
,
"avis [error]: unsupported input format (%c%c%c%c)
\n
"
,
(
char
)(
info
.
fccHandler
&
0xff
),
(
char
)((
info
.
fccHandler
>>
8
)
&
0xff
),
(
char
)((
info
.
fccHandler
>>
16
)
&
0xff
),
(
char
)((
info
.
fccHandler
>>
24
))
);
AVIStreamRelease
(
p_avi
);
AVIFileExit
();
return
-
1
;
}
p_param
->
i_width
=
info
.
rcFrame
.
right
-
info
.
rcFrame
.
left
;
p_param
->
i_height
=
info
.
rcFrame
.
bottom
-
info
.
rcFrame
.
top
;
i
=
gcd
(
info
.
dwRate
,
info
.
dwScale
);
p_param
->
i_fps_den
=
info
.
dwScale
/
i
;
p_param
->
i_fps_num
=
info
.
dwRate
/
i
;
fprintf
(
stderr
,
"avis [info]: %dx%d @ %.2f fps (%d frames)
\n
"
,
p_param
->
i_width
,
p_param
->
i_height
,
(
double
)
p_param
->
i_fps_num
/
(
double
)
p_param
->
i_fps_den
,
(
int
)
info
.
dwLength
);
*
p_handle
=
(
hnd_t
)
p_avi
;
return
0
;
}
int
get_frame_total_avis
(
hnd_t
handle
,
int
i_width
,
int
i_height
)
{
PAVISTREAM
p_avi
=
(
PAVISTREAM
)
handle
;
AVISTREAMINFO
info
;
if
(
AVIStreamInfo
(
p_avi
,
&
info
,
sizeof
(
AVISTREAMINFO
))
)
return
-
1
;
return
info
.
dwLength
;
}
int
read_frame_avis
(
x264_picture_t
*
p_pic
,
hnd_t
handle
,
int
i_frame
,
int
i_width
,
int
i_height
)
{
PAVISTREAM
p_avi
=
(
PAVISTREAM
)
handle
;
p_pic
->
img
.
i_csp
=
X264_CSP_YV12
;
if
(
AVIStreamRead
(
p_avi
,
i_frame
,
1
,
p_pic
->
img
.
plane
[
0
],
i_width
*
i_height
*
3
/
2
,
NULL
,
NULL
)
)
return
-
1
;
return
0
;
}
int
close_file_avis
(
hnd_t
handle
)
{
PAVISTREAM
p_avi
=
(
PAVISTREAM
)
handle
;
AVIStreamRelease
(
p_avi
);
AVIFileExit
();
return
0
;
}
#endif
int
open_file_bsf
(
char
*
psz_filename
,
hnd_t
*
p_handle
)
{
if
((
*
p_handle
=
fopen
(
psz_filename
,
"w+b"
))
==
NULL
)
return
-
1
;
return
0
;
}
int
set_param_bsf
(
hnd_t
handle
,
x264_param_t
*
p_param
)
{
return
0
;
}
int
write_nalu_bsf
(
hnd_t
handle
,
uint8_t
*
p_nalu
,
int
i_size
)
{
if
(
fwrite
(
p_nalu
,
i_size
,
1
,
(
FILE
*
)
handle
)
>
0
)
return
i_size
;
return
-
1
;
}
int
set_eop_bsf
(
hnd_t
handle
,
x264_picture_t
*
p_picture
)
{
return
0
;
}
int
close_file_bsf
(
hnd_t
handle
)
{
if
((
handle
==
NULL
)
||
(
handle
==
stdout
))
return
0
;
return
fclose
((
FILE
*
)
handle
);
}
/* -- mp4 muxing support ------------------------------------------------- */
#ifdef MP4_OUTPUT
typedef
struct
{
GF_ISOFile
*
p_file
;
GF_AVCConfig
*
p_config
;
GF_ISOSample
*
p_sample
;
int
i_track
;
int
i_descidx
;
int
i_time_inc
;
int
i_time_res
;
int
i_numframe
;
int
i_init_delay
;
uint8_t
b_sps
;
uint8_t
b_pps
;
}
mp4_t
;
void
recompute_bitrate_mp4
(
GF_ISOFile
*
p_file
,
int
i_track
)
{
u32
i
,
count
,
di
,
timescale
,
time_wnd
,
rate
;
u64
offset
;
Double
br
;
GF_ESD
*
esd
;
esd
=
gf_isom_get_esd
(
p_file
,
i_track
,
1
);
if
(
!
esd
)
return
;
esd
->
decoderConfig
->
avgBitrate
=
0
;
esd
->
decoderConfig
->
maxBitrate
=
0
;
rate
=
time_wnd
=
0
;
timescale
=
gf_isom_get_media_timescale
(
p_file
,
i_track
);
count
=
gf_isom_get_sample_count
(
p_file
,
i_track
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
GF_ISOSample
*
samp
=
gf_isom_get_sample_info
(
p_file
,
i_track
,
i
+
1
,
&
di
,
&
offset
);
if
(
samp
->
dataLength
>
esd
->
decoderConfig
->
bufferSizeDB
)
esd
->
decoderConfig
->
bufferSizeDB
=
samp
->
dataLength
;
if
(
esd
->
decoderConfig
->
bufferSizeDB
<
samp
->
dataLength
)
esd
->
decoderConfig
->
bufferSizeDB
=
samp
->
dataLength
;
esd
->
decoderConfig
->
avgBitrate
+=
samp
->
dataLength
;
rate
+=
samp
->
dataLength
;
if
(
samp
->
DTS
>
time_wnd
+
timescale
)
{
if
(
rate
>
esd
->
decoderConfig
->
maxBitrate
)
esd
->
decoderConfig
->
maxBitrate
=
rate
;
time_wnd
=
samp
->
DTS
;
rate
=
0
;
}
gf_isom_sample_del
(
&
samp
);
}
br
=
(
Double
)
(
s64
)
gf_isom_get_media_duration
(
p_file
,
i_track
);
br
/=
timescale
;
esd
->
decoderConfig
->
avgBitrate
=
(
u32
)
(
esd
->
decoderConfig
->
avgBitrate
/
br
);
/*move to bps*/
esd
->
decoderConfig
->
avgBitrate
*=
8
;
esd
->
decoderConfig
->
maxBitrate
*=
8
;
gf_isom_change_mpeg4_description
(
p_file
,
i_track
,
1
,
esd
);
gf_odf_desc_del
((
GF_Descriptor
*
)
esd
);
}
int
close_file_mp4
(
hnd_t
handle
)
{
mp4_t
*
p_mp4
=
(
mp4_t
*
)
handle
;
if
(
p_mp4
==
NULL
)
return
0
;
if
(
p_mp4
->
p_config
)
gf_odf_avc_cfg_del
(
p_mp4
->
p_config
);
if
(
p_mp4
->
p_sample
)
{
if
(
p_mp4
->
p_sample
->
data
)
free
(
p_mp4
->
p_sample
->
data
);
gf_isom_sample_del
(
&
p_mp4
->
p_sample
);
}
if
(
p_mp4
->
p_file
)
{
recompute_bitrate_mp4
(
p_mp4
->
p_file
,
p_mp4
->
i_track
);
gf_isom_set_pl_indication
(
p_mp4
->
p_file
,
GF_ISOM_PL_VISUAL
,
0x15
);
gf_isom_set_storage_mode
(
p_mp4
->
p_file
,
GF_ISOM_STORE_FLAT
);
gf_isom_close
(
p_mp4
->
p_file
);
}
free
(
p_mp4
);
return
0
;
}
int
open_file_mp4
(
char
*
psz_filename
,
hnd_t
*
p_handle
)
{
mp4_t
*
p_mp4
;
*
p_handle
=
NULL
;
if
((
p_mp4
=
(
mp4_t
*
)
malloc
(
sizeof
(
mp4_t
)))
==
NULL
)
return
-
1
;
memset
(
p_mp4
,
0
,
sizeof
(
mp4_t
));
p_mp4
->
p_file
=
gf_isom_open
(
psz_filename
,
GF_ISOM_OPEN_WRITE
,
NULL
);
if
((
p_mp4
->
p_sample
=
gf_isom_sample_new
())
==
NULL
)
{
close_file_mp4
(
p_mp4
);
return
-
1
;
}
gf_isom_set_brand_info
(
p_mp4
->
p_file
,
GF_ISOM_BRAND_AVC1
,
0
);
*
p_handle
=
p_mp4
;
return
0
;
}
int
set_param_mp4
(
hnd_t
handle
,
x264_param_t
*
p_param
)
{
mp4_t
*
p_mp4
=
(
mp4_t
*
)
handle
;
p_mp4
->
i_track
=
gf_isom_new_track
(
p_mp4
->
p_file
,
0
,
GF_ISOM_MEDIA_VISUAL
,
p_param
->
i_fps_num
);
p_mp4
->
p_config
=
gf_odf_avc_cfg_new
();
gf_isom_avc_config_new
(
p_mp4
->
p_file
,
p_mp4
->
i_track
,
p_mp4
->
p_config
,
NULL
,
NULL
,
&
p_mp4
->
i_descidx
);
gf_isom_set_track_enabled
(
p_mp4
->
p_file
,
p_mp4
->
i_track
,
1
);
gf_isom_set_visual_info
(
p_mp4
->
p_file
,
p_mp4
->
i_track
,
p_mp4
->
i_descidx
,
p_param
->
i_width
,
p_param
->
i_height
);
p_mp4
->
p_sample
->
data
=
(
char
*
)
malloc
(
p_param
->
i_width
*
p_param
->
i_height
*
3
/
2
);
if
(
p_mp4
->
p_sample
->
data
==
NULL
)
return
-
1
;
p_mp4
->
i_time_res
=
p_param
->
i_fps_num
;
p_mp4
->
i_time_inc
=
p_param
->
i_fps_den
;
p_mp4
->
i_init_delay
=
p_param
->
i_bframe
?
(
p_param
->
b_bframe_pyramid
?
2
:
1
)
:
0
;
p_mp4
->
i_init_delay
*=
p_mp4
->
i_time_inc
;
fprintf
(
stderr
,
"mp4 [info]: initial delay %d (scale %d)
\n
"
,
p_mp4
->
i_init_delay
,
p_mp4
->
i_time_res
);
return
0
;
}
int
write_nalu_mp4
(
hnd_t
handle
,
uint8_t
*
p_nalu
,
int
i_size
)
{
mp4_t
*
p_mp4
=
(
mp4_t
*
)
handle
;
GF_AVCConfigSlot
*
p_slot
;
uint8_t
type
=
p_nalu
[
4
]
&
0x1f
;
int
psize
;
switch
(
type
)
{
// sps
case
0x07
:
if
(
!
p_mp4
->
b_sps
)
{
p_mp4
->
p_config
->
configurationVersion
=
1
;
p_mp4
->
p_config
->
AVCProfileIndication
=
p_nalu
[
5
];
p_mp4
->
p_config
->
profile_compatibility
=
p_nalu
[
6
];
p_mp4
->
p_config
->
AVCLevelIndication
=
p_nalu
[
7
];
p_slot
=
(
GF_AVCConfigSlot
*
)
malloc
(
sizeof
(
GF_AVCConfigSlot
));
p_slot
->
size
=
i_size
-
4
;
p_slot
->
data
=
(
char
*
)
malloc
(
p_slot
->
size
);
memcpy
(
p_slot
->
data
,
p_nalu
+
4
,
i_size
-
4
);
gf_list_add
(
p_mp4
->
p_config
->
sequenceParameterSets
,
p_slot
);
p_slot
=
NULL
;
p_mp4
->
b_sps
=
1
;
}
break
;
// pps
case
0x08
:
if
(
!
p_mp4
->
b_pps
)
{
p_slot
=
(
GF_AVCConfigSlot
*
)
malloc
(
sizeof
(
GF_AVCConfigSlot
));
p_slot
->
size
=
i_size
-
4
;
p_slot
->
data
=
(
char
*
)
malloc
(
p_slot
->
size
);
memcpy
(
p_slot
->
data
,
p_nalu
+
4
,
i_size
-
4
);
gf_list_add
(
p_mp4
->
p_config
->
pictureParameterSets
,
p_slot
);
p_slot
=
NULL
;
p_mp4
->
b_pps
=
1
;
if
(
p_mp4
->
b_sps
)
gf_isom_avc_config_update
(
p_mp4
->
p_file
,
p_mp4
->
i_track
,
1
,
p_mp4
->
p_config
);
}
break
;
// slice, sei
case
0x1
:
case
0x5
:
case
0x6
:
psize
=
i_size
-
4
;
memcpy
(
p_mp4
->
p_sample
->
data
+
p_mp4
->
p_sample
->
dataLength
,
p_nalu
,
i_size
);
p_mp4
->
p_sample
->
data
[
p_mp4
->
p_sample
->
dataLength
+
0
]
=
(
psize
>>
24
)
&
0xff
;
p_mp4
->
p_sample
->
data
[
p_mp4
->
p_sample
->
dataLength
+
1
]
=
(
psize
>>
16
)
&
0xff
;
p_mp4
->
p_sample
->
data
[
p_mp4
->
p_sample
->
dataLength
+
2
]
=
(
psize
>>
8
)
&
0xff
;
p_mp4
->
p_sample
->
data
[
p_mp4
->
p_sample
->
dataLength
+
3
]
=
(
psize
>>
0
)
&
0xff
;
p_mp4
->
p_sample
->
dataLength
+=
i_size
;
break
;
}
return
i_size
;
}
int
set_eop_mp4
(
hnd_t
handle
,
x264_picture_t
*
p_picture
)
{
mp4_t
*
p_mp4
=
(
mp4_t
*
)
handle
;
uint64_t
dts
=
(
uint64_t
)
p_mp4
->
i_numframe
*
p_mp4
->
i_time_inc
;
uint64_t
pts
=
(
uint64_t
)
p_picture
->
i_pts
;
int32_t
offset
=
p_mp4
->
i_init_delay
+
pts
-
dts
;
p_mp4
->
p_sample
->
IsRAP
=
p_picture
->
i_type
==
X264_TYPE_IDR
?
1
:
0
;
p_mp4
->
p_sample
->
DTS
=
dts
;
p_mp4
->
p_sample
->
CTS_Offset
=
offset
;
gf_isom_add_sample
(
p_mp4
->
p_file
,
p_mp4
->
i_track
,
p_mp4
->
i_descidx
,
p_mp4
->
p_sample
);
p_mp4
->
p_sample
->
dataLength
=
0
;
p_mp4
->
i_numframe
++
;
return
0
;
}
#endif
/* -- mkv muxing support ------------------------------------------------- */
typedef
struct
{
mk_Writer
*
w
;
uint8_t
*
sps
,
*
pps
;
int
sps_len
,
pps_len
;
int
width
,
height
,
d_width
,
d_height
;
int64_t
frame_duration
;
int
fps_num
;
int
b_header_written
;
char
b_writing_frame
;
}
mkv_t
;
int
write_header_mkv
(
mkv_t
*
p_mkv
)
{
int
ret
;
uint8_t
*
avcC
;
int
avcC_len
;
if
(
p_mkv
->
sps
==
NULL
||
p_mkv
->
pps
==
NULL
||
p_mkv
->
width
==
0
||
p_mkv
->
height
==
0
||
p_mkv
->
d_width
==
0
||
p_mkv
->
d_height
==
0
)
return
-
1
;
avcC_len
=
5
+
1
+
2
+
p_mkv
->
sps_len
+
1
+
2
+
p_mkv
->
pps_len
;
avcC
=
malloc
(
avcC_len
);
if
(
avcC
==
NULL
)
return
-
1
;
avcC
[
0
]
=
1
;
avcC
[
1
]
=
p_mkv
->
sps
[
1
];
avcC
[
2
]
=
p_mkv
->
sps
[
2
];
avcC
[
3
]
=
p_mkv
->
sps
[
3
];
avcC
[
4
]
=
0xff
;
// nalu size length is four bytes
avcC
[
5
]
=
0xe1
;
// one sps
avcC
[
6
]
=
p_mkv
->
sps_len
>>
8
;
avcC
[
7
]
=
p_mkv
->
sps_len
;
memcpy
(
avcC
+
8
,
p_mkv
->
sps
,
p_mkv
->
sps_len
);
avcC
[
8
+
p_mkv
->
sps_len
]
=
1
;
// one pps
avcC
[
9
+
p_mkv
->
sps_len
]
=
p_mkv
->
pps_len
>>
8
;
avcC
[
10
+
p_mkv
->
sps_len
]
=
p_mkv
->
pps_len
;
memcpy
(
avcC
+
11
+
p_mkv
->
sps_len
,
p_mkv
->
pps
,
p_mkv
->
pps_len
);
ret
=
mk_writeHeader
(
p_mkv
->
w
,
"x264"
,
"V_MPEG4/ISO/AVC"
,
avcC
,
avcC_len
,
p_mkv
->
frame_duration
,
50000
,
p_mkv
->
width
,
p_mkv
->
height
,
p_mkv
->
d_width
,
p_mkv
->
d_height
);
free
(
avcC
);
p_mkv
->
b_header_written
=
1
;
return
ret
;
}
int
open_file_mkv
(
char
*
psz_filename
,
hnd_t
*
p_handle
)
{
mkv_t
*
p_mkv
;
*
p_handle
=
NULL
;
p_mkv
=
malloc
(
sizeof
(
*
p_mkv
));
if
(
p_mkv
==
NULL
)
return
-
1
;
memset
(
p_mkv
,
0
,
sizeof
(
*
p_mkv
));
p_mkv
->
w
=
mk_createWriter
(
psz_filename
);
if
(
p_mkv
->
w
==
NULL
)
{
free
(
p_mkv
);
return
-
1
;
}
*
p_handle
=
p_mkv
;
return
0
;
}
int
set_param_mkv
(
hnd_t
handle
,
x264_param_t
*
p_param
)
{
mkv_t
*
p_mkv
=
handle
;
int64_t
dw
,
dh
;
if
(
p_param
->
i_fps_num
>
0
)
{
p_mkv
->
frame_duration
=
(
int64_t
)
p_param
->
i_fps_den
*
(
int64_t
)
1000000000
/
p_param
->
i_fps_num
;
p_mkv
->
fps_num
=
p_param
->
i_fps_num
;
}
else
{
p_mkv
->
frame_duration
=
0
;
p_mkv
->
fps_num
=
1
;
}
p_mkv
->
width
=
p_param
->
i_width
;
p_mkv
->
height
=
p_param
->
i_height
;
if
(
p_param
->
vui
.
i_sar_width
&&
p_param
->
vui
.
i_sar_height
)
{
dw
=
(
int64_t
)
p_param
->
i_width
*
p_param
->
vui
.
i_sar_width
;
dh
=
(
int64_t
)
p_param
->
i_height
*
p_param
->
vui
.
i_sar_height
;
}
else
{
dw
=
p_param
->
i_width
;
dh
=
p_param
->
i_height
;
}
if
(
dw
>
0
&&
dh
>
0
)
{
int64_t
a
=
dw
,
b
=
dh
;
for
(;;)
{
int64_t
c
=
a
%
b
;
if
(
c
==
0
)
break
;
a
=
b
;
b
=
c
;
}
dw
/=
b
;
dh
/=
b
;
}
p_mkv
->
d_width
=
(
int
)
dw
;
p_mkv
->
d_height
=
(
int
)
dh
;