3 * Copyright (c) 2006 Reynaldo H. Verdejo Pinochet
5 * This file is part of FFmpeg.
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.
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.
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
23 * @file libavformat/mtv.c
27 #include "libavutil/bswap.h"
30 #define MTV_ASUBCHUNK_DATA_SIZE 500
31 #define MTV_HEADER_SIZE 512
32 #define MTV_AUDIO_PADDING_SIZE 12
33 #define AUDIO_SAMPLING_RATE 44100
37 typedef struct MTVDemuxContext
{
39 unsigned int file_size
; ///< filesize, not always right
40 unsigned int segments
; ///< number of 512 byte segments
41 unsigned int audio_identifier
; ///< 'MP3' on all files I have seen
42 unsigned int audio_br
; ///< bitrate of audio chanel (mp3)
43 unsigned int img_colorfmt
; ///< frame colorfmt rgb 565/555
44 unsigned int img_bpp
; ///< frame bits per pixel
45 unsigned int img_width
; //
46 unsigned int img_height
; //
47 unsigned int img_segment_size
; ///< size of image segment
48 unsigned int video_fps
; //
49 unsigned int full_segment_size
;
53 static int mtv_probe(AVProbeData
*p
)
56 if(*(p
->buf
) != 'A' || *(p
->buf
+1) != 'M' || *(p
->buf
+2) != 'V')
59 return AVPROBE_SCORE_MAX
;
62 static int mtv_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
64 MTVDemuxContext
*mtv
= s
->priv_data
;
65 ByteIOContext
*pb
= s
->pb
;
67 unsigned int audio_subsegments
;
70 mtv
->file_size
= get_le32(pb
);
71 mtv
->segments
= get_le32(pb
);
73 mtv
->audio_identifier
= get_le24(pb
);
74 mtv
->audio_br
= get_le16(pb
);
75 mtv
->img_colorfmt
= get_le24(pb
);
76 mtv
->img_bpp
= get_byte(pb
);
77 mtv
->img_width
= get_le16(pb
);
78 mtv
->img_height
= get_le16(pb
);
79 mtv
->img_segment_size
= get_le16(pb
);
81 audio_subsegments
= get_le16(pb
);
82 mtv
->full_segment_size
=
83 audio_subsegments
* (MTV_AUDIO_PADDING_SIZE
+ MTV_ASUBCHUNK_DATA_SIZE
) +
84 mtv
->img_segment_size
;
85 mtv
->video_fps
= (mtv
->audio_br
/ 4) / audio_subsegments
;
87 // FIXME Add sanity check here
89 // all systems go! init decoders
93 st
= av_new_stream(s
, VIDEO_SID
);
95 return AVERROR(ENOMEM
);
97 av_set_pts_info(st
, 64, 1, mtv
->video_fps
);
98 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
99 st
->codec
->codec_id
= CODEC_ID_RAWVIDEO
;
100 st
->codec
->codec_tag
= MKTAG('R', 'G', 'B', mtv
->img_bpp
);
101 st
->codec
->width
= mtv
->img_width
;
102 st
->codec
->height
= mtv
->img_height
;
103 st
->codec
->bits_per_coded_sample
= mtv
->img_bpp
;
104 st
->codec
->sample_rate
= mtv
->video_fps
;
105 st
->codec
->extradata
= av_strdup("BottomUp");
106 st
->codec
->extradata_size
= 9;
110 st
= av_new_stream(s
, AUDIO_SID
);
112 return AVERROR(ENOMEM
);
114 av_set_pts_info(st
, 64, 1, AUDIO_SAMPLING_RATE
);
115 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
116 st
->codec
->codec_id
= CODEC_ID_MP3
;
117 st
->codec
->bit_rate
= mtv
->audio_br
;
118 st
->need_parsing
= AVSTREAM_PARSE_FULL
;
122 if(url_fseek(pb
, MTV_HEADER_SIZE
, SEEK_SET
) != MTV_HEADER_SIZE
)
129 static int mtv_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
131 MTVDemuxContext
*mtv
= s
->priv_data
;
132 ByteIOContext
*pb
= s
->pb
;
138 if((url_ftell(pb
) - s
->data_offset
+ mtv
->img_segment_size
) % mtv
->full_segment_size
)
140 url_fskip(pb
, MTV_AUDIO_PADDING_SIZE
);
142 ret
= av_get_packet(pb
, pkt
, MTV_ASUBCHUNK_DATA_SIZE
);
143 if(ret
!= MTV_ASUBCHUNK_DATA_SIZE
)
146 pkt
->pos
-= MTV_AUDIO_PADDING_SIZE
;
147 pkt
->stream_index
= AUDIO_SID
;
151 ret
= av_get_packet(pb
, pkt
, mtv
->img_segment_size
);
152 if(ret
!= mtv
->img_segment_size
)
157 /* pkt->data is GGGRRRR BBBBBGGG
158 * and we need RRRRRGGG GGGBBBBB
159 * for PIX_FMT_RGB565 so here we
160 * just swap bytes as they come
163 for(i
=0;i
<mtv
->img_segment_size
/2;i
++)
164 *((uint16_t *)pkt
->data
+i
) = bswap_16(*((uint16_t *)pkt
->data
+i
));
166 pkt
->stream_index
= VIDEO_SID
;
172 AVInputFormat mtv_demuxer
= {
174 NULL_IF_CONFIG_SMALL("MTV format"),
175 sizeof(MTVDemuxContext
),