FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
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 <inttypes.h>
23
24
#include "
libavutil/channel_layout.h
"
25
#include "
avformat.h
"
26
#include "
internal.h
"
27
28
#define MVI_FRAC_BITS 10
29
30
#define MVI_AUDIO_STREAM_INDEX 0
31
#define MVI_VIDEO_STREAM_INDEX 1
32
33
typedef
struct
MviDemuxContext
{
34
unsigned
int (*
get_int
)(
AVIOContext
*);
35
uint32_t
audio_data_size
;
36
uint64_t
audio_size_counter
;
37
uint64_t
audio_frame_size
;
38
int
audio_size_left
;
39
int
video_frame_size
;
40
}
MviDemuxContext
;
41
42
static
int
read_header
(
AVFormatContext
*
s
)
43
{
44
MviDemuxContext
*mvi = s->
priv_data
;
45
AVIOContext
*pb = s->
pb
;
46
AVStream
*ast, *vst;
47
unsigned
int
version
, frames_count, msecs_per_frame, player_version;
48
49
ast =
avformat_new_stream
(s, NULL);
50
if
(!ast)
51
return
AVERROR
(ENOMEM);
52
53
vst =
avformat_new_stream
(s, NULL);
54
if
(!vst)
55
return
AVERROR
(ENOMEM);
56
57
if
(
ff_alloc_extradata
(vst->
codec
, 2))
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
<= 1 <<
MVI_FRAC_BITS
- 1) {
100
av_log
(s,
AV_LOG_ERROR
,
101
"Invalid audio_data_size (%"
PRIu32
") or frames_count (%u)\n"
,
102
mvi->
audio_data_size
, frames_count);
103
return
AVERROR_INVALIDDATA
;
104
}
105
106
mvi->
audio_size_counter
= (ast->
codec
->
sample_rate
* 830 / mvi->
audio_frame_size
- 1) * mvi->
audio_frame_size
;
107
mvi->
audio_size_left
= mvi->
audio_data_size
;
108
109
return
0;
110
}
111
112
static
int
read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
113
{
114
int
ret
,
count
;
115
MviDemuxContext
*mvi = s->
priv_data
;
116
AVIOContext
*pb = s->
pb
;
117
118
if
(mvi->
video_frame_size
== 0) {
119
mvi->
video_frame_size
= (mvi->
get_int
)(pb);
120
if
(mvi->
audio_size_left
== 0)
121
return
AVERROR
(EIO);
122
count = (mvi->
audio_size_counter
+ mvi->
audio_frame_size
+ 512) >>
MVI_FRAC_BITS
;
123
if
(count > mvi->
audio_size_left
)
124
count = mvi->
audio_size_left
;
125
if
((ret =
av_get_packet
(pb, pkt, count)) < 0)
126
return
ret;
127
pkt->
stream_index
=
MVI_AUDIO_STREAM_INDEX
;
128
mvi->
audio_size_left
-=
count
;
129
mvi->
audio_size_counter
+= mvi->
audio_frame_size
- (count <<
MVI_FRAC_BITS
);
130
}
else
{
131
if
((ret =
av_get_packet
(pb, pkt, mvi->
video_frame_size
)) < 0)
132
return
ret
;
133
pkt->
stream_index
=
MVI_VIDEO_STREAM_INDEX
;
134
mvi->
video_frame_size
= 0;
135
}
136
return
0;
137
}
138
139
AVInputFormat
ff_mvi_demuxer
= {
140
.
name
=
"mvi"
,
141
.long_name =
NULL_IF_CONFIG_SMALL
(
"Motion Pixels MVI"
),
142
.priv_data_size =
sizeof
(
MviDemuxContext
),
143
.
read_header
=
read_header
,
144
.
read_packet
=
read_packet
,
145
.extensions =
"mvi"
,
146
};
Generated on Fri Dec 5 2014 04:42:12 for FFmpeg by
1.8.2