Mercurial > mplayer.hg
comparison libmpdemux/asfheader.c @ 21610:05a8a034d9aa
ASF aspect support via metadata reading.
Patch by Zuxy Meng (zuxy meng (at) gmail.com) with some
simplifications by me.
author | reimar |
---|---|
date | Fri, 15 Dec 2006 21:51:20 +0000 |
parents | f91f04764311 |
children | fb4bb5aed0cf |
comparison
equal
deleted
inserted
replaced
21609:3452c36a7fe2 | 21610:05a8a034d9aa |
---|---|
58 0xef, 0x47, 0xf2, 0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43}; | 58 0xef, 0x47, 0xf2, 0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43}; |
59 const char asf_ext_stream_audio[16] = {0x9d, 0x8c, 0x17, 0x31, | 59 const char asf_ext_stream_audio[16] = {0x9d, 0x8c, 0x17, 0x31, |
60 0xe1, 0x03, 0x28, 0x45, 0xb5, 0x82, 0x3d, 0xf9, 0xdb, 0x22, 0xf5, 0x03}; | 60 0xe1, 0x03, 0x28, 0x45, 0xb5, 0x82, 0x3d, 0xf9, 0xdb, 0x22, 0xf5, 0x03}; |
61 const char asf_ext_stream_header[16] = {0xCB, 0xA5, 0xE6, 0x14, | 61 const char asf_ext_stream_header[16] = {0xCB, 0xA5, 0xE6, 0x14, |
62 0x72, 0xC6, 0x32, 0x43, 0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A}; | 62 0x72, 0xC6, 0x32, 0x43, 0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A}; |
63 const char asf_metadata_header[16] = {0xea, 0xcb, 0xf8, 0xc5, | |
64 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca}; | |
65 | |
66 typedef struct { | |
67 // must be 0 for metadata record, might be non-zero for metadata lib record | |
68 uint16_t lang_list_index; | |
69 uint16_t stream_num; | |
70 uint16_t name_length; | |
71 uint16_t data_type; | |
72 uint32_t data_length; | |
73 uint16_t* name; | |
74 void* data; | |
75 } ASF_meta_record_t; | |
63 | 76 |
64 static char* get_ucs2str(const uint16_t* inbuf, uint16_t inlen) | 77 static char* get_ucs2str(const uint16_t* inbuf, uint16_t inlen) |
65 { | 78 { |
66 char* outbuf = calloc(inlen, 2); | 79 char* outbuf = calloc(inlen, 2); |
67 char* q; | 80 char* q; |
203 } | 216 } |
204 } | 217 } |
205 return 0; | 218 return 0; |
206 } | 219 } |
207 | 220 |
221 #define CHECKDEC(l, n) if (((l) -= (n)) < 0) return 0 | |
222 static char* read_meta_record(ASF_meta_record_t* dest, char* buf, | |
223 int* buf_len) | |
224 { | |
225 CHECKDEC(*buf_len, 2 + 2 + 2 + 2 + 4); | |
226 dest->lang_list_index = LE_16(buf); | |
227 dest->stream_num = LE_16(&buf[2]); | |
228 dest->name_length = LE_16(&buf[4]); | |
229 dest->data_type = LE_16(&buf[6]); | |
230 dest->data_length = LE_32(&buf[8]); | |
231 buf += 2 + 2 + 2 + 2 + 4; | |
232 CHECKDEC(*buf_len, dest->name_length); | |
233 dest->name = (uint16_t*)buf; | |
234 buf += dest->name_length; | |
235 CHECKDEC(*buf_len, dest->data_length); | |
236 dest->data = buf; | |
237 buf += dest->data_length; | |
238 return buf; | |
239 } | |
240 | |
241 static int get_meta(char *buf, int buf_len, int this_stream_num, | |
242 float* asp_ratio) | |
243 { | |
244 int pos = 0; | |
245 uint16_t records_count; | |
246 uint16_t x = 0, y = 0; | |
247 | |
248 if ((pos = find_asf_guid(buf, asf_metadata_header, pos, buf_len)) < 0) | |
249 return 0; | |
250 | |
251 CHECKDEC(buf_len, pos); | |
252 buf += pos; | |
253 CHECKDEC(buf_len, 2); | |
254 records_count = LE_16(buf); | |
255 buf += 2; | |
256 | |
257 while (records_count--) { | |
258 ASF_meta_record_t record_entry; | |
259 char* name; | |
260 | |
261 if (!(buf = read_meta_record(&record_entry, buf, &buf_len))) | |
262 return 0; | |
263 /* reserved, must be zero */ | |
264 if (record_entry.lang_list_index) | |
265 continue; | |
266 /* match stream number: 0 to match all */ | |
267 if (record_entry.stream_num && record_entry.stream_num != this_stream_num) | |
268 continue; | |
269 if (!(name = get_ucs2str(record_entry.name, record_entry.name_length))) { | |
270 mp_msg(MSGT_HEADER, MSGL_ERR, MSGTR_MemAllocFailed); | |
271 continue; | |
272 } | |
273 if (strcmp(name, "AspectRatioX") == 0) | |
274 x = LE_16(record_entry.data); | |
275 else if (strcmp(name, "AspectRatioY") == 0) | |
276 y = LE_16(record_entry.data); | |
277 free(name); | |
278 } | |
279 if (x && y) { | |
280 *asp_ratio = (float)x / (float)y; | |
281 return 1; | |
282 } | |
283 return 0; | |
284 } | |
285 | |
208 static int asf_init_audio_stream(demuxer_t *demuxer,struct asf_priv* asf, sh_audio_t* sh_audio, ASF_stream_header_t *streamh, int *ppos, uint8_t** buf, char *hdr, unsigned int hdr_len) | 286 static int asf_init_audio_stream(demuxer_t *demuxer,struct asf_priv* asf, sh_audio_t* sh_audio, ASF_stream_header_t *streamh, int *ppos, uint8_t** buf, char *hdr, unsigned int hdr_len) |
209 { | 287 { |
210 uint8_t *buffer = *buf; | 288 uint8_t *buffer = *buf; |
211 int pos = *ppos; | 289 int pos = *ppos; |
212 | 290 |
334 break; | 412 break; |
335 } | 413 } |
336 case ASF_GUID_PREFIX_video_stream: { | 414 case ASF_GUID_PREFIX_video_stream: { |
337 sh_video_t* sh_video=new_sh_video(demuxer,streamh->stream_no & 0x7F); | 415 sh_video_t* sh_video=new_sh_video(demuxer,streamh->stream_no & 0x7F); |
338 unsigned int len=streamh->type_size-(4+4+1+2); | 416 unsigned int len=streamh->type_size-(4+4+1+2); |
417 float asp_ratio; | |
339 ++video_streams; | 418 ++video_streams; |
340 // sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize); | 419 // sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize); |
341 sh_video->bih=calloc((len<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):len,1); | 420 sh_video->bih=calloc((len<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):len,1); |
342 memcpy(sh_video->bih,&buffer[4+4+1+2],len); | 421 memcpy(sh_video->bih,&buffer[4+4+1+2],len); |
343 le2me_BITMAPINFOHEADER(sh_video->bih); | 422 le2me_BITMAPINFOHEADER(sh_video->bih); |
355 sh_video->fps=1.0f/sh_video->frametime; | 434 sh_video->fps=1.0f/sh_video->frametime; |
356 } else { | 435 } else { |
357 asf->avg_vid_frame_time=0.0; // only used for dvr-ms when > 0.0 | 436 asf->avg_vid_frame_time=0.0; // only used for dvr-ms when > 0.0 |
358 sh_video->fps=1000.0f; | 437 sh_video->fps=1000.0f; |
359 sh_video->frametime=0.001f; | 438 sh_video->frametime=0.001f; |
439 } | |
440 if (get_meta(hdr, hdr_len, streamh->stream_no, &asp_ratio)) { | |
441 sh_video->aspect = asp_ratio * sh_video->bih->biWidth / | |
442 sh_video->bih->biHeight; | |
360 } | 443 } |
361 | 444 |
362 if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V); | 445 if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V); |
363 //asf_video_id=streamh.stream_no & 0x7F; | 446 //asf_video_id=streamh.stream_no & 0x7F; |
364 //if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F; | 447 //if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F; |