Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
mvi.c
Go to the documentation of this file.
1
/*
2
* Motion Pixels MVI Demuxer
3
* Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net)
4
*
5
* This file is part of Libav.
6
*
7
* Libav is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* Libav is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "
libavutil/channel_layout.h
"
23
#include "
avformat.h
"
24
#include "
internal.h
"
25
26
#define MVI_FRAC_BITS 10
27
28
#define MVI_AUDIO_STREAM_INDEX 0
29
#define MVI_VIDEO_STREAM_INDEX 1
30
31
typedef
struct
MviDemuxContext
{
32
unsigned
int (*
get_int
)(
AVIOContext
*);
33
uint32_t
audio_data_size
;
34
uint64_t
audio_size_counter
;
35
uint64_t
audio_frame_size
;
36
int
audio_size_left
;
37
int
video_frame_size
;
38
}
MviDemuxContext
;
39
40
static
int
read_header
(
AVFormatContext
*s)
41
{
42
MviDemuxContext
*mvi = s->
priv_data
;
43
AVIOContext
*pb = s->
pb
;
44
AVStream
*ast, *vst;
45
unsigned
int
version
, frames_count, msecs_per_frame, player_version;
46
47
ast =
avformat_new_stream
(s,
NULL
);
48
if
(!ast)
49
return
AVERROR
(ENOMEM);
50
51
vst =
avformat_new_stream
(s,
NULL
);
52
if
(!vst)
53
return
AVERROR
(ENOMEM);
54
55
vst->
codec
->
extradata_size
= 2;
56
vst->
codec
->
extradata
=
av_mallocz
(2 +
FF_INPUT_BUFFER_PADDING_SIZE
);
57
58
version =
avio_r8
(pb);
59
vst->
codec
->
extradata
[0] =
avio_r8
(pb);
60
vst->
codec
->
extradata
[1] =
avio_r8
(pb);
61
frames_count =
avio_rl32
(pb);
62
msecs_per_frame =
avio_rl32
(pb);
63
vst->
codec
->
width
=
avio_rl16
(pb);
64
vst->
codec
->
height
=
avio_rl16
(pb);
65
avio_r8
(pb);
66
ast->
codec
->
sample_rate
=
avio_rl16
(pb);
67
mvi->
audio_data_size
=
avio_rl32
(pb);
68
avio_r8
(pb);
69
player_version =
avio_rl32
(pb);
70
avio_rl16
(pb);
71
avio_r8
(pb);
72
73
if
(frames_count == 0 || mvi->
audio_data_size
== 0)
74
return
AVERROR_INVALIDDATA
;
75
76
if
(version != 7 || player_version > 213) {
77
av_log
(s,
AV_LOG_ERROR
,
"unhandled version (%d,%d)\n"
, version, player_version);
78
return
AVERROR_INVALIDDATA
;
79
}
80
81
avpriv_set_pts_info
(ast, 64, 1, ast->
codec
->
sample_rate
);
82
ast->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
83
ast->
codec
->
codec_id
=
AV_CODEC_ID_PCM_U8
;
84
ast->
codec
->
channels
= 1;
85
ast->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
86
ast->
codec
->
bits_per_coded_sample
= 8;
87
ast->
codec
->
bit_rate
= ast->
codec
->
sample_rate
* 8;
88
89
avpriv_set_pts_info
(vst, 64, msecs_per_frame, 1000000);
90
vst->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
91
vst->
codec
->
codec_id
=
AV_CODEC_ID_MOTIONPIXELS
;
92
93
mvi->
get_int
= (vst->
codec
->
width
* vst->
codec
->
height
< (1 << 16)) ?
avio_rl16
:
avio_rl24
;
94
95
mvi->
audio_frame_size
= ((uint64_t)mvi->
audio_data_size
<<
MVI_FRAC_BITS
) / frames_count;
96
mvi->
audio_size_counter
= (ast->
codec
->
sample_rate
* 830 / mvi->
audio_frame_size
- 1) * mvi->
audio_frame_size
;
97
mvi->
audio_size_left
= mvi->
audio_data_size
;
98
99
return
0;
100
}
101
102
static
int
read_packet
(
AVFormatContext
*s,
AVPacket
*pkt)
103
{
104
int
ret, count;
105
MviDemuxContext
*mvi = s->
priv_data
;
106
AVIOContext
*pb = s->
pb
;
107
108
if
(mvi->
video_frame_size
== 0) {
109
mvi->
video_frame_size
= (mvi->
get_int
)(pb);
110
if
(mvi->
audio_size_left
== 0)
111
return
AVERROR
(EIO);
112
count = (mvi->
audio_size_counter
+ mvi->
audio_frame_size
+ 512) >>
MVI_FRAC_BITS
;
113
if
(count > mvi->
audio_size_left
)
114
count = mvi->
audio_size_left
;
115
if
((ret =
av_get_packet
(pb, pkt, count)) < 0)
116
return
ret;
117
pkt->
stream_index
=
MVI_AUDIO_STREAM_INDEX
;
118
mvi->
audio_size_left
-= count;
119
mvi->
audio_size_counter
+= mvi->
audio_frame_size
- (count <<
MVI_FRAC_BITS
);
120
}
else
{
121
if
((ret =
av_get_packet
(pb, pkt, mvi->
video_frame_size
)) < 0)
122
return
ret;
123
pkt->
stream_index
=
MVI_VIDEO_STREAM_INDEX
;
124
mvi->
video_frame_size
= 0;
125
}
126
return
0;
127
}
128
129
AVInputFormat
ff_mvi_demuxer
= {
130
.
name
=
"mvi"
,
131
.long_name =
NULL_IF_CONFIG_SMALL
(
"Motion Pixels MVI"
),
132
.priv_data_size =
sizeof
(
MviDemuxContext
),
133
.
read_header
=
read_header
,
134
.
read_packet
=
read_packet
,
135
.extensions =
"mvi"
,
136
};