FFmpeg
Loading...
Searching...
No Matches
mtv.c
Go to the documentation of this file.
1/*
2 * mtv demuxer
3 * Copyright (c) 2006 Reynaldo H. Verdejo Pinochet
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/**
23 * @file
24 * MTV demuxer.
25 */
26
28#include "libavutil/mem.h"
29#include "avformat.h"
30#include "demux.h"
31#include "internal.h"
32
33#define MTV_ASUBCHUNK_DATA_SIZE 500
34#define MTV_HEADER_SIZE 512
35#define MTV_AUDIO_PADDING_SIZE 12
36#define MTV_IMAGE_DEFAULT_BPP 16
37#define MTV_AUDIO_SAMPLING_RATE 44100
38
39typedef struct MTVDemuxContext {
40
41 unsigned int file_size; ///< filesize, not always right
42 unsigned int segments; ///< number of 512 byte segments
43 unsigned int audio_identifier; ///< 'MP3' on all files I have seen
44 unsigned int audio_br; ///< bitrate of audio channel (mp3)
45 unsigned int img_colorfmt; ///< frame colorfmt rgb 565/555
46 unsigned int img_bpp; ///< frame bits per pixel
47 unsigned int img_width;
48 unsigned int img_height;
49 unsigned int img_segment_size; ///< size of image segment
50 unsigned int video_fps;
51 unsigned int full_segment_size;
52
54
55static int mtv_probe(const AVProbeData *p)
56{
57 /* we need at least 57 bytes from the header
58 * to try parsing all required fields
59 */
60 if (p->buf_size < 57)
61 return 0;
62
63 /* Magic is 'AMV' */
64 if (*p->buf != 'A' || *(p->buf + 1) != 'M' || *(p->buf + 2) != 'V')
65 return 0;
66
67 /* Audio magic is always MP3 */
68 if (p->buf[43] != 'M' || p->buf[44] != 'P' || p->buf[45] != '3')
69 return 0;
70
71 /* Check for nonzero in bpp and (width|height) header fields */
72 if(!(p->buf[51] && AV_RL16(&p->buf[52]) | AV_RL16(&p->buf[54])))
73 return 0;
74
75 /* If width or height are 0 then imagesize header field should not */
76 if(!AV_RL16(&p->buf[52]) || !AV_RL16(&p->buf[54]))
77 {
78 if(!!AV_RL16(&p->buf[56]))
80 else
81 return 0;
82 }
83
84 /* Image bpp is not an absolutely required
85 * field as we latter claim it should be 16
86 * no matter what. All samples in the wild
87 * are RGB565/555.
88 */
89 if(p->buf[51] != MTV_IMAGE_DEFAULT_BPP)
90 return AVPROBE_SCORE_EXTENSION / 2;
91
92 /* We had enough data to parse header values
93 * but we expect to be able to get 512 bytes
94 * of header to be sure.
95 */
96 if (p->buf_size < MTV_HEADER_SIZE)
98
99 return AVPROBE_SCORE_MAX;
100}
101
103{
104 MTVDemuxContext *mtv = s->priv_data;
105 AVIOContext *pb = s->pb;
106 AVStream *st;
107 unsigned int audio_subsegments;
108 int64_t ret64;
109
110 avio_skip(pb, 3);
111 mtv->file_size = avio_rl32(pb);
112 mtv->segments = avio_rl32(pb);
113 avio_skip(pb, 32);
114 mtv->audio_identifier = avio_rl24(pb);
115 mtv->audio_br = avio_rl16(pb);
116 mtv->img_colorfmt = avio_rl24(pb);
117 mtv->img_bpp = avio_r8(pb);
118 mtv->img_width = avio_rl16(pb);
119 mtv->img_height = avio_rl16(pb);
120 mtv->img_segment_size = avio_rl16(pb);
121
122 /* Assume 16bpp even if claimed otherwise.
123 * We know its going to be RGBG565/555 anyway
124 */
125 if (mtv->img_bpp != MTV_IMAGE_DEFAULT_BPP) {
126 av_log (s, AV_LOG_WARNING, "Header claims %dbpp (!= 16). Ignoring\n",
127 mtv->img_bpp);
129 }
130
131 /* Calculate width and height if missing from header */
132
133 if (!mtv->img_width && mtv->img_height > 0 && mtv->img_bpp >= 8)
134 mtv->img_width=mtv->img_segment_size / (mtv->img_bpp>>3)
135 / mtv->img_height;
136
137 if (!mtv->img_height && mtv->img_width > 0 && mtv->img_bpp >= 8)
138 mtv->img_height=mtv->img_segment_size / (mtv->img_bpp>>3)
139 / mtv->img_width;
140
141 if(!mtv->img_height || !mtv->img_width || !mtv->img_segment_size){
142 av_log(s, AV_LOG_ERROR, "width or height or segment_size is invalid and I cannot calculate them from other information\n");
143 return AVERROR_INVALIDDATA;
144 }
145
146 avio_skip(pb, 4);
147 audio_subsegments = avio_rl16(pb);
148
149 if (audio_subsegments == 0) {
150 avpriv_request_sample(s, "MTV files without audio");
152 }
153
154 mtv->full_segment_size =
155 audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) +
156 mtv->img_segment_size;
157 mtv->video_fps = (mtv->audio_br / 4) / audio_subsegments;
158
159 // FIXME Add sanity check here
160
161 // all systems go! init decoders
162
163 // video - raw rgb565
164
166 if(!st)
167 return AVERROR(ENOMEM);
168
169 avpriv_set_pts_info(st, 64, 1, mtv->video_fps);
173 st->codecpar->width = mtv->img_width;
174 st->codecpar->height = mtv->img_height;
175 st->codecpar->extradata = av_strdup("BottomUp");
176 if (!st->codecpar->extradata)
177 return AVERROR(ENOMEM);
178 st->codecpar->extradata_size = 9;
179
180 // audio - mp3
181
183 if(!st)
184 return AVERROR(ENOMEM);
185
189 st->codecpar->bit_rate = mtv->audio_br;
191
192 // Jump over header
193
194 if ((ret64 = avio_seek(pb, MTV_HEADER_SIZE, SEEK_SET)) < 0)
195 return (int)ret64;
196
197 return 0;
198
199}
200
202{
203 MTVDemuxContext *mtv = s->priv_data;
204 AVIOContext *pb = s->pb;
205 int ret;
206
207 if((avio_tell(pb) - ffformatcontext(s)->data_offset + mtv->img_segment_size) % mtv->full_segment_size)
208 {
210
212 if(ret < 0)
213 return ret;
214
216 pkt->stream_index = 1;
217
218 }else
219 {
220 ret = av_get_packet(pb, pkt, mtv->img_segment_size);
221 if(ret < 0)
222 return ret;
223
224 pkt->stream_index = 0;
225 }
226
227 return ret;
228}
229
231 .p.name = "mtv",
232 .p.long_name = NULL_IF_CONFIG_SMALL("MTV"),
233 .priv_data_size = sizeof(MTVDemuxContext),
237};
const FFInputFormat ff_mtv_demuxer
Definition mtv.c:230
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition avformat.h:481
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition utils.c:98
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition avformat.h:611
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
unsigned int avio_rl16(AVIOContext *s)
Definition aviobuf.c:717
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
unsigned int avio_rl32(AVIOContext *s)
Definition aviobuf.c:733
unsigned int avio_rl24(AVIOContext *s)
Definition aviobuf.c:725
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
@ AV_CODEC_ID_RAWVIDEO
Definition codec_id.h:63
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:454
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_RL16(p)
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition internal.h:130
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
Memory handling functions.
#define MTV_IMAGE_DEFAULT_BPP
Definition mtv.c:36
#define MTV_HEADER_SIZE
Definition mtv.c:34
#define MTV_ASUBCHUNK_DATA_SIZE
Definition mtv.c:33
static int mtv_probe(const AVProbeData *p)
Definition mtv.c:55
#define MTV_AUDIO_SAMPLING_RATE
Definition mtv.c:37
#define MTV_AUDIO_PADDING_SIZE
Definition mtv.c:35
static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mtv.c:201
static int mtv_read_header(AVFormatContext *s)
Definition mtv.c:102
#define av_strdup(s)
Definition ops_static.c:55
@ AV_PIX_FMT_RGB565BE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition pixfmt.h:112
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int width
The width of the video frame in pixels.
Definition codec_par.h:143
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
Format I/O context.
Definition avformat.h:1333
Bytestream IO Context.
Definition avio.h:160
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
enum AVStreamParseType need_parsing
Definition internal.h:321
unsigned int audio_br
bitrate of audio channel (mp3)
Definition mtv.c:44
unsigned int segments
number of 512 byte segments
Definition mtv.c:42
unsigned int img_bpp
frame bits per pixel
Definition mtv.c:46
unsigned int video_fps
Definition mtv.c:50
unsigned int img_segment_size
size of image segment
Definition mtv.c:49
unsigned int file_size
filesize, not always right
Definition mtv.c:41
unsigned int img_colorfmt
frame colorfmt rgb 565/555
Definition mtv.c:45
unsigned int img_width
Definition mtv.c:47
unsigned int img_height
Definition mtv.c:48
unsigned int audio_identifier
'MP3' on all files I have seen
Definition mtv.c:43
unsigned int full_segment_size
Definition mtv.c:51
#define avpriv_request_sample(...)
#define av_log(a,...)