2 * Copyright (c) 2004, Marcus Overhagen
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23 * OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <MediaFormats.h>
28 #include "matroska_codecs.h"
30 #define TRACE_MATROSKA
37 #define ERROR(a...) fprintf(stderr, a)
39 struct bitmap_info_header
48 uint32 x_pels_per_meter
;
49 uint32 y_pels_per_meter
;
60 GetAudioFormat(media_format
*format
, const char *codec
, void *private_data
, int private_size
)
62 TRACE("private_data: codec '%s', private data size %d\n", codec
, private_size
);
64 BMediaFormats formats
;
65 media_format_description description
;
67 if (IS_CODEC(codec
, "A_VORBIS")) {
68 description
.family
= B_MISC_FORMAT_FAMILY
;
69 description
.u
.misc
.file_format
= 'OggS';
70 description
.u
.misc
.codec
= 'vorb';
71 if (B_OK
!= formats
.GetFormatFor(description
, format
))
72 format
->type
= B_MEDIA_ENCODED_AUDIO
;
74 uint8_t * data_bytes
= (uint8_t*)private_data
;
75 int packet_count
= data_bytes
[0] + 1;
76 if (packet_count
!= 3) {
80 int info_packet_size
= data_bytes
[1];
81 int comment_packet_size
= data_bytes
[2];
82 int codebook_packet_size
= private_size
- info_packet_size
- comment_packet_size
- 3;
84 static uint8_t * vorbis_bytes
= new uint8_t[private_size
- 3];
85 memcpy(vorbis_bytes
, &(data_bytes
[3]), private_size
- 3);
88 static std::vector
<ogg_packet
> header_packets
;
92 packet
.granulepos
= 0;
94 packet
.packet
= &(vorbis_bytes
[0]);
95 packet
.bytes
= info_packet_size
;
96 header_packets
.push_back(packet
);
100 packet
.granulepos
= 0;
102 packet
.packet
= &(vorbis_bytes
[info_packet_size
]);
103 packet
.bytes
= comment_packet_size
;
104 header_packets
.push_back(packet
);
108 packet
.granulepos
= 0;
110 packet
.packet
= &(vorbis_bytes
[info_packet_size
+comment_packet_size
]);
111 packet
.bytes
= codebook_packet_size
;
112 header_packets
.push_back(packet
);
114 format
->SetMetaData(&header_packets
, sizeof(header_packets
));
119 if (IS_CODEC(codec
, "A_MPEG/L3")) {
120 description
.family
= B_MPEG_FORMAT_FAMILY
;
121 description
.u
.mpeg
.id
= B_MPEG_1_AUDIO_LAYER_3
;
122 if (formats
.GetFormatFor(description
, format
) != B_OK
)
123 format
->type
= B_MEDIA_ENCODED_AUDIO
;
128 if (IS_CODEC(codec
, "A_AC3")) {
129 description
.family
= B_WAV_FORMAT_FAMILY
;
130 description
.u
.wav
.codec
= 0x2000;
132 if (B_OK
!= formats
.GetFormatFor(description
, format
))
133 format
->type
= B_MEDIA_ENCODED_AUDIO
;
135 // Set the DecoderConfigSize (Not that haiku seems to use it)
136 if (private_size
> 0) {
137 TRACE("AC3 private data found, size is %d\n", private_size
);
138 if (format
->SetMetaData(private_data
, private_size
) != B_OK
) {
139 ERROR("Failed to set Decoder Config\n");
147 // The codec name only has to start with A_AAC to be AAC
148 // The rest is some sort of hint for creating the codec specific data
149 if (IS_CODEC(codec
, "A_AAC")) {
150 uint64 misc_codec
= 'mp4a';
151 media_format_description description
;
152 description
.family
= B_MISC_FORMAT_FAMILY
;
153 description
.u
.misc
.file_format
= (uint32
)(misc_codec
>> 32);
154 description
.u
.misc
.codec
= (uint32
)misc_codec
;
155 if (formats
.GetFormatFor(description
, format
) != B_OK
)
156 format
->type
= B_MEDIA_ENCODED_AUDIO
;
158 // Set the DecoderConfigSize (Not that haiku seems to use it)
159 if (private_size
> 0) {
160 TRACE("AAC private data found, size is %d\n", private_size
);
161 if (format
->SetMetaData(private_data
, private_size
) != B_OK
) {
162 ERROR("Failed to set Decoder Config\n");
175 GetVideoFormat(media_format
*format
, const char *codec
, void *private_data
, int private_size
)
177 TRACE("private_data: codec '%s', private data size %d\n", codec
, private_size
);
179 BMediaFormats formats
;
180 media_format_description description
;
182 if (IS_CODEC(codec
, "V_MS/VFW/FOURCC")) {
183 if (private_size
< (int)sizeof(bitmap_info_header
)) {
184 TRACE("private_size too small!\n");
187 const bitmap_info_header
*bih
= (const bitmap_info_header
*)private_data
;
189 description
.family
= B_AVI_FORMAT_FAMILY
;
190 description
.u
.avi
.codec
= bih
->compression
;
191 if (B_OK
!= formats
.GetFormatFor(description
, format
))
192 format
->type
= B_MEDIA_ENCODED_VIDEO
;
194 format
->user_data_type
= B_CODEC_TYPE_INFO
;
195 *(uint32
*)format
->user_data
= bih
->compression
; format
->user_data
[4] = 0;
199 if (IS_CODEC(codec
, "V_MPEG4/ISO/AVC")) {
200 uint64 codecid
= 'avc1';
202 description
.family
= B_QUICKTIME_FORMAT_FAMILY
;
203 description
.u
.quicktime
.codec
= codecid
;
204 if (B_OK
!= formats
.GetFormatFor(description
, format
))
205 format
->type
= B_MEDIA_ENCODED_VIDEO
;
207 format
->user_data_type
= B_CODEC_TYPE_INFO
;
208 *(uint32
*)format
->user_data
= codecid
; format
->user_data
[4] = 0;
210 // Set the DecoderConfigSize (Not that haiku seems to use it)
211 if (private_size
> 0) {
212 TRACE("AVC private data found, size is %d\n", private_size
);
213 if (format
->SetMetaData(private_data
, private_size
) != B_OK
) {
214 ERROR("Failed to set Decoder Config\n");
221 TRACE("not a codec!\n");