FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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 FFmpeg.
6
*
7
* FFmpeg 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
* FFmpeg 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 FFmpeg; 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
if
(!vst->
codec
->
extradata
)
58
return
AVERROR
(ENOMEM);
59
60
version =
avio_r8
(pb);
61
vst->
codec
->
extradata
[0] =
avio_r8
(pb);
62
vst->
codec
->
extradata
[1] =
avio_r8
(pb);
63
frames_count =
avio_rl32
(pb);
64
msecs_per_frame =
avio_rl32
(pb);
65
vst->
codec
->
width
=
avio_rl16
(pb);
66
vst->
codec
->
height
=
avio_rl16
(pb);
67
avio_r8
(pb);
68
ast->
codec
->
sample_rate
=
avio_rl16
(pb);
69
mvi->
audio_data_size
=
avio_rl32
(pb);
70
avio_r8
(pb);
71
player_version =
avio_rl32
(pb);
72
avio_rl16
(pb);
73
avio_r8
(pb);
74
75
if
(frames_count == 0 || mvi->
audio_data_size
== 0)
76
return
AVERROR_INVALIDDATA
;
77
78
if
(version != 7 || player_version > 213) {
79
av_log
(s,
AV_LOG_ERROR
,
"unhandled version (%d,%d)\n"
, version, player_version);
80
return
AVERROR_INVALIDDATA
;
81
}
82
83
avpriv_set_pts_info
(ast, 64, 1, ast->
codec
->
sample_rate
);
84
ast->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
85
ast->
codec
->
codec_id
=
AV_CODEC_ID_PCM_U8
;
86
ast->
codec
->
channels
= 1;
87
ast->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
88
ast->
codec
->
bits_per_coded_sample
= 8;
89
ast->
codec
->
bit_rate
= ast->
codec
->
sample_rate
* 8;
90
91
avpriv_set_pts_info
(vst, 64, msecs_per_frame, 1000000);
92
vst->
avg_frame_rate
=
av_inv_q
(vst->
time_base
);
93
vst->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
94
vst->
codec
->
codec_id
=
AV_CODEC_ID_MOTIONPIXELS
;
95
96
mvi->
get_int
= (vst->
codec
->
width
* vst->
codec
->
height
< (1 << 16)) ?
avio_rl16
:
avio_rl24
;
97
98
mvi->
audio_frame_size
= ((uint64_t)mvi->
audio_data_size
<<
MVI_FRAC_BITS
) / frames_count;
99
if
(!mvi->
audio_frame_size
) {
100
av_log
(s,
AV_LOG_ERROR
,
"audio_frame_size is 0\n"
);
101
return
AVERROR_INVALIDDATA
;
102
}
103
mvi->
audio_size_counter
= (ast->
codec
->
sample_rate
* 830 / mvi->
audio_frame_size
- 1) * mvi->
audio_frame_size
;
104
mvi->
audio_size_left
= mvi->
audio_data_size
;
105
106
return
0;
107
}
108
109
static
int
read_packet
(
AVFormatContext
*s,
AVPacket
*
pkt
)
110
{
111
int
ret, count;
112
MviDemuxContext
*mvi = s->
priv_data
;
113
AVIOContext
*pb = s->
pb
;
114
115
if
(mvi->
video_frame_size
== 0) {
116
mvi->
video_frame_size
= (mvi->
get_int
)(pb);
117
if
(mvi->
audio_size_left
== 0)
118
return
AVERROR
(EIO);
119
count = (mvi->
audio_size_counter
+ mvi->
audio_frame_size
+ 512) >>
MVI_FRAC_BITS
;
120
if
(count > mvi->
audio_size_left
)
121
count = mvi->
audio_size_left
;
122
if
((ret =
av_get_packet
(pb, pkt, count)) < 0)
123
return
ret;
124
pkt->
stream_index
=
MVI_AUDIO_STREAM_INDEX
;
125
mvi->
audio_size_left
-= count;
126
mvi->
audio_size_counter
+= mvi->
audio_frame_size
- (count <<
MVI_FRAC_BITS
);
127
}
else
{
128
if
((ret =
av_get_packet
(pb, pkt, mvi->
video_frame_size
)) < 0)
129
return
ret;
130
pkt->
stream_index
=
MVI_VIDEO_STREAM_INDEX
;
131
mvi->
video_frame_size
= 0;
132
}
133
return
0;
134
}
135
136
AVInputFormat
ff_mvi_demuxer
= {
137
.
name
=
"mvi"
,
138
.long_name =
NULL_IF_CONFIG_SMALL
(
"Motion Pixels MVI"
),
139
.priv_data_size =
sizeof
(
MviDemuxContext
),
140
.
read_header
=
read_header
,
141
.
read_packet
=
read_packet
,
142
.extensions =
"mvi"
,
143
};
Generated on Sat May 25 2013 04:01:18 for FFmpeg by
1.8.2