Mercurial > libavformat.hg
annotate mtv.c @ 3068:9cc9ff5aff9c libavformat
set bps to uncompressed original sound data for compressed audio
according to aiff specs, qt set it to 16 for mace and ima4,
fail if block align is not set.
author | bcoudurier |
---|---|
date | Mon, 25 Feb 2008 12:00:31 +0000 |
parents | d52c718e83f9 |
children | 1de87c1b6a12 |
rev | line source |
---|---|
1380 | 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 mtv.c | |
24 * MTV demuxer. | |
25 */ | |
26 | |
27 #include "avformat.h" | |
28 #include "bswap.h" | |
29 | |
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 | |
34 #define VIDEO_SID 0 | |
35 #define AUDIO_SID 1 | |
36 | |
37 typedef struct MTVDemuxContext { | |
38 | |
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 | |
50 | |
51 uint8_t audio_packet_count; | |
52 | |
53 } MTVDemuxContext; | |
54 | |
55 static int mtv_probe(AVProbeData *p) | |
56 { | |
57 /* Magic is 'AMV' */ | |
58 | |
59 if(*(p->buf) != 'A' || *(p->buf+1) != 'M' || *(p->buf+2) != 'V') | |
60 return 0; | |
61 | |
62 return AVPROBE_SCORE_MAX; | |
63 } | |
64 | |
65 static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap) | |
66 { | |
67 MTVDemuxContext *mtv = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
68 ByteIOContext *pb = s->pb; |
1380 | 69 AVStream *st; |
70 | |
71 | |
72 url_fskip(pb, 3); | |
73 mtv->file_size = get_le32(pb); | |
74 mtv->segments = get_le32(pb); | |
75 url_fskip(pb, 32); | |
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); | |
83 url_fskip(pb, 4); | |
84 mtv->audio_subsegments = get_le16(pb); | |
85 mtv->video_fps = (mtv->audio_br / 4) / mtv->audio_subsegments; | |
86 | |
87 /* FIXME Add sanity check here */ | |
88 | |
1986 | 89 /* first packet is always audio*/ |
1380 | 90 |
91 mtv->audio_packet_count = 1; | |
92 | |
93 /* all systems go! init decoders */ | |
94 | |
95 /* video - raw rgb565 */ | |
96 | |
97 st = av_new_stream(s, VIDEO_SID); | |
98 if(!st) | |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2023
diff
changeset
|
99 return AVERROR(ENOMEM); |
1380 | 100 |
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; | |
1449
64a44155a525
now we set codec_tag, still have to figure out how to handle flipping
reynaldo
parents:
1380
diff
changeset
|
104 st->codec->codec_tag = MKTAG('R', 'G', 'B', mtv->img_bpp); |
1380 | 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; | |
109 | |
110 /* audio - mp3 */ | |
111 | |
112 st = av_new_stream(s, AUDIO_SID); | |
113 if(!st) | |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2023
diff
changeset
|
114 return AVERROR(ENOMEM); |
1380 | 115 |
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; | |
2023 | 120 st->need_parsing = AVSTREAM_PARSE_FULL; |
1380 | 121 |
122 /* Jump over header */ | |
123 | |
124 if(url_fseek(pb, MTV_HEADER_SIZE, SEEK_SET) != MTV_HEADER_SIZE) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
125 return AVERROR(EIO); |
1380 | 126 |
127 return(0); | |
128 | |
129 } | |
130 | |
131 static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt) | |
132 { | |
133 MTVDemuxContext *mtv = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
134 ByteIOContext *pb = s->pb; |
1380 | 135 int ret; |
136 #ifndef WORDS_BIGENDIAN | |
137 int i; | |
138 #endif | |
139 | |
140 ret = 0; | |
141 | |
142 if(mtv->audio_subsegments >= mtv->audio_packet_count) | |
143 { | |
144 url_fskip(pb, MTV_AUDIO_PADDING_SIZE); | |
145 | |
146 ret = av_get_packet(pb, pkt, MTV_ASUBCHUNK_DATA_SIZE); | |
147 if(ret != MTV_ASUBCHUNK_DATA_SIZE) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
148 return AVERROR(EIO); |
1380 | 149 |
150 mtv->audio_packet_count++; | |
151 pkt->stream_index = AUDIO_SID; | |
152 | |
153 }else | |
154 { | |
155 ret = av_get_packet(pb, pkt, mtv->img_segment_size); | |
156 if(ret != mtv->img_segment_size) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
157 return AVERROR(EIO); |
1380 | 158 |
159 #ifndef WORDS_BIGENDIAN | |
160 | |
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 | |
165 */ | |
166 | |
167 for(i=0;i<mtv->img_segment_size/2;i++) | |
168 *((uint16_t *)pkt->data+i) = bswap_16(*((uint16_t *)pkt->data+i)); | |
169 #endif | |
170 mtv->audio_packet_count = 1; | |
171 pkt->stream_index = VIDEO_SID; | |
172 } | |
173 | |
174 return(ret); | |
175 } | |
176 | |
177 AVInputFormat mtv_demuxer = { | |
178 "MTV", | |
179 "MTV format", | |
180 sizeof(MTVDemuxContext), | |
181 mtv_probe, | |
182 mtv_read_header, | |
183 mtv_read_packet, | |
184 }; |