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
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 audio_subsegments
; ///< audio subsegments on one segment
51 uint8_t audio_packet_count
;
55 static int mtv_probe(AVProbeData
*p
)
59 if(*(p
->buf
) != 'A' || *(p
->buf
+1) != 'M' || *(p
->buf
+2) != 'V')
62 return AVPROBE_SCORE_MAX
;
65 static int mtv_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
67 MTVDemuxContext
*mtv
= s
->priv_data
;
68 ByteIOContext
*pb
= s
->pb
;
73 mtv
->file_size
= get_le32(pb
);
74 mtv
->segments
= get_le32(pb
);
76 mtv
->audio_identifier
= get_le24(pb
);
77 mtv
->audio_br
= get_le16(pb
);
78 mtv
->img_colorfmt
= get_le24(pb
);
79 mtv
->img_bpp
= get_byte(pb
);
80 mtv
->img_width
= get_le16(pb
);
81 mtv
->img_height
= get_le16(pb
);
82 mtv
->img_segment_size
= get_le16(pb
);
84 mtv
->audio_subsegments
= get_le16(pb
);
85 mtv
->video_fps
= (mtv
->audio_br
/ 4) / mtv
->audio_subsegments
;
87 /* FIXME Add sanity check here */
89 /* first packet is always audio*/
91 mtv
->audio_packet_count
= 1;
93 /* all systems go! init decoders */
95 /* video - raw rgb565 */
97 st
= av_new_stream(s
, VIDEO_SID
);
99 return AVERROR(ENOMEM
);
101 av_set_pts_info(st
, 64, 1, mtv
->video_fps
);
102 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
103 st
->codec
->codec_id
= CODEC_ID_RAWVIDEO
;
104 st
->codec
->codec_tag
= MKTAG('R', 'G', 'B', mtv
->img_bpp
);
105 st
->codec
->width
= mtv
->img_width
;
106 st
->codec
->height
= mtv
->img_height
;
107 st
->codec
->bits_per_sample
= mtv
->img_bpp
;
108 st
->codec
->sample_rate
= mtv
->video_fps
;
112 st
= av_new_stream(s
, AUDIO_SID
);
114 return AVERROR(ENOMEM
);
116 av_set_pts_info(st
, 64, 1, AUDIO_SAMPLING_RATE
);
117 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
118 st
->codec
->codec_id
= CODEC_ID_MP3
;
119 st
->codec
->bit_rate
= mtv
->audio_br
;
120 st
->need_parsing
= AVSTREAM_PARSE_FULL
;
122 /* Jump over header */
124 if(url_fseek(pb
, MTV_HEADER_SIZE
, SEEK_SET
) != MTV_HEADER_SIZE
)
131 static int mtv_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
133 MTVDemuxContext
*mtv
= s
->priv_data
;
134 ByteIOContext
*pb
= s
->pb
;
136 #ifndef WORDS_BIGENDIAN
142 if(mtv
->audio_subsegments
>= mtv
->audio_packet_count
)
144 url_fskip(pb
, MTV_AUDIO_PADDING_SIZE
);
146 ret
= av_get_packet(pb
, pkt
, MTV_ASUBCHUNK_DATA_SIZE
);
147 if(ret
!= MTV_ASUBCHUNK_DATA_SIZE
)
150 mtv
->audio_packet_count
++;
151 pkt
->stream_index
= AUDIO_SID
;
155 ret
= av_get_packet(pb
, pkt
, mtv
->img_segment_size
);
156 if(ret
!= mtv
->img_segment_size
)
159 #ifndef WORDS_BIGENDIAN
161 /* pkt->data is GGGRRRR BBBBBGGG
162 * and we need RRRRRGGG GGGBBBBB
163 * for PIX_FMT_RGB565 so here we
164 * just swap bytes as they come
167 for(i
=0;i
<mtv
->img_segment_size
/2;i
++)
168 *((uint16_t *)pkt
->data
+i
) = bswap_16(*((uint16_t *)pkt
->data
+i
));
170 mtv
->audio_packet_count
= 1;
171 pkt
->stream_index
= VIDEO_SID
;
177 AVInputFormat mtv_demuxer
= {
180 sizeof(MTVDemuxContext
),