Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
lmlm4.c
Go to the documentation of this file.
1
/*
2
* Linux Media Labs MPEG-4 demuxer
3
* Copyright (c) 2008 Ivo van Poorten
4
*
5
* Due to a lack of sample files, only files with one channel are supported.
6
* u-law and ADPCM audio are unsupported for the same reason.
7
*
8
* This file is part of Libav.
9
*
10
* Libav is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU Lesser General Public
12
* License as published by the Free Software Foundation; either
13
* version 2.1 of the License, or (at your option) any later version.
14
*
15
* Libav is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
* Lesser General Public License for more details.
19
*
20
* You should have received a copy of the GNU Lesser General Public
21
* License along with Libav; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
*/
24
25
#include "
libavutil/intreadwrite.h
"
26
#include "
avformat.h
"
27
#include "
internal.h
"
28
29
#define LMLM4_I_FRAME 0x00
30
#define LMLM4_P_FRAME 0x01
31
#define LMLM4_B_FRAME 0x02
32
#define LMLM4_INVALID 0x03
33
#define LMLM4_MPEG1L2 0x04
34
35
#define LMLM4_MAX_PACKET_SIZE 1024 * 1024
36
37
static
int
lmlm4_probe
(
AVProbeData
* pd) {
38
unsigned
char
*buf = pd->
buf
;
39
unsigned
int
frame_type, packet_size;
40
41
frame_type =
AV_RB16
(buf+2);
42
packet_size =
AV_RB32
(buf+4);
43
44
if
(!
AV_RB16
(buf) && frame_type <=
LMLM4_MPEG1L2
&& packet_size &&
45
frame_type !=
LMLM4_INVALID
&& packet_size <=
LMLM4_MAX_PACKET_SIZE
) {
46
47
if
(frame_type ==
LMLM4_MPEG1L2
) {
48
if
((
AV_RB16
(buf+8) & 0xfffe) != 0xfffc)
49
return
0;
50
/* I could calculate the audio framesize and compare with
51
* packet_size-8, but that seems overkill */
52
return
AVPROBE_SCORE_MAX
/ 3;
53
}
else
if
(
AV_RB24
(buf+8) == 0x000001) {
/* PES Signal */
54
return
AVPROBE_SCORE_MAX
/ 5;
55
}
56
}
57
58
return
0;
59
}
60
61
static
int
lmlm4_read_header
(
AVFormatContext
*s,
AVFormatParameters
*ap) {
62
AVStream
*st;
63
64
if
(!(st =
avformat_new_stream
(s,
NULL
)))
65
return
AVERROR
(ENOMEM);
66
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
67
st->
codec
->
codec_id
=
CODEC_ID_MPEG4
;
68
st->
need_parsing
=
AVSTREAM_PARSE_HEADERS
;
69
avpriv_set_pts_info
(st, 64, 1001, 30000);
70
71
if
(!(st =
avformat_new_stream
(s,
NULL
)))
72
return
AVERROR
(ENOMEM);
73
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
74
st->
codec
->
codec_id
=
CODEC_ID_MP2
;
75
st->
need_parsing
=
AVSTREAM_PARSE_HEADERS
;
76
77
/* the parameters will be extracted from the compressed bitstream */
78
return
0;
79
}
80
81
static
int
lmlm4_read_packet
(
AVFormatContext
*s,
AVPacket
*pkt) {
82
AVIOContext
*pb = s->
pb
;
83
int
ret;
84
unsigned
int
frame_type, packet_size, padding, frame_size;
85
86
avio_rb16
(pb);
/* channel number */
87
frame_type =
avio_rb16
(pb);
88
packet_size =
avio_rb32
(pb);
89
padding = -packet_size & 511;
90
frame_size = packet_size - 8;
91
92
if
(frame_type >
LMLM4_MPEG1L2
|| frame_type ==
LMLM4_INVALID
) {
93
av_log
(s,
AV_LOG_ERROR
,
"invalid or unsupported frame_type\n"
);
94
return
AVERROR
(EIO);
95
}
96
if
(packet_size >
LMLM4_MAX_PACKET_SIZE
) {
97
av_log
(s,
AV_LOG_ERROR
,
"packet size exceeds maximum\n"
);
98
return
AVERROR
(EIO);
99
}
100
101
if
((ret =
av_get_packet
(pb, pkt, frame_size)) <= 0)
102
return
AVERROR
(EIO);
103
104
avio_skip
(pb, padding);
105
106
switch
(frame_type) {
107
case
LMLM4_I_FRAME
:
108
pkt->
flags
=
AV_PKT_FLAG_KEY
;
109
case
LMLM4_P_FRAME
:
110
case
LMLM4_B_FRAME
:
111
pkt->
stream_index
= 0;
112
break
;
113
case
LMLM4_MPEG1L2
:
114
pkt->
stream_index
= 1;
115
break
;
116
}
117
118
return
ret;
119
}
120
121
AVInputFormat
ff_lmlm4_demuxer
= {
122
.
name
=
"lmlm4"
,
123
.long_name =
NULL_IF_CONFIG_SMALL
(
"lmlm4 raw format"
),
124
.read_probe =
lmlm4_probe
,
125
.read_header =
lmlm4_read_header
,
126
.read_packet =
lmlm4_read_packet
,
127
};