1 // LiVES - asf decoder plugin
2 // (c) G. Finch 2011 - 2014 <salsaman@gmail.com>
3
4 /*
5 This file is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 LiVES is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with LiVES; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 // based on code from libavformat
21
22 /*
23 ASF compatible demuxer
24 Copyright (c) 2000, 2001 Fabrice Bellard
25
26 */
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #if !defined (IS_MINGW) && !defined (IS_SOLARIS) && !defined (__DragonFly__)
35 #include <endian.h>
36 #endif
37 #include <sys/stat.h>
38 #include <pthread.h>
39
40 static const char *plname = "lives_asf";
41 static int vmaj = 1;
42 static int vmin = 1;
43 const char *plugin_version = "LiVES asf/wmv decoder version 1.1";
44
45 #ifdef HAVE_AV_CONFIG_H
46 #undef HAVE_AV_CONFIG_H
47 #endif
48
49 #define HAVE_AVCODEC
50 #define HAVE_AVUTIL
51
52 #include <libavformat/avformat.h>
53 #include <libavutil/avstring.h>
54 #include <libavcodec/version.h>
55 #include <libavutil/mem.h>
56
57 #define NEED_FOURCC_COMPAT
58
59 #ifdef NEED_LOCAL_WEED_COMPAT
60 #include "../../../libweed/weed-compat.h"
61 #else
62 #include <weed/weed-compat.h>
63 #endif
64
65 #define NEED_CLONEFUNC
66 #include "decplugin.h"
67 #include "libav_helper.h"
68
69 #include "asf_decoder.h"
70
ff_codec_get_id(const AVCodecTag * tags,unsigned int tag)71 static enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag) {
72 int i;
73 for (i = 0; tags[i].id != AV_CODEC_ID_NONE; i++) {
74 if (tag == tags[i].tag)
75 return tags[i].id;
76 }
77 for (i = 0; tags[i].id != AV_CODEC_ID_NONE; i++) {
78 if (toupper((tag >> 0) & 0xFF) == toupper((tags[i].tag >> 0) & 0xFF)
79 && toupper((tag >> 8) & 0xFF) == toupper((tags[i].tag >> 8) & 0xFF)
80 && toupper((tag >> 16) & 0xFF) == toupper((tags[i].tag >> 16) & 0xFF)
81 && toupper((tag >> 24) & 0xFF) == toupper((tags[i].tag >> 24) & 0xFF))
82 return tags[i].id;
83 }
84 return AV_CODEC_ID_NONE;
85 }
86
87 static index_container_t **indices;
88 static int nidxc;
89 static pthread_mutex_t indices_mutex;
90 static pthread_mutexattr_t mattr;
91
92
93 ////////////////////////////////////////////////////////////////////////////
94
95 /* can enable this later to handle pix_fmt (35) - YUVA4204P */
96 /*
97 static void convert_quad_chroma(guchar *src, int width, int height, guchar *dest) {
98 // width and height here are width and height of dest chroma planes, in bytes
99
100 // double the chroma samples vertically and horizontally, with interpolation, eg. 420p to 444p
101
102 // output to planes
103
104 register int i,j;
105 guchar *d_u=dest,*s_u=src;
106 gboolean chroma=FALSE;
107 int height2=height;
108 int width2=width;
109
110 height>>=1;
111 width>>=1;
112
113 // for this algorithm, we assume chroma samples are aligned like mpeg
114
115 for (i=0;i<height2;i++) {
116 d_u[0]=d_u[1]=s_u[0];
117 for (j=2;j<width2;j+=2) {
118 d_u[j+1]=d_u[j]=s_u[(j>>1)];
119 d_u[j-1]=avg_chroma(d_u[j-1],d_u[j]);
120 if (!chroma&&i>0) {
121 // pass 2
122 // average two src rows (e.g 2 with 1, 4 with 3, ... etc) for odd dst rows
123 // thus dst row 1 becomes average of src chroma rows 0 and 1, etc.)
124 d_u[j-width2]=avg_chroma(d_u[j-width2],d_u[j]);
125 d_u[j-1-width2]=avg_chroma(d_u[j-1-width2],d_u[j-1]);
126 }
127 }
128 if (!chroma&&i>0) {
129 d_u[j-1-width2]=avg_chroma(d_u[j-1-width2],d_u[j-1]);
130 }
131 if (chroma) {
132 s_u+=width;
133 }
134 chroma=!chroma;
135 d_u+=width2;
136 }
137 }
138
139 */
140
141 //////////////////////////////////////////////
142
143
frame_to_dts(const lives_clip_data_t * cdata,int64_t frame)144 static int frame_to_dts(const lives_clip_data_t *cdata, int64_t frame) {
145 lives_asf_priv_t *priv = cdata->priv;
146 return (int)((double)(frame) * 1000. / cdata->fps) + priv->start_dts;
147 }
148
149
dts_to_frame(const lives_clip_data_t * cdata,int dts)150 static int64_t dts_to_frame(const lives_clip_data_t *cdata, int dts) {
151 lives_asf_priv_t *priv = cdata->priv;
152 return (int64_t)((double)(dts - priv->start_dts) / 1000.*cdata->fps + .5);
153 }
154
155
156 ////////////////////////////////////////////////////////////////
157
get_guid(int fd,lives_asf_guid * g)158 static boolean get_guid(int fd, lives_asf_guid *g) {
159 if ((read(fd, g, sizeof(lives_asf_guid))) != sizeof(lives_asf_guid)) return FALSE;
160 return TRUE;
161 }
162
guidcmp(const void * v1,const void * v2)163 static boolean guidcmp(const void *v1, const void *v2) {
164
165 int res = memcmp(v1, v2, sizeof(lives_asf_guid));
166
167 #ifdef DEBUG
168 uint8_t *g1 = (uint8_t *)v1;
169 uint8_t *g2 = (uint8_t *)v2;
170 if (res == 0) {
171 printf("check %0X %0X %0X %0X %0X %0X %0X %0X %0X %0X %0X %0X %0X %0X %0X %0X\n", (uint8_t)g1[0], (uint8_t)g1[1],
172 (uint8_t)g1[2],
173 (uint8_t)g1[3], (uint8_t)g1[4], (uint8_t)g1[5], (uint8_t)g1[6], (uint8_t)g1[7], (uint8_t)g1[8], (uint8_t)g1[9], (uint8_t)g1[10],
174 (uint8_t)g1[11],
175 (uint8_t)g1[12], (uint8_t)g1[13], (uint8_t)g1[14], (uint8_t)g1[15]);
176 }
177 #endif
178
179 return res != 0;
180 }
181
182
get_str16_nolen(unsigned char * inbuf,int len,char * buf,int buf_size)183 static void get_str16_nolen(unsigned char *inbuf, int len, char *buf, int buf_size) {
184 int i = 0;
185 char *q = buf;
186 while (len > 1) {
187 uint8_t tmp;
188 uint32_t ch;
189
190 GET_UTF16(ch, (len -= 2) >= 0 ? get_le16int(&inbuf[i]) : 0, break;)
191 PUT_UTF8(ch, tmp, if (q - buf < buf_size - 1) *q++ = tmp;)
192 i += 2;
193 }
194 *q = '\0';
195 }
196
197
198 //////////////////////////////////////////////////////////////////
199
check_eof(const lives_clip_data_t * cdata)200 static boolean check_eof(const lives_clip_data_t *cdata) {
201 lives_asf_priv_t *priv = cdata->priv;
202 if (priv->input_position >= priv->filesize) return TRUE;
203 return FALSE;
204 }
205
206
get_value(const lives_clip_data_t * cdata,int type)207 static int get_value(const lives_clip_data_t *cdata, int type) {
208 unsigned char buffer[4096];
209 lives_asf_priv_t *priv = cdata->priv;
210 switch (type) {
211 case 2:
212 case 3:
213 if (read(priv->fd, buffer, 4) < 4) {
214 fprintf(stderr, "asf_decoder: read error getting value\n");
215 close(priv->fd);
216 return INT_MIN;
217 }
218 priv->input_position += 4;
219 return get_le32int(buffer);
220 case 4:
221 if (read(priv->fd, buffer, 8) < 8) {
222 fprintf(stderr, "asf_decoder: read error getting value\n");
223 close(priv->fd);
224 return INT_MIN;
225 }
226 priv->input_position += 8;
227 return get_le64int(buffer);
228 case 5:
229 if (read(priv->fd, buffer, 2) < 2) {
230 fprintf(stderr, "asf_decoder: read error getting value\n");
231 close(priv->fd);
232 return INT_MIN;
233 }
234 priv->input_position += 2;
235 return get_le16int(buffer);
236 default:
237 return INT_MIN;
238 }
239 }
240
241
get_tag(const lives_clip_data_t * cdata,AVFormatContext * s,const char * key,int type,int len)242 static boolean get_tag(const lives_clip_data_t *cdata, AVFormatContext *s, const char *key, int type, int len) {
243 char *value;
244 unsigned char buffer[4096];
245 lives_asf_priv_t *priv = cdata->priv;
246
247 if ((unsigned)len >= (UINT_MAX - 1) / 2) return TRUE;
248 value = malloc(2 * len + 1);
249 if (!value) return TRUE;
250
251 if (type == 0) { // UTF16-LE
252 if (read(priv->fd, buffer, len) < len) {
253 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
254 close(priv->fd);
255 return FALSE;
256 }
257 get_str16_nolen(buffer, len, value, 2 * len + 1);
258 priv->input_position += len;
259 } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD
260 uint64_t num = get_value(cdata, type);
261 if (num == INT_MIN) return FALSE;
262 snprintf(value, len, "%"PRIu64, num);
263 } else {
264 lseek(priv->fd, len, SEEK_CUR);
265 priv->input_position += len;
266 free(value);
267 fprintf(stderr, "asf_decoder: Unsupported value type %d len %d in tag %s.\n", type, len, key);
268 return TRUE;
269 }
270
271 av_dict_set(&s->metadata, key, value, 0);
272
273 free(value);
274 return TRUE;
275 }
276
277
asf_reset_header(AVFormatContext * s)278 static void asf_reset_header(AVFormatContext *s) {
279 ASFContext *asf = s->priv_data;
280 ASFStream *asf_st;
281 int i;
282
283 asf->packet_nb_frames = 0;
284 asf->packet_size_left = 0;
285 asf->packet_segments = 0;
286 asf->packet_flags = 0;
287 asf->packet_property = 0;
288 asf->packet_timestamp = 0;
289 asf->packet_segsizetype = 0;
290 asf->packet_segments = 0;
291 asf->packet_seq = 0;
292 asf->packet_replic_size = 0;
293 asf->packet_key_frame = 0;
294 asf->packet_padsize = 0;
295 asf->packet_frag_offset = 0;
296 asf->packet_frag_size = 0;
297 asf->packet_frag_timestamp = 0;
298 asf->packet_multi_size = 0;
299 asf->packet_obj_size = 0;
300 asf->packet_time_delta = 0;
301 asf->packet_time_start = 0;
302
303 for (i = 0; i < s->nb_streams; i++) {
304 asf_st = s->streams[i]->priv_data;
305 av_packet_unref(&asf_st->pkt);
306 asf_st->frag_offset = 0;
307 asf_st->seq = 0;
308 }
309 asf->asf_st = NULL;
310 }
311
312
get_sync(lives_asf_priv_t * priv)313 static void get_sync(lives_asf_priv_t *priv) {
314 unsigned char buffer;
315
316 while (1) {
317 if (read(priv->fd, &buffer, 1) < 1) return;
318 priv->input_position++;
319 if (buffer == 0x82) goto got_82;
320 else continue;
321
322 got_82:
323 if (read(priv->fd, &buffer, 1) < 1) return;
324 priv->input_position++;
325
326 if (buffer == 0x82) goto got_82;
327 if (buffer == 0) goto got_0;
328 else continue;
329
330 got_0:
331 if (read(priv->fd, &buffer, 1) < 1) return;
332 priv->input_position++;
333 if (buffer == 0) return; // OK
334 if (buffer == 0x82) goto got_82;
335
336 }
337 }
338
339
340 /////////////////////////////////////////////////////
341
index_free(index_entry * idx)342 static void index_free(index_entry *idx) {
343 index_entry *cidx = idx, *next;
344
345 while (cidx != NULL) {
346 next = cidx->next;
347 free(cidx);
348 cidx = next;
349 }
350 }
351
352
idx_alloc(int64_t offs,int frag,int dts)353 static index_entry *idx_alloc(int64_t offs, int frag, int dts) {
354 index_entry *nidx = (index_entry *)malloc(sizeof(index_entry));
355 nidx->offs = offs;
356 nidx->dts = dts;
357 nidx->frag = frag;
358 return nidx;
359 }
360
361
362 /// here we assume that pts of interframes > pts of previous keyframe
363 // should be true for most formats (except eg. dirac)
364
365 // we further assume that pts == dts for all frames
366
add_keyframe(const lives_clip_data_t * cdata,int64_t offs,int frag,int dts)367 static index_entry *add_keyframe(const lives_clip_data_t *cdata, int64_t offs, int frag, int dts) {
368 // dts 0 is start (i.e excluding start_dts)
369 lives_asf_priv_t *priv = cdata->priv;
370 index_entry *idx, *lidx, *nidx;
371
372 lidx = idx = priv->idxc->idx;
373
374 while (idx != NULL) {
375 if (idx->dts == dts) return idx; // already indexed
376 if (idx->dts > dts) {
377 // insert before idx
378 nidx = idx_alloc(offs, frag, dts);
379 nidx->next = idx;
380 if (idx == priv->idxc->idx) priv->idxc->idx = nidx;
381 else lidx->next = nidx;
382 return nidx;
383 }
384 lidx = idx;
385 idx = idx->next;
386 }
387
388 // insert at tail
389
390 nidx = idx_alloc(offs, frag, dts);
391
392 if (lidx != NULL) lidx->next = nidx;
393 else priv->idxc->idx = nidx;
394
395 nidx->next = NULL;
396
397 return nidx;
398 }
399
400
get_next_video_packet(const lives_clip_data_t * cdata,int tfrag,int64_t tdts)401 static int get_next_video_packet(const lives_clip_data_t *cdata, int tfrag, int64_t tdts) {
402 lives_asf_priv_t *priv = cdata->priv;
403 uint32_t packet_length, padsize;
404 unsigned char buffer[8];
405 uint8_t num;
406 //uint16_t duration;
407 int rsize;
408 int streamid;
409 int pack_fill = 0;
410 int64_t ts0;
411 int64_t frag_start;
412 AVFormatContext *s = priv->s;
413 ASFContext *asf = priv->asf;
414 int16_t vidindex = priv->st->id;
415
416 // create avpacket
417
418 // if (nodata):
419 // seek to input_pos
420 // a:
421 // sync to hdr start
422
423 // b)
424 // do until avpacket is full:
425 // if no more fragments, set target fragment to 0, goto a)
426 // get next vid fragment, decrement target fragment
427 // if we reached or passed target fragment, fill avpacket with fragment data
428 // if fragment_offset is 0, and we have data in our packet, packet is full so return
429
430
431 // if (!nodata):
432 // create avpacket
433 // set target fragment to 0
434 // goto b)
435
436 // if we have target (tdts) we parse only, until we reach a video fragment with dts>=tdts
437
438 if (tdts == -1) {
439 priv->avpkt.size = priv->def_packet_size + AV_INPUT_BUFFER_PADDING_SIZE;
440 priv->avpkt.data = malloc(priv->avpkt.size);
441 memset(priv->avpkt.data, 0, priv->avpkt.size);
442 }
443
444 while (1) {
445 lseek(priv->fd, priv->input_position, SEEK_SET);
446
447 if (tfrag >= 0 || asf->packet_segments == 0) {
448 rsize = 8;
449
450 #ifdef DEBUG
451 printf("pos is %x\n", priv->input_position);
452 #endif
453 get_sync(priv);
454
455 priv->hdr_start = priv->input_position - 3;
456
457 if (read(priv->fd, buffer, 2) < 2) return -2;
458
459 priv->input_position += 2;
460
461 asf->packet_flags = buffer[0];
462 asf->packet_property = buffer[1];
463
464 rsize += 3;
465
466 DO_2BITS(asf->packet_flags >> 5, packet_length, s->packet_size);
467 DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored
468 DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length
469
470 if (read(priv->fd, buffer, 4) < 4) {
471 fprintf(stderr, "asf_decoder: read error getting value\n");
472 return -5;
473 }
474
475 priv->input_position += 4;
476
477 asf->packet_timestamp = get_le32int(buffer); // send time
478
479 //the following checks prevent overflows and infinite loops
480 if (!packet_length || packet_length >= (1U << 29)) {
481 fprintf(stderr, "invalid packet_length %d at:%"PRId64"\n", packet_length, priv->input_position);
482 return -3;
483 }
484 if (padsize >= packet_length) {
485 fprintf(stderr, "invalid padsize %d at:%"PRId64"\n", padsize, priv->input_position);
486 return -4;
487 }
488
489 if (read(priv->fd, buffer, 2) < 2) {
490 fprintf(stderr, "asf_decoder: read error getting value\n");
491 return -2;
492 }
493 priv->input_position += 2;
494
495 //duration = get_le16int(buffer);
496
497 // rsize has at least 11 bytes which have to be present
498
499 if (asf->packet_flags & 0x01) {
500 // multi segments
501 if (read(priv->fd, buffer, 1) < 1) {
502 fprintf(stderr, "asf_decoder: read error getting value\n");
503 return -2;
504 }
505 priv->input_position++;
506 asf->packet_segsizetype = buffer[0];
507 rsize++;
508 asf->packet_segments = asf->packet_segsizetype & 0x3f;
509 } else {
510 // single segment
511 asf->packet_segments = 1;
512 asf->packet_segsizetype = 0x80;
513 }
514
515 asf->packet_size_left = packet_length - padsize - rsize;
516
517 if (packet_length < asf->hdr.min_pktsize)
518 padsize += asf->hdr.min_pktsize - packet_length;
519
520 asf->packet_padsize = padsize;
521
522 asf->packet_time_start = 0;
523
524 priv->fragnum = 0;
525 // packet header parsed
526 }
527
528 if (asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1) {
529 fprintf(stderr, "asf_decoder: bad packet\n");
530 return -8;
531 }
532
533 do {
534 // read frame header for fragment to get stream
535
536 lseek(priv->fd, priv->input_position, SEEK_SET);
537 frag_start = priv->input_position;
538
539 if (read(priv->fd, buffer, 1) < 1) {
540 fprintf(stderr, "asf_decoder: read error getting value\n");
541 return -2;
542 }
543
544 priv->input_position++;
545
546 num = buffer[0];
547 asf->packet_key_frame = num >> 7;
548
549 streamid = num & 0x7f;
550
551 #ifdef DEBUG
552 printf("streamid is %d\n", streamid);
553 #endif
554 rsize = 1;
555
556 if (asf->packet_time_start == 0) {
557 asf->asf_st = s->streams[asf->stream_index]->priv_data;
558
559 // read rest of frame header
560
561 DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
562 DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
563 DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);
564
565 if (asf->packet_replic_size >= 8) {
566
567 if (read(priv->fd, buffer, 4) < 4) {
568 fprintf(stderr, "asf_decoder: read error getting value\n");
569 return -2;
570 }
571 priv->input_position += 4;
572 asf->packet_obj_size = get_le32int(buffer);
573
574 if (asf->packet_obj_size >= (1 << 24) || asf->packet_obj_size <= 0) {
575 if (streamid == vidindex) {
576 fprintf(stderr, "asf_decoder: packet_obj_size invalid\n");
577 return -9;
578 }
579 }
580
581 if (read(priv->fd, buffer, 4) < 4) {
582 fprintf(stderr, "asf_decoder: read error getting value\n");
583 return -2;
584 }
585 priv->input_position += 4;
586
587 asf->packet_frag_timestamp = get_le32int(buffer); // timestamp
588
589 if (asf->packet_replic_size >= 8 + 38 + 4) {
590
591 priv->input_position += 10;
592 lseek(priv->fd, 10, SEEK_CUR);
593
594 if (read(priv->fd, buffer, 8) < 8) {
595 fprintf(stderr, "asf_decoder: read error getting value\n");
596 return -2;
597 }
598 priv->input_position += 8;
599 ts0 = get_le64int(buffer);
600
601 priv->input_position += asf->packet_replic_size + 16 - 38 - 4;
602 lseek(priv->fd, asf->packet_replic_size + 16 - 38 - 4, SEEK_CUR);
603
604 if (ts0 != -1) asf->packet_frag_timestamp = ts0 / 10000;
605 else asf->packet_frag_timestamp = AV_NOPTS_VALUE;
606 } else {
607 priv->input_position += asf->packet_replic_size - 8;
608 lseek(priv->fd, asf->packet_replic_size - 8, SEEK_CUR);
609 }
610 rsize += asf->packet_replic_size; // FIXME - check validity
611 } else if (asf->packet_replic_size == 1) {
612 // single packet ? - frag_offset is beginning timestamp
613 asf->packet_time_start = asf->packet_frag_offset;
614 asf->packet_frag_offset = 0;
615 asf->packet_frag_timestamp = asf->packet_timestamp;
616
617 if (read(priv->fd, buffer, 1) < 1) {
618 fprintf(stderr, "asf_decoder: read error getting value\n");
619 return -2;
620 }
621 priv->input_position += 1;
622
623 asf->packet_time_delta = buffer[0];
624
625 rsize++;
626 } else if (asf->packet_replic_size != 0) {
627 if (check_eof(cdata)) {
628 // could also be EOF in DO_2_BITS
629 fprintf(stderr, "asf_decoder: EOF");
630 return -2;
631 }
632 fprintf(stderr, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);
633 return -1;
634 }
635
636 if (asf->packet_flags & 0x01) {
637 // multi fragments
638 DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal
639 if (asf->packet_frag_size > asf->packet_size_left - rsize) {
640 fprintf(stderr, "asf_decoder: packet_frag_size is invalid (%d > %d) %d %d\n", asf->packet_frag_size,
641 asf->packet_size_left - rsize,
642 asf->packet_padsize, rsize);
643
644 #ifdef DEBUG
645 printf("skipping %d %ld\n", asf->packet_size_left + asf->packet_padsize - 2, asf->packet_padsize);
646 #endif
647
648 lseek(priv->fd, asf->packet_size_left + asf->packet_padsize - 2 - rsize, SEEK_CUR);
649 priv->input_position += asf->packet_size_left + asf->packet_padsize - 2 - rsize;
650 asf->packet_segments = 0;
651 asf->packet_size_left = 0;
652
653 return -1;
654 }
655 #ifdef DEBUG
656 printf("Fragsize %d nsegs %d\n", asf->packet_frag_size, asf->packet_segments);
657 #endif
658 } else {
659 asf->packet_frag_size = asf->packet_size_left - rsize;
660 #ifdef DEBUG
661 printf("Using rest %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize);
662 #endif
663 }
664 }
665
666 if (streamid == vidindex) {
667 #ifdef DEBUG
668 printf("got vid fragment in packet !\n");
669 #endif
670
671 if (asf->packet_key_frame && asf->packet_frag_offset == 0 && priv->have_start_dts) {
672 pthread_mutex_lock(&priv->idxc->mutex);
673 priv->kframe = add_keyframe(cdata, priv->hdr_start, priv->fragnum, asf->packet_frag_timestamp - priv->start_dts);
674 pthread_mutex_unlock(&priv->idxc->mutex);
675
676 #ifdef DEBUG
677 printf("and is keyframe !\n");
678 #endif
679 }
680
681 if (tdts >= 0 && (asf->packet_frag_timestamp >= tdts)) {
682 // reached target dts
683 return 0;
684 }
685
686 if (asf->packet_frag_offset == 0) {
687 if (pack_fill == 0) priv->frame_dts = asf->packet_frag_timestamp;
688 else if (tdts == -1) {
689 // got complete AV video packet
690 priv->input_position = frag_start;
691 priv->avpkt.size = pack_fill;
692 return 0;
693 }
694 }
695
696 priv->fragnum++;
697
698 if (tfrag <= 0 && tdts == -1) {
699 if (asf->packet_frag_offset != 0 && pack_fill == 0) {
700 // we reached our target, but it has a non-zero offset, which is not allowed
701 // So skip this packet;
702 // - this could happen if we have broken fragments at the start of the clip.
703 priv->input_position += asf->packet_frag_size;
704 continue;
705 }
706
707 while (asf->packet_frag_offset + asf->packet_frag_size > priv->avpkt.size) {
708 fprintf(stderr, "asf_decoder: buffer overflow reading vid packet (%d + %d > %d),\n increasing buffer size\n",
709 asf->packet_frag_offset, asf->packet_frag_size, priv->avpkt.size);
710
711 priv->avpkt.data = realloc(priv->avpkt.data, priv->def_packet_size * 2 + AV_INPUT_BUFFER_PADDING_SIZE);
712 memset(priv->avpkt.data + priv->avpkt.size, 0, priv->def_packet_size);
713 priv->def_packet_size *= 2;
714 priv->avpkt.size = priv->def_packet_size + AV_INPUT_BUFFER_PADDING_SIZE;
715 }
716
717 if (read(priv->fd, priv->avpkt.data + asf->packet_frag_offset, asf->packet_frag_size)
718 < asf->packet_frag_size) {
719 fprintf(stderr, "asf_decoder: EOF error reading vid packet\n");
720 return -2;
721 }
722 pack_fill = asf->packet_frag_offset + asf->packet_frag_size;
723 }
724
725 priv->input_position += asf->packet_frag_size;
726
727 tfrag--;
728
729 } else {
730 // fragment is for another stream
731 priv->input_position += asf->packet_frag_size;
732 }
733
734 asf->packet_size_left -= asf->packet_frag_size + rsize;
735 asf->packet_segments--;
736 } while (asf->packet_segments > 0);
737
738 // no more fragments left, skip remainder of asf packet
739
740 #ifdef DEBUG
741 //printf("skipping %d %ld\n",asf->packet_size_left + asf->packet_padsize - 2, asf->packet_padsize);
742 #endif
743
744 priv->input_position += asf->packet_size_left + asf->packet_padsize - 2;
745 }
746
747 // will never reach here
748 return 0;
749 }
750
751
get_idx_for_pts(const lives_clip_data_t * cdata,int64_t pts)752 static index_entry *get_idx_for_pts(const lives_clip_data_t *cdata, int64_t pts) {
753 lives_asf_priv_t *priv = cdata->priv;
754 int64_t tdts = pts;
755 index_entry *idx = priv->idxc->idx, *lidx = idx;
756 int ret;
757
758 while (idx != NULL) {
759 if (idx->dts > tdts) return lidx;
760 lidx = idx;
761 idx = idx->next;
762 }
763 priv->kframe = lidx;
764 priv->input_position = lidx->offs;
765 do {
766 ret = get_next_video_packet(cdata, lidx->frag, tdts);
767 } while (ret < 0 && ret != -2);
768 if (ret != -2) return priv->kframe;
769 return NULL;
770 }
771
772
get_last_video_dts(const lives_clip_data_t * cdata)773 static int get_last_video_dts(const lives_clip_data_t *cdata) {
774 // get last vido frame dts (relative to start dts)
775 lives_asf_priv_t *priv = cdata->priv;
776
777 pthread_mutex_lock(&priv->idxc->mutex);
778 priv->kframe = get_idx_for_pts(cdata, frame_to_dts(cdata, 0) - priv->start_dts);
779 pthread_mutex_unlock(&priv->idxc->mutex);
780 // this will parse through the file, adding keyframes, until we reach EOF
781
782 priv->input_position = priv->kframe->offs;
783 asf_reset_header(priv->s);
784 get_next_video_packet(cdata, priv->kframe->frag, INT_MAX);
785
786 // priv->kframe will hold last kframe in the clip
787 return priv->frame_dts - priv->start_dts;
788 }
789
790
791 //////////////////////////////////////////////
792
idxc_for(lives_clip_data_t * cdata)793 static index_container_t *idxc_for(lives_clip_data_t *cdata) {
794 // check all idxc for string match with URI
795 index_container_t *idxc;
796 register int i;
797
798 pthread_mutex_lock(&indices_mutex);
799
800 for (i = 0; i < nidxc; i++) {
801 if (indices[i]->clients[0]->current_clip == cdata->current_clip &&
802 !strcmp(indices[i]->clients[0]->URI, cdata->URI)) {
803 idxc = indices[i];
804 // append cdata to clients
805 idxc->clients = (lives_clip_data_t **)realloc(idxc->clients, (idxc->nclients + 1) * sizeof(lives_clip_data_t *));
806 idxc->clients[idxc->nclients] = cdata;
807 idxc->nclients++;
808 //
809 pthread_mutex_unlock(&indices_mutex);
810 return idxc;
811 }
812 }
813
814 indices = (index_container_t **)realloc(indices, (nidxc + 1) * sizeof(index_container_t *));
815
816 // match not found, create a new index container
817 idxc = (index_container_t *)malloc(sizeof(index_container_t));
818
819 idxc->idx = NULL;
820
821 idxc->nclients = 1;
822 idxc->clients = (lives_clip_data_t **)malloc(sizeof(lives_clip_data_t *));
823 idxc->clients[0] = cdata;
824
825 pthread_mutex_init(&idxc->mutex, &mattr);
826
827 indices[nidxc] = idxc;
828 pthread_mutex_unlock(&indices_mutex);
829
830 nidxc++;
831
832 return idxc;
833 }
834
835
idxc_release(lives_clip_data_t * cdata)836 static void idxc_release(lives_clip_data_t *cdata) {
837 lives_asf_priv_t *priv = cdata->priv;
838 index_container_t *idxc = priv->idxc;
839 register int i, j;
840
841 if (idxc == NULL) return;
842
843 pthread_mutex_lock(&indices_mutex);
844
845 if (idxc->nclients == 1) {
846 // remove this index
847 index_free(idxc->idx);
848 free(idxc->clients);
849 for (i = 0; i < nidxc; i++) {
850 if (indices[i] == idxc) {
851 nidxc--;
852 for (j = i; j < nidxc; j++) {
853 indices[j] = indices[j + 1];
854 }
855 free(idxc);
856 if (nidxc == 0) {
857 free(indices);
858 indices = NULL;
859 } else indices = (index_container_t **)realloc(indices, nidxc * sizeof(index_container_t *));
860 break;
861 }
862 }
863 } else {
864 // reduce client count by 1
865 for (i = 0; i < idxc->nclients; i++) {
866 if (idxc->clients[i] == cdata) {
867 // remove this entry
868 idxc->nclients--;
869 for (j = i; j < idxc->nclients; j++) {
870 idxc->clients[j] = idxc->clients[j + 1];
871 }
872 idxc->clients = (lives_clip_data_t **)realloc(idxc->clients, idxc->nclients * sizeof(lives_clip_data_t *));
873 break;
874 }
875 }
876 }
877
878 pthread_mutex_unlock(&indices_mutex);
879 }
880
881
idxc_release_all(void)882 static void idxc_release_all(void) {
883 register int i;
884
885 for (i = 0; i < nidxc; i++) {
886 index_free(indices[i]->idx);
887 free(indices[i]->clients);
888 free(indices[i]);
889 }
890 nidxc = 0;
891 }
892
893
detach_stream(lives_clip_data_t * cdata)894 static void detach_stream(lives_clip_data_t *cdata) {
895 // close the file, free the decoder
896 lives_asf_priv_t *priv = cdata->priv;
897
898 cdata->seek_flag = 0;
899
900 if (priv->avpkt.data != NULL) free(priv->avpkt.data);
901 priv->avpkt.data = NULL;
902 priv->avpkt.size = 0;
903
904 if (priv->ctx != NULL) {
905 avcodec_close(priv->ctx);
906 av_free(priv->ctx);
907 }
908
909 if (priv->picture != NULL) av_frame_unref(priv->picture);
910
911 priv->ctx = NULL;
912 priv->picture = NULL;
913
914 if (cdata->palettes != NULL) free(cdata->palettes);
915 cdata->palettes = NULL;
916
917 free(priv->asf);
918
919 av_free(priv->s);
920 //avformat_free_context(priv->s);
921
922 if (priv->st != NULL) {
923 if (priv->st->codec->extradata_size != 0) free(priv->st->codec->extradata);
924 }
925
926 if (priv->asf_st != NULL) free(priv->asf_st);
927
928 close(priv->fd);
929 }
930
931
attach_stream(lives_clip_data_t * cdata,boolean isclone)932 static boolean attach_stream(lives_clip_data_t *cdata, boolean isclone) {
933 // open the file and get metadata
934 lives_asf_priv_t *priv = cdata->priv;
935 char header[16];
936 unsigned char buffer[4096];
937 unsigned char flags;
938
939 int i, len, retval;
940 int size;
941
942 boolean got_vidst = FALSE;
943 boolean got_picture = FALSE;
944 boolean gotframe2 = FALSE;
945 boolean is_partial_clone = FALSE;
946
947 double fps;
948
949 AVCodec *codec = NULL;
950 AVCodecContext *ctx;
951 AVStream *vidst = NULL;
952
953 int64_t pts = AV_NOPTS_VALUE, pts2 = pts;
954 int64_t gsize;
955 int64_t ftime;
956
957 lives_asf_guid g;
958
959 AVRational dar[128];
960 uint32_t bitrate[128];
961
962 int16_t vidindex = -1;
963
964 struct stat sb;
965
966 #ifdef DEBUG
967 fprintf(stderr, "\n");
968 #endif
969
970 if (isclone && !priv->inited) {
971 isclone = FALSE;
972 if (cdata->fps > 0. && cdata->nframes > 0)
973 is_partial_clone = TRUE;
974 }
975
976 if ((priv->fd = open(cdata->URI, O_RDONLY)) == -1) {
977 fprintf(stderr, "asf_decoder: unable to open %s\n", cdata->URI);
978 return FALSE;
979 }
980
981 #ifdef IS_MINGW
982 setmode(priv->fd, O_BINARY);
983 #endif
984
985 if (isclone) {
986 lseek(priv->fd, ASF_PROBE_SIZE + 14, SEEK_SET);
987 priv->input_position = ASF_PROBE_SIZE + 14;
988 goto seek_skip;
989 }
990
991 if (read(priv->fd, header, ASF_PROBE_SIZE) < ASF_PROBE_SIZE) {
992 // for example, might be a directory
993 #ifdef DEBUG
994 fprintf(stderr, "asf_decoder: unable to read header for %s\n", cdata->URI);
995 #endif
996 close(priv->fd);
997 return FALSE;
998 }
999
1000 priv->input_position = ASF_PROBE_SIZE;
1001
1002 // test header
1003 if (guidcmp(header, &lives_asf_header)) {
1004 #ifdef DEBUG
1005 fprintf(stderr, "asf_decoder: not asf header\n");
1006 #endif
1007 close(priv->fd);
1008 return FALSE;
1009 }
1010
1011 // skip 14 bytes
1012 lseek(priv->fd, 14, SEEK_CUR);
1013
1014 priv->input_position += 14;
1015
1016 cdata->par = 1.;
1017 cdata->fps = 0.;
1018 cdata->width = cdata->frame_width = cdata->height = cdata->frame_height = 0;
1019 cdata->offs_x = cdata->offs_y = 0;
1020
1021 cdata->arate = 0;
1022 cdata->achans = 0;
1023 cdata->asamps = 0;
1024 sprintf(cdata->audio_name, "%s", "");
1025
1026 cdata->seek_flag = LIVES_SEEK_FAST | LIVES_SEEK_NEEDS_CALCULATION;
1027
1028 cdata->offs_x = 0;
1029 cdata->offs_y = 0;
1030
1031 cdata->frame_gamma = WEED_GAMMA_UNKNOWN;
1032
1033 fstat(priv->fd, &sb);
1034 priv->filesize = sb.st_size;
1035
1036 seek_skip:
1037
1038 priv->idxc = idxc_for(cdata);
1039
1040 priv->asf = (ASFContext *)malloc(sizeof(ASFContext));
1041 memset(&priv->asf->asfid2avid, -1, sizeof(priv->asf->asfid2avid));
1042 priv->s = avformat_alloc_context();
1043 priv->s->priv_data = priv->asf;
1044 av_init_packet(&priv->avpkt);
1045 priv->avpkt.data = NULL;
1046 priv->avpkt.size = 0;
1047 priv->st = NULL;
1048 priv->asf_st = NULL;
1049 priv->ctx = NULL;
1050
1051 for (i = 0; i < 128; i++) dar[i].num = dar[i].den = 0;
1052
1053 for (;;) {
1054 int64_t gpos = priv->input_position;
1055
1056 get_guid(priv->fd, &g);
1057 priv->input_position += sizeof(lives_asf_guid);
1058
1059 if (read(priv->fd, buffer, 8) < 8) {
1060 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1061 detach_stream(cdata);
1062 return FALSE;
1063 }
1064
1065 priv->input_position += 8;
1066
1067 gsize = get_le64int(buffer);
1068
1069 if (!guidcmp(&g, &lives_asf_data_header)) {
1070 priv->asf->data_object_offset = priv->input_position;
1071 if (!(priv->asf->hdr.flags & 0x01) && gsize >= 100) {
1072 priv->asf->data_object_size = gsize - 24;
1073 } else {
1074 priv->asf->data_object_size = (uint64_t) - 1;
1075 }
1076 break;
1077 }
1078
1079 if (gsize < 24) {
1080 fprintf(stderr, "asf_decoder: guid too small in %s\n", cdata->URI);
1081 detach_stream(cdata);
1082 return FALSE;
1083 }
1084
1085 if (!guidcmp(&g, &lives_asf_file_header)) {
1086 // tested OK
1087
1088 get_guid(priv->fd, &priv->asf->hdr.guid);
1089 priv->input_position += sizeof(lives_asf_guid);
1090
1091 if (read(priv->fd, buffer, 8) < 8) {
1092 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1093 detach_stream(cdata);
1094 return FALSE;
1095 }
1096
1097 priv->input_position += 8;
1098 priv->asf->hdr.file_size = get_le64int(buffer);
1099
1100 #ifdef DEBUG
1101 fprintf(stderr, "hdr says size is %ld\n", priv->asf->hdr.file_size);
1102 #endif
1103
1104 if (read(priv->fd, buffer, 8) < 8) {
1105 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1106 detach_stream(cdata);
1107 return FALSE;
1108 }
1109
1110 priv->input_position += 8;
1111 priv->asf->hdr.create_time = get_le64int(buffer);
1112
1113 if (read(priv->fd, buffer, 8) < 8) {
1114 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1115 detach_stream(cdata);
1116 return FALSE;
1117 }
1118
1119 priv->input_position += 8;
1120 priv->asf->nb_packets = get_le64int(buffer);
1121
1122 #ifdef DEBUG
1123 fprintf(stderr, "hdr says pax is %ld\n", priv->asf->nb_packets);
1124 #endif
1125
1126 if (read(priv->fd, buffer, 8) < 8) {
1127 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1128 detach_stream(cdata);
1129 return FALSE;
1130 }
1131
1132 priv->input_position += 8;
1133 priv->asf->hdr.play_time = get_le64int(buffer);
1134
1135 #ifdef DEBUG
1136 fprintf(stderr, "hdr says playtime is %ld\n", priv->asf->hdr.play_time);
1137 #endif
1138
1139 if (read(priv->fd, buffer, 8) < 8) {
1140 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1141 detach_stream(cdata);
1142 return FALSE;
1143 }
1144
1145 priv->input_position += 8;
1146 // seems to be the duration
1147 priv->asf->hdr.send_time = get_le64int(buffer);
1148
1149 #ifdef DEBUG
1150 fprintf(stderr, "hdr says send time is %ld\n", priv->asf->hdr.send_time);
1151 #endif
1152
1153 if (read(priv->fd, buffer, 4) < 4) {
1154 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1155 detach_stream(cdata);
1156 return FALSE;
1157 }
1158
1159 priv->input_position += 4;
1160 priv->asf->hdr.preroll = get_le32int(buffer);
1161
1162 #ifdef DEBUG
1163 fprintf(stderr, "hdr says preroll is %d\n", priv->asf->hdr.preroll);
1164 #endif
1165
1166 if (read(priv->fd, buffer, 4) < 4) {
1167 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1168 detach_stream(cdata);
1169 return FALSE;
1170 }
1171
1172 priv->input_position += 4;
1173 priv->asf->hdr.ignore = get_le32int(buffer);
1174
1175 if (read(priv->fd, buffer, 4) < 4) {
1176 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1177 detach_stream(cdata);
1178 return FALSE;
1179 }
1180
1181 priv->input_position += 4;
1182 priv->asf->hdr.flags = get_le32int(buffer);
1183
1184 if (read(priv->fd, buffer, 4) < 4) {
1185 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1186 detach_stream(cdata);
1187 return FALSE;
1188 }
1189
1190 priv->input_position += 4;
1191 priv->asf->hdr.min_pktsize = get_le32int(buffer);
1192
1193 if (read(priv->fd, buffer, 4) < 4) {
1194 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1195 detach_stream(cdata);
1196 return FALSE;
1197 }
1198
1199 priv->input_position += 4;
1200 priv->asf->hdr.max_pktsize = get_le32int(buffer);
1201
1202 if (read(priv->fd, buffer, 4) < 4) {
1203 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1204 detach_stream(cdata);
1205 return FALSE;
1206 }
1207
1208 priv->input_position += 4;
1209 priv->asf->hdr.max_bitrate = get_le32int(buffer);
1210
1211 priv->s->packet_size = priv->asf->hdr.max_pktsize;
1212
1213 #ifdef DEBUG
1214 fprintf(stderr, "hdr says maxbr is %d\n", priv->asf->hdr.max_bitrate);
1215 #endif
1216
1217 } else if (!guidcmp(&g, &lives_asf_stream_header)) {
1218 enum LiVESMediaType type;
1219 int sizeX;
1220 //uint64_t total_size;
1221 unsigned int tag1;
1222 int64_t pos1, pos2, start_time;
1223 int test_for_ext_stream_audio;
1224
1225 pos1 = priv->input_position;
1226
1227 priv->st = av_new_stream(priv->s, 0);
1228
1229 if (!priv->st) {
1230 fprintf(stderr, "asf_decoder: Unable to create new stream for %s\n", cdata->URI);
1231 detach_stream(cdata);
1232 return FALSE;
1233 }
1234
1235 av_set_pts_info(priv->st, 32, 1, 1000); /* 32 bit pts in ms */
1236 priv->st->codec->extradata_size = 0;
1237
1238 priv->asf_st = malloc(sizeof(ASFStream));
1239 memset(priv->asf_st, 0, (sizeof(ASFStream)));
1240
1241 if (!priv->asf_st) {
1242 fprintf(stderr, "asf_decoder: Unable to create asf stream for %s\n", cdata->URI);
1243 detach_stream(cdata);
1244 return FALSE;
1245 }
1246
1247 priv->st->priv_data = priv->asf_st;
1248 start_time = priv->asf->hdr.preroll;
1249
1250 priv->asf_st->stream_language_index = 128; // invalid stream index means no language info
1251
1252 if (!(priv->asf->hdr.flags & 0x01)) { // if we aren't streaming...
1253 priv->st->duration = priv->asf->hdr.play_time /
1254 (10000000 / 1000) - start_time;
1255 }
1256
1257 get_guid(priv->fd, &g);
1258 priv->input_position += sizeof(lives_asf_guid);
1259
1260 test_for_ext_stream_audio = 0;
1261 if (!guidcmp(&g, &lives_asf_audio_stream)) {
1262 type = LIVES_MEDIA_TYPE_AUDIO;
1263 } else if (!guidcmp(&g, &lives_asf_video_stream)) {
1264 type = LIVES_MEDIA_TYPE_VIDEO;
1265 } else if (!guidcmp(&g, &lives_asf_command_stream)) {
1266 type = LIVES_MEDIA_TYPE_DATA;
1267 } else if (!guidcmp(&g, &lives_asf_ext_stream_embed_stream_header)) {
1268 test_for_ext_stream_audio = 1;
1269 type = LIVES_MEDIA_TYPE_UNKNOWN;
1270 } else {
1271 return -1;
1272 }
1273
1274 get_guid(priv->fd, &g);
1275 priv->input_position += sizeof(lives_asf_guid);
1276
1277 if (read(priv->fd, buffer, 8) < 8) {
1278 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1279 detach_stream(cdata);
1280 return FALSE;
1281 }
1282
1283 priv->input_position += 8;
1284
1285 // total_size = get_le64int(buffer);
1286
1287 if (read(priv->fd, buffer, 4) < 4) {
1288 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1289 detach_stream(cdata);
1290 return FALSE;
1291 }
1292
1293 priv->input_position += 4;
1294
1295 //type_specific_size = get_le32int(buffer);
1296
1297 lseek(priv->fd, 4, SEEK_CUR);
1298 priv->input_position += 4;
1299
1300 if (read(priv->fd, buffer, 2) < 2) {
1301 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1302 detach_stream(cdata);
1303 return FALSE;
1304 }
1305
1306 priv->input_position += 2;
1307
1308 priv->st->id = get_le16int(buffer) & 0x7f; /* stream id */
1309 // mapping of asf ID to AV stream ID;
1310 priv->asf->asfid2avid[priv->st->id] = priv->s->nb_streams - 1;
1311
1312 lseek(priv->fd, 4, SEEK_CUR);
1313 priv->input_position += 4;
1314
1315 if (test_for_ext_stream_audio) {
1316 get_guid(priv->fd, &g);
1317 priv->input_position += sizeof(lives_asf_guid);
1318
1319 if (!guidcmp(&g, &lives_asf_ext_stream_audio_stream)) {
1320 type = LIVES_MEDIA_TYPE_AUDIO;
1321 //is_dvr_ms_audio=1;
1322 get_guid(priv->fd, &g);
1323 priv->input_position += sizeof(lives_asf_guid);
1324
1325 lseek(priv->fd, 12, SEEK_CUR);
1326 priv->input_position += 12;
1327
1328 get_guid(priv->fd, &g);
1329 priv->input_position += sizeof(lives_asf_guid);
1330
1331 lseek(priv->fd, 4, SEEK_CUR);
1332 priv->input_position += 4;
1333 }
1334 }
1335
1336 if (type == LIVES_MEDIA_TYPE_AUDIO) {
1337 priv->st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
1338
1339 } else if (type == LIVES_MEDIA_TYPE_VIDEO) {
1340 priv->st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
1341 if (vidindex != -1 && vidindex != priv->st->id) {
1342 fprintf(stderr, "asf_decoder: unhandled multiple vidstreams %d and %d in %s\n", vidindex, priv->st->id, cdata->URI);
1343 got_vidst = TRUE;
1344 detach_stream(cdata);
1345 return FALSE;
1346 } else {
1347 vidst = priv->st;
1348 vidindex = vidst->id;
1349 priv->asf->stream_index = priv->asf->asfid2avid[vidindex];
1350 }
1351
1352 lseek(priv->fd, 9, SEEK_CUR);
1353 priv->input_position += 9;
1354
1355 if (read(priv->fd, buffer, 2) < 2) {
1356 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1357 detach_stream(cdata);
1358 return FALSE;
1359 }
1360
1361 priv->input_position += 2;
1362
1363 size = get_le16int(buffer); /* size */
1364
1365 if (read(priv->fd, buffer, 4) < 4) {
1366 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1367 detach_stream(cdata);
1368 return FALSE;
1369 }
1370
1371 priv->input_position += 4;
1372 sizeX = get_le32int(buffer); /* size */
1373
1374 if (read(priv->fd, buffer, 4) < 4) {
1375 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1376 detach_stream(cdata);
1377 return FALSE;
1378 }
1379
1380 priv->input_position += 4;
1381
1382 if (!got_vidst) cdata->width = priv->st->codec->width = get_le32int(buffer);
1383
1384 if (read(priv->fd, buffer, 4) < 4) {
1385 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1386 detach_stream(cdata);
1387 return FALSE;
1388 }
1389
1390 priv->input_position += 4;
1391 if (!got_vidst) cdata->height = priv->st->codec->height = get_le32int(buffer);
1392
1393 /* not available for asf */
1394 lseek(priv->fd, 2, SEEK_CUR); // panes
1395 priv->input_position += 2;
1396
1397
1398 if (read(priv->fd, buffer, 2) < 2) {
1399 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1400 detach_stream(cdata);
1401 return FALSE;
1402 }
1403
1404 priv->input_position += 2;
1405
1406 if (!got_vidst) priv->st->codec->bits_per_coded_sample = get_le16int(buffer); /* depth */
1407
1408 if (read(priv->fd, buffer, 4) < 4) {
1409 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1410 detach_stream(cdata);
1411 return FALSE;
1412 }
1413
1414 priv->input_position += 4;
1415 tag1 = get_le32int(buffer);
1416
1417 lseek(priv->fd, 20, SEEK_CUR);
1418 priv->input_position += 20;
1419
1420 size = sizeX;
1421
1422 if (size > 40) {
1423 if (!got_vidst) {
1424 priv->st->codec->extradata_size = size - 40;
1425
1426 priv->st->codec->extradata = malloc(priv->st->codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
1427 memset(priv->st->codec->extradata, 0, priv->st->codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
1428
1429 if (read(priv->fd, priv->st->codec->extradata,
1430 priv->st->codec->extradata_size) < priv->st->codec->extradata_size) {
1431 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1432 detach_stream(cdata);
1433 return FALSE;
1434 }
1435 } else lseek(priv->fd, size - 40, SEEK_CUR);
1436 priv->input_position += priv->st->codec->extradata_size;
1437
1438 }
1439
1440 /* Extract palette from extradata if bpp <= 8 */
1441 /* This code assumes that extradata contains only palette */
1442 /* This is true for all paletted codecs implemented in ffmpeg */
1443
1444 if (!got_vidst) {
1445 if (priv->st->codec->extradata_size && (priv->st->codec->bits_per_coded_sample <= 8)) {
1446
1447
1448 #if !defined (IS_MINGW) && !defined (IS_SOLARIS) && !defined (__DragonFly__)
1449 # if __BYTE_ORDER == __BIG_ENDIAN
1450 int i;
1451 for (i = 0; i < FFMIN(priv->st->codec->extradata_size, AVPALETTE_SIZE) / 4; i++)
1452 priv->asf_st->palette[i] = av_bswap32(((uint32_t *)priv->st->codec->extradata)[i]);
1453 #else
1454 memcpy(priv->asf_st->palette, priv->st->codec->extradata,
1455 FFMIN(priv->st->codec->extradata_size, AVPALETTE_SIZE));
1456 #endif
1457 #else
1458 memcpy(priv->asf_st->palette, priv->st->codec->extradata,
1459 FFMIN(priv->st->codec->extradata_size, AVPALETTE_SIZE));
1460 #endif
1461
1462 priv->asf_st->palette_changed = 1;
1463 }
1464
1465 priv->st->codec->codec_tag = tag1;
1466 priv->st->codec->codec_id = ff_codec_get_id((const AVCodecTag *)(codec_bmp_tags), tag1);
1467
1468 if (tag1 == FOURCC_DVR)
1469 priv->st->need_parsing = AVSTREAM_PARSE_FULL;
1470 }
1471 }
1472
1473 pos2 = priv->input_position;
1474 gsize -= (pos2 - pos1 + 24);
1475 lseek(priv->fd, gsize, SEEK_CUR);
1476 priv->input_position += gsize;
1477 gsize += (pos2 - pos1 + 24);
1478 } else if (!guidcmp(&g, &lives_asf_comment_header)) {
1479 int len1, len2, len3, len4, len5;
1480
1481 if (read(priv->fd, buffer, 2) < 2) {
1482 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1483 detach_stream(cdata);
1484 return FALSE;
1485 }
1486
1487 priv->input_position += 2;
1488
1489 len1 = get_le16int(buffer);
1490
1491 if (read(priv->fd, buffer, 2) < 2) {
1492 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1493 detach_stream(cdata);
1494 return FALSE;
1495 }
1496
1497 priv->input_position += 2;
1498
1499 len2 = get_le16int(buffer);
1500
1501 if (read(priv->fd, buffer, 2) < 2) {
1502 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1503 detach_stream(cdata);
1504 return FALSE;
1505 }
1506
1507 priv->input_position += 2;
1508
1509 len3 = get_le16int(buffer);
1510 if (read(priv->fd, buffer, 2) < 2) {
1511 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1512 detach_stream(cdata);
1513 return FALSE;
1514 }
1515
1516 priv->input_position += 2;
1517
1518 len4 = get_le16int(buffer);
1519
1520 if (read(priv->fd, buffer, 2) < 2) {
1521 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1522 detach_stream(cdata);
1523 return FALSE;
1524 }
1525
1526 priv->input_position += 2;
1527
1528 len5 = get_le16int(buffer);
1529
1530 /* get_tag(s, "title" , 0, len1);
1531 get_tag(s, "author" , 0, len2);
1532 get_tag(s, "copyright", 0, len3);
1533 get_tag(s, "comment" , 0, len4); */
1534
1535 lseek(priv->fd, len1 + len2 + len3 + len4 + len5, SEEK_CUR);
1536 priv->input_position += len1 + len2 + len3 + len4 + len5;
1537
1538 #ifdef DEBUG
1539 fprintf(stderr, "skipping fwd %d bytes\n", len1 + len2 + len3 + len4 + len5);
1540 #endif
1541 } else if (!guidcmp(&g, &stream_bitrate_guid)) {
1542 int stream_count;
1543 int j;
1544
1545 if (read(priv->fd, buffer, 2) < 2) {
1546 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1547 detach_stream(cdata);
1548 return FALSE;
1549 }
1550
1551 priv->input_position += 2;
1552
1553 stream_count = get_le16int(buffer);
1554
1555 for (j = 0; j < stream_count; j++) {
1556 int flags, bitrate, stream_id;
1557
1558 if (read(priv->fd, buffer, 2) < 2) {
1559 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1560 detach_stream(cdata);
1561 return FALSE;
1562 }
1563
1564 priv->input_position += 2;
1565
1566 flags = get_le16int(buffer);
1567
1568 if (read(priv->fd, buffer, 4) < 4) {
1569 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1570 detach_stream(cdata);
1571 return FALSE;
1572 }
1573
1574 priv->input_position += 4;
1575 bitrate = get_le32int(buffer);
1576 stream_id = (flags & 0x7f);
1577 priv->asf->stream_bitrates[stream_id] = bitrate;
1578 }
1579 } else if (!guidcmp(&g, &lives_asf_language_guid)) {
1580 int j;
1581 int stream_count = get_le16int(buffer);
1582 for (j = 0; j < stream_count; j++) {
1583 char lang[6];
1584 unsigned int lang_len;
1585
1586 if (read(priv->fd, buffer, 1) < 1) {
1587 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1588 detach_stream(cdata);
1589 return FALSE;
1590 }
1591
1592 priv->input_position += 1;
1593
1594 lang_len = buffer[0];
1595
1596 if (read(priv->fd, buffer, lang_len) < lang_len) {
1597 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1598 detach_stream(cdata);
1599 return FALSE;
1600 }
1601
1602 get_str16_nolen(buffer, lang_len, lang, sizeof(lang));
1603 priv->input_position += lang_len;
1604
1605 if (j < 128)
1606 av_strlcpy(priv->asf->stream_languages[j], lang, sizeof(*priv->asf->stream_languages));
1607 }
1608 } else if (!guidcmp(&g, &lives_asf_extended_content_header)) {
1609 int desc_count, i;
1610
1611 if (read(priv->fd, buffer, 2) < 2) {
1612 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1613 detach_stream(cdata);
1614 return FALSE;
1615 }
1616
1617 priv->input_position += 2;
1618
1619 desc_count = get_le16int(buffer);
1620
1621 for (i = 0; i < desc_count; i++) {
1622 int name_len, value_type, value_len;
1623 char name[1024];
1624
1625 if (read(priv->fd, buffer, 2) < 2) {
1626 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1627 detach_stream(cdata);
1628 return FALSE;
1629 }
1630
1631 priv->input_position += 2;
1632
1633 name_len = get_le16int(buffer);
1634
1635 if (name_len % 2) // must be even, broken lavf versions wrote len-1
1636 name_len += 1;
1637
1638 if (read(priv->fd, buffer, name_len) < name_len) {
1639 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1640 detach_stream(cdata);
1641 return FALSE;
1642 }
1643
1644 get_str16_nolen(buffer, name_len, name, sizeof(name));
1645
1646 priv->input_position += name_len;
1647
1648 if (read(priv->fd, buffer, 2) < 2) {
1649 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1650 detach_stream(cdata);
1651 return FALSE;
1652 }
1653
1654 priv->input_position += 2;
1655
1656 value_type = get_le16int(buffer);
1657
1658 if (read(priv->fd, buffer, 2) < 2) {
1659 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1660 detach_stream(cdata);
1661 return FALSE;
1662 }
1663
1664 priv->input_position += 2;
1665
1666 value_len = get_le16int(buffer);
1667 if (!value_type && value_len % 2)
1668 value_len += 1;
1669 if (!get_tag(cdata, priv->s, name, value_type, value_len)) return FALSE;
1670 }
1671 } else if (!guidcmp(&g, &lives_asf_metadata_header)) {
1672 int n, stream_num, name_len, value_len, value_num;
1673
1674 if (read(priv->fd, buffer, 2) < 2) {
1675 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1676 detach_stream(cdata);
1677 return FALSE;
1678 }
1679
1680 priv->input_position += 2;
1681
1682 n = get_le16int(buffer);
1683
1684 for (i = 0; i < n; i++) {
1685 char name[1024];
1686
1687 lseek(priv->fd, 2, SEEK_CUR); // lang_list_index
1688 priv->input_position += 2;
1689
1690 if (read(priv->fd, buffer, 2) < 2) {
1691 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1692 detach_stream(cdata);
1693 return FALSE;
1694 }
1695
1696 priv->input_position += 2;
1697
1698 stream_num = get_le16int(buffer);
1699
1700 if (read(priv->fd, buffer, 2) < 2) {
1701 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1702 detach_stream(cdata);
1703 return FALSE;
1704 }
1705
1706 priv->input_position += 2;
1707
1708 name_len = get_le16int(buffer);
1709
1710 if (read(priv->fd, buffer, 2) < 2) {
1711 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1712 detach_stream(cdata);
1713 return FALSE;
1714 }
1715
1716 priv->input_position += 2;
1717
1718 //value_type= get_le16int(buffer);
1719
1720 if (read(priv->fd, buffer, 4) < 4) {
1721 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1722 detach_stream(cdata);
1723 return FALSE;
1724 }
1725
1726 priv->input_position += 4;
1727
1728 value_len = get_le32int(buffer);
1729
1730 if (read(priv->fd, buffer, name_len) < name_len) {
1731 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1732 detach_stream(cdata);
1733 return FALSE;
1734 }
1735
1736 get_str16_nolen(buffer, name_len, name, sizeof(name));
1737
1738 priv->input_position += name_len;
1739
1740 if (read(priv->fd, buffer, 2) < 2) {
1741 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1742 detach_stream(cdata);
1743 return FALSE;
1744 }
1745
1746 priv->input_position += 2;
1747
1748 value_num = get_le16int(buffer);
1749
1750 // check this
1751 priv->input_position += value_len - 2;
1752 lseek(priv->fd, value_len + 2, SEEK_CUR);
1753
1754 if (stream_num < 128) {
1755 if (!strcmp(name, "AspectRatioX")) dar[stream_num].num =
1756 value_num;
1757 else if (!strcmp(name, "AspectRatioY")) dar[stream_num].den =
1758 value_num;
1759
1760 // i think PAR == 1/DAR (gf)
1761 if (cdata->par == 1. && dar[stream_num].num != 0 && dar[stream_num].den != 0)
1762 cdata->par = (float)dar[stream_num].den / (float)dar[stream_num].num;
1763 }
1764 }
1765 } else if (!guidcmp(&g, &lives_asf_ext_stream_header)) {
1766 int ext_len, payload_ext_ct, stream_ct;
1767 uint32_t leak_rate, stream_num;
1768 unsigned int stream_languageid_index;
1769
1770 lseek(priv->fd, 16, SEEK_CUR); // startime, endtime
1771 priv->input_position += 16;
1772
1773 if (read(priv->fd, buffer, 4) < 4) {
1774 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1775 detach_stream(cdata);
1776 return FALSE;
1777 }
1778
1779 priv->input_position += 4;
1780
1781 leak_rate = get_le32int(buffer); // leak-datarate
1782
1783 /* get_le32int(buffer); // bucket-datasize
1784 get_le32int(buffer); // init-bucket-fullness
1785 get_le32int(buffer); // alt-leak-datarate
1786 get_le32int(buffer); // alt-bucket-datasize
1787 get_le32int(buffer); // alt-init-bucket-fullness
1788 get_le32int(buffer); // max-object-size
1789 */
1790
1791 lseek(priv->fd, 20, SEEK_CUR);
1792 priv->input_position += 20;
1793
1794 if (read(priv->fd, buffer, 4) < 4) {
1795 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1796 detach_stream(cdata);
1797 return FALSE;
1798 }
1799
1800 priv->input_position += 4;
1801
1802 flags = get_le32int(buffer); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved)
1803
1804 if (!(flags & 0x02)) {
1805 #ifndef RELEASE
1806 fprintf(stderr, "asf_decoder: NON-SEEKABLE FILE, falling back to default open.\n");
1807 #endif
1808 detach_stream(cdata);
1809 return FALSE;
1810 }
1811
1812 if (read(priv->fd, buffer, 2) < 2) {
1813 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1814 detach_stream(cdata);
1815 return FALSE;
1816 }
1817
1818 priv->input_position += 2;
1819
1820 stream_num = get_le16int(buffer); // stream-num
1821
1822 if (read(priv->fd, buffer, 2) < 2) {
1823 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1824 detach_stream(cdata);
1825 return FALSE;
1826 }
1827
1828 priv->input_position += 2;
1829
1830 stream_languageid_index = get_le16int(buffer); // stream-language-id-index
1831 if (stream_num < 128)
1832 priv->asf->streams[stream_num].stream_language_index = stream_languageid_index;
1833
1834 if (read(priv->fd, buffer, 8) < 8) {
1835 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1836 detach_stream(cdata);
1837 return FALSE;
1838 }
1839
1840 priv->input_position += 8;
1841
1842 ftime = get_le64int(buffer); // avg frametime in 100ns units
1843
1844 if (cdata->fps == 0.) cdata->fps = (double)100000000. / (double)ftime;
1845
1846 if (read(priv->fd, buffer, 2) < 2) {
1847 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1848 detach_stream(cdata);
1849 return FALSE;
1850 }
1851
1852 priv->input_position += 2;
1853 stream_ct = get_le16int(buffer); //stream-name-count
1854
1855 if (read(priv->fd, buffer, 2) < 2) {
1856 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1857 detach_stream(cdata);
1858 return FALSE;
1859 }
1860
1861 priv->input_position += 2;
1862 payload_ext_ct = get_le16int(buffer); //payload-extension-system-count
1863
1864 if (stream_num < 128)
1865 bitrate[stream_num] = leak_rate;
1866
1867 for (i = 0; i < stream_ct; i++) {
1868 lseek(priv->fd, 2, SEEK_CUR);
1869 priv->input_position += 2;
1870
1871 if (read(priv->fd, buffer, 2) < 2) {
1872 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1873 detach_stream(cdata);
1874 return FALSE;
1875 }
1876
1877 priv->input_position += 2;
1878 ext_len = get_le16int(buffer);
1879
1880 lseek(priv->fd, ext_len, SEEK_CUR);
1881 priv->input_position += ext_len;
1882 }
1883
1884 for (i = 0; i < payload_ext_ct; i++) {
1885 get_guid(priv->fd, &g);
1886 priv->input_position += sizeof(lives_asf_guid);
1887
1888 if (read(priv->fd, buffer, 2) < 2) {
1889 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1890 detach_stream(cdata);
1891 return FALSE;
1892 }
1893
1894 priv->input_position += 2;
1895
1896 //ext_d=get_le16int(buffer);
1897
1898 if (read(priv->fd, buffer, 4) < 4) {
1899 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1900 detach_stream(cdata);
1901 return FALSE;
1902 }
1903
1904 priv->input_position += 4;
1905
1906 ext_len = get_le32int(buffer);
1907
1908 lseek(priv->fd, ext_len, SEEK_CUR);
1909 }
1910 // there could be a optional stream properties object to follow
1911 // if so the next iteration will pick it up
1912 } else if (!guidcmp(&g, &lives_asf_head1_guid)) {
1913 get_guid(priv->fd, &g);
1914 priv->input_position += sizeof(lives_asf_guid);
1915 lseek(priv->fd, 6, SEEK_CUR);
1916 priv->input_position += 6;
1917 } else if (!guidcmp(&g, &lives_asf_marker_header)) {
1918 int i, count, name_len;
1919 char name[1024];
1920
1921 #if 1
1922 fprintf(stderr, "asf_decoder: Chapter handling not yet implemented for %s\n", cdata->URI);
1923 detach_stream(cdata);
1924 return FALSE;
1925 #endif
1926
1927 lseek(priv->fd, 16, SEEK_CUR);
1928 priv->input_position += 16;
1929
1930 if (read(priv->fd, buffer, 4) < 4) {
1931 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1932 detach_stream(cdata);
1933 return FALSE;
1934 }
1935
1936 priv->input_position += 4;
1937
1938 cdata->nclips = count = get_le32int(buffer); // markers count
1939
1940 lseek(priv->fd, 2, SEEK_CUR);
1941 priv->input_position += 2;
1942
1943 if (read(priv->fd, buffer, 2) < 2) {
1944 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1945 detach_stream(cdata);
1946 return FALSE;
1947 }
1948
1949 priv->input_position += 2;
1950
1951 name_len = get_le16int(buffer); // name length
1952 lseek(priv->fd, name_len, SEEK_CUR);
1953 priv->input_position += name_len;
1954
1955 for (i = 0; i < count; i++) {
1956 // int64_t pres_time;
1957 int name_len;
1958
1959 lseek(priv->fd, 8, SEEK_CUR);
1960 priv->input_position += 8;
1961
1962 if (read(priv->fd, buffer, 8) < 8) {
1963 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1964 detach_stream(cdata);
1965 return FALSE;
1966 }
1967
1968 priv->input_position += 8;
1969
1970 //pres_time = get_le64int(buffer); // presentation time
1971
1972 lseek(priv->fd, 10, SEEK_CUR);
1973 priv->input_position += 10;
1974
1975 if (read(priv->fd, buffer, 4) < 4) {
1976 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1977 detach_stream(cdata);
1978 return FALSE;
1979 }
1980
1981 priv->input_position += 4;
1982
1983 name_len = get_le32int(buffer); // name length
1984
1985 if (read(priv->fd, buffer, name_len) < name_len) {
1986 fprintf(stderr, "asf_decoder: read error in %s\n", cdata->URI);
1987 detach_stream(cdata);
1988 return FALSE;
1989 }
1990
1991 get_str16_nolen(buffer, name_len * 2, name, sizeof(name));
1992 //ff_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );
1993 priv->input_position += name_len;
1994 }
1995 } else if (check_eof(cdata)) {
1996 fprintf(stderr, "asf_decoder: EOF in %s\n", cdata->URI);
1997 detach_stream(cdata);
1998 return FALSE;
1999 } else {
2000 if (!priv->s->keylen) {
2001 if (!guidcmp(&g, &lives_asf_content_encryption) ||
2002 !guidcmp(&g, &lives_asf_ext_content_encryption) ||
2003 !guidcmp(&g, &lives_asf_digital_signature)) {
2004 fprintf(stderr, "asf_decoder: encrypted/signed content in %s\n", cdata->URI);
2005 detach_stream(cdata);
2006 return FALSE;
2007 }
2008 }
2009 }
2010
2011 lseek(priv->fd, gpos + gsize, SEEK_SET);
2012 if (priv->input_position != gpos + gsize)
2013 #ifdef DEBUG
2014 fprintf(stderr, "gpos mismatch our pos=%"PRIu64", end=%"PRIu64"\n", priv->input_position - gpos, gsize);
2015 #endif
2016 priv->input_position = gpos + gsize;
2017 } // end for
2018
2019 if (vidindex == -1) {
2020 fprintf(stderr, "asf_decoder: no video stream found in %s\n", cdata->URI);
2021 detach_stream(cdata);
2022 return FALSE;
2023 }
2024
2025 get_guid(priv->fd, &g);
2026 priv->input_position += sizeof(lives_asf_guid);
2027
2028 lseek(priv->fd, 10, SEEK_CUR);
2029 priv->input_position += 10;
2030
2031 if (check_eof(cdata)) {
2032 fprintf(stderr, "asf_decoder: EOF in %s\n", cdata->URI);
2033 detach_stream(cdata);
2034 return FALSE;
2035 }
2036
2037 priv->data_start = priv->input_position;
2038 priv->asf->packet_size_left = 0;
2039
2040 for (i = 0; i < 128; i++) {
2041 int stream_num = priv->asf->asfid2avid[i];
2042 if (stream_num >= 0) {
2043 AVStream *st = priv->s->streams[stream_num];
2044 if (!st || !priv->st->codec) continue;
2045 if (!priv->st->codec->bit_rate)
2046 priv->st->codec->bit_rate = bitrate[i];
2047 if (dar[i].num > 0 && dar[i].den > 0)
2048 av_reduce(&priv->st->sample_aspect_ratio.num,
2049 &priv->st->sample_aspect_ratio.den,
2050 dar[i].num, dar[i].den, INT_MAX);
2051
2052 // copy and convert language codes to the frontend
2053 /* if (priv->asf->streams[i].stream_language_index < 128) {
2054 const char *rfc1766 = priv->asf->stream_languages[priv->asf->streams[i].stream_language_index];
2055 if (rfc1766 && strlen(rfc1766) > 1) {
2056 const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any
2057 const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL);
2058 if (iso6392)
2059 av_dict_set(&priv->stmetadata, "language", iso6392, 0);
2060 }
2061 }*/
2062 }
2063 }
2064
2065 priv->inited = TRUE;
2066
2067 priv->data_start = priv->input_position;
2068
2069 priv->start_dts = 0; // will reset this later
2070 priv->have_start_dts = FALSE; // cannot add keyframes until we know offset of start_dts
2071
2072 // re-scan with avcodec; priv->data_start holds video data start position
2073 priv->input_position = priv->data_start;
2074 lseek(priv->fd, priv->input_position, SEEK_SET);
2075
2076 priv->ctx = ctx = vidst->codec;
2077
2078 if (vidst->codec) codec = avcodec_find_decoder(vidst->codec->codec_id);
2079
2080 if (isclone) {
2081 retval = avcodec_open2(vidst->codec, codec, NULL);
2082 return TRUE;
2083 }
2084
2085 switch (vidst->codec->codec_id) {
2086 case AV_CODEC_ID_WMV1:
2087 snprintf(cdata->video_name, 16, "wmv1");
2088 break;
2089 case AV_CODEC_ID_WMV2:
2090 snprintf(cdata->video_name, 16, "wmv2");
2091 break;
2092 case AV_CODEC_ID_WMV3:
2093 snprintf(cdata->video_name, 16, "wmv3");
2094 break;
2095 case AV_CODEC_ID_DVVIDEO:
2096 snprintf(cdata->video_name, 16, "dv");
2097 break;
2098 case AV_CODEC_ID_MPEG4:
2099 snprintf(cdata->video_name, 16, "mpeg4");
2100 break;
2101 case AV_CODEC_ID_H264:
2102 snprintf(cdata->video_name, 16, "h264");
2103 break;
2104 case AV_CODEC_ID_MPEG1VIDEO:
2105 snprintf(cdata->video_name, 16, "mpeg1");
2106 break;
2107 case AV_CODEC_ID_MPEG2VIDEO:
2108 snprintf(cdata->video_name, 16, "mpeg2");
2109 break;
2110 default:
2111 snprintf(cdata->video_name, 16, "unknown");
2112 break;
2113 fprintf(stderr, "add video format %d\n", vidst->codec->codec_id);
2114 break;
2115 }
2116
2117 #ifdef DEBUG
2118 fprintf(stderr, "video type is %s %d x %d (%d x %d +%d +%d)\n", cdata->video_name,
2119 cdata->width, cdata->height, cdata->frame_width, cdata->frame_height, cdata->offs_x, cdata->offs_y);
2120 #endif
2121
2122 if (!vidst->codec) {
2123 if (strlen(cdata->video_name) > 0)
2124 fprintf(stderr, "asf_decoder: Could not find avcodec codec for video type %s\n", cdata->video_name);
2125 detach_stream(cdata);
2126 return FALSE;
2127 }
2128
2129 if ((retval = avcodec_open2(vidst->codec, codec, NULL)) < 0) {
2130 fprintf(stderr, "asf_decoder: Could not open avcodec context (%d) %d\n", retval, vidst->codec->frame_number);
2131 detach_stream(cdata);
2132 return FALSE;
2133 }
2134
2135 priv->input_position = priv->data_start;
2136 asf_reset_header(priv->s);
2137
2138 pthread_mutex_lock(&priv->idxc->mutex);
2139 priv->kframe = add_keyframe(cdata, priv->data_start, 0, 0);
2140 pthread_mutex_unlock(&priv->idxc->mutex);
2141 priv->def_packet_size = priv->asf->hdr.max_pktsize * 10;
2142
2143 priv->picture = av_frame_alloc();
2144
2145 do {
2146 if (priv->avpkt.data != NULL) free(priv->avpkt.data);
2147 retval = get_next_video_packet(cdata, 0, -1);
2148 if (retval == -2) {
2149 fprintf(stderr, "asf_decoder: No frames found.\n");
2150 detach_stream(cdata);
2151 return FALSE; // eof
2152 }
2153 } while (retval < 0);
2154
2155 if (priv->asf->packet_time_delta != 0) {
2156 fprintf(stderr, "asf_decoder: packet time delta of (%d) not understood\n", priv->asf->packet_time_delta);
2157 detach_stream(cdata);
2158 return FALSE;
2159 }
2160
2161 #if LIBAVCODEC_VERSION_MAJOR >= 52
2162 len = avcodec_decode_video2(vidst->codec, priv->picture, &got_picture, &priv->avpkt);
2163 #else
2164 len = avcodec_decode_video(vidst->codec, priv->picture, &got_picture, priv->avpkt.data, priv->avpkt.size);
2165 #endif
2166 priv->avpkt.size -= len;
2167
2168 if (!got_picture) {
2169 fprintf(stderr, "asf_decoder: Did not get picture.\n");
2170 detach_stream(cdata);
2171 return FALSE;
2172 }
2173
2174 if (priv->avpkt.size != 0) {
2175 fprintf(stderr, "asf_decoder: Multi frame packets, not decoding.\n");
2176 detach_stream(cdata);
2177 return FALSE;
2178 }
2179
2180 pts = priv->start_dts = priv->frame_dts;
2181 priv->have_start_dts = TRUE;
2182 cdata->video_start_time = (double)pts / 10000.;
2183
2184 cdata->sync_hint = 0;
2185 //#define DEBUG
2186 #ifdef DEBUG
2187 printf("first pts is %ld\n", pts);
2188 #endif
2189
2190 if (pts == AV_NOPTS_VALUE) {
2191 fprintf(stderr, "asf_decoder: No timestamps for frames, not decoding.\n");
2192 detach_stream(cdata);
2193 return FALSE;
2194 }
2195
2196 do {
2197 free(priv->avpkt.data);
2198 retval = get_next_video_packet(cdata, -1, -1);
2199
2200 // try to get dts of second frame
2201 if (retval != -2) { // eof
2202 if (retval == 0) {
2203
2204 if (priv->frame_dts == AV_NOPTS_VALUE) {
2205 fprintf(stderr, "asf_decoder: No timestamp for second frame, aborting.\n");
2206 detach_stream(cdata);
2207 return FALSE;
2208 }
2209
2210 if (priv->asf->packet_time_delta != 0) {
2211 fprintf(stderr, "asf_decoder: packet time delta of (%d) not understood\n", priv->asf->packet_time_delta);
2212 detach_stream(cdata);
2213 return FALSE;
2214 }
2215
2216 pts = priv->frame_dts - pts;
2217 pts2 = priv->frame_dts;
2218
2219 #ifdef DEBUG
2220 printf("delta pts is %ld %ld\n", pts, priv->frame_dts);
2221 #endif
2222
2223 if (pts > 0) cdata->fps = 1000. / (double)pts;
2224 gotframe2 = TRUE;
2225 }
2226 }
2227 } while (retval < 0 && retval != -2);
2228
2229 if (gotframe2) {
2230 do {
2231 free(priv->avpkt.data);
2232 retval = get_next_video_packet(cdata, -1, -1);
2233
2234 // try to get dts of second frame
2235 if (retval != -2) { // eof
2236 if (retval == 0) {
2237
2238 if (priv->frame_dts == AV_NOPTS_VALUE) {
2239 break;
2240 }
2241
2242 if (priv->asf->packet_time_delta != 0) {
2243 fprintf(stderr, "asf_decoder: packet time delta of (%d) not understood\n", priv->asf->packet_time_delta);
2244 detach_stream(cdata);
2245 return FALSE;
2246 }
2247
2248 if (priv->frame_dts - pts2 != pts) {
2249 // 2->3 delta can be more accurate than 1 - 2 delta
2250 pts = priv->frame_dts - pts2;
2251 if (pts > 0) cdata->fps = 1000. / (double)pts;
2252 priv->start_dts = pts2 - pts;
2253 priv->have_start_dts = TRUE;
2254 cdata->video_start_time = (double)priv->start_dts / 10000.;
2255 }
2256
2257 #ifdef DEBUG
2258 printf("3delta pts is %ld %ld\n", pts, priv->frame_dts);
2259 #endif
2260
2261 }
2262 }
2263 } while (retval < 0 && retval != -2);
2264 }
2265
2266 free(priv->avpkt.data);
2267 priv->avpkt.data = NULL;
2268 priv->avpkt.size = 0;
2269
2270 priv->ctx = ctx = vidst->codec;
2271
2272 cdata->YUV_clamping = WEED_YUV_CLAMPING_UNCLAMPED;
2273 if (ctx->color_range == AVCOL_RANGE_MPEG) cdata->YUV_clamping = WEED_YUV_CLAMPING_CLAMPED;
2274
2275 cdata->YUV_sampling = WEED_YUV_SAMPLING_DEFAULT;
2276 if (ctx->chroma_sample_location != AVCHROMA_LOC_LEFT) cdata->YUV_sampling = WEED_YUV_SAMPLING_MPEG;
2277
2278 cdata->YUV_subspace = WEED_YUV_SUBSPACE_YCBCR;
2279 if (ctx->colorspace == AVCOL_SPC_BT709) cdata->YUV_subspace = WEED_YUV_SUBSPACE_BT709;
2280
2281 cdata->palettes[0] = avi_pix_fmt_to_weed_palette(ctx->pix_fmt,
2282 &cdata->YUV_clamping);
2283
2284 if (cdata->palettes[0] == WEED_PALETTE_END) {
2285 fprintf(stderr, "asf_decoder: Could not find a usable palette for (%d) %s\n", ctx->pix_fmt, cdata->URI);
2286 detach_stream(cdata);
2287 return FALSE;
2288 }
2289
2290 cdata->current_palette = cdata->palettes[0];
2291
2292 // re-get fps, width, height, nframes - actually avcodec is pretty useless at getting this
2293 // so we fall back on the values we obtained ourselves
2294
2295 if (cdata->width == 0) cdata->width = ctx->width - cdata->offs_x * 2;
2296 if (cdata->height == 0) cdata->height = ctx->height - cdata->offs_y * 2;
2297
2298 if (cdata->width * cdata->height == 0) {
2299 fprintf(stderr, "asf_decoder: invalid width and height (%d X %d)\n", cdata->width, cdata->height);
2300 detach_stream(cdata);
2301 return FALSE;
2302 }
2303
2304 #ifdef DEBUG
2305 fprintf(stderr, "using palette %d, size %d x %d\n",
2306 cdata->current_palette, cdata->width, cdata->height);
2307 #endif
2308
2309 cdata->par = (double)ctx->sample_aspect_ratio.num / (double)ctx->sample_aspect_ratio.den;
2310 if (cdata->par == 0.) cdata->par = 1.;
2311
2312 if (ctx->time_base.den > 0 && ctx->time_base.num > 0) {
2313 fps = (double)ctx->time_base.den / (double)ctx->time_base.num;
2314 if (fps != 1000.) cdata->fps = fps;
2315 }
2316
2317 if (cdata->fps == 0. || cdata->fps == 1000.) {
2318 double res = get_fps(cdata->URI);
2319 if (res >= 0.) cdata->fps = res;
2320 }
2321
2322 if (cdata->fps == 0. && ctx->time_base.num == 0) {
2323 if (ctx->time_base.den == 1) cdata->fps = 25.;
2324 }
2325
2326 if (cdata->fps == 0. || cdata->fps == 1000.) {
2327 fprintf(stderr, "asf_decoder: invalid framerate %.4f (%d / %d)\n", cdata->fps, ctx->time_base.den, ctx->time_base.num);
2328 detach_stream(cdata);
2329 return FALSE;
2330 }
2331
2332 if (ctx->ticks_per_frame == 2) {
2333 // TODO - needs checking
2334 cdata->fps /= 2.;
2335 cdata->interlace = LIVES_INTERLACE_BOTTOM_FIRST;
2336 }
2337
2338 priv->last_frame = -1;
2339 priv->black_fill = FALSE;
2340
2341 if (is_partial_clone) return TRUE;
2342
2343 vidst->duration = get_last_video_dts(cdata);
2344
2345 cdata->nframes = dts_to_frame(cdata, vidst->duration + priv->start_dts) + 2;
2346
2347 // double check, sometimes we can be out by one or two frames
2348 while (1) {
2349 if (get_frame(cdata, cdata->nframes - 1, NULL, 0, NULL)) break;
2350 cdata->nframes--;
2351 }
2352
2353 if (cdata->width != cdata->frame_width || cdata->height != cdata->frame_height)
2354 fprintf(stderr, "asf_decoder: info frame size=%d x %d, pixel size=%d x %d\n", cdata->frame_width, cdata->frame_height,
2355 cdata->width,
2356 cdata->height);
2357
2358
2359 return TRUE;
2360 }
2361
2362
2363 //////////////////////////////////////////
2364 // std functions
2365
module_check_init(void)2366 const char *module_check_init(void) {
2367 avcodec_register_all();
2368 indices = NULL;
2369 nidxc = 0;
2370
2371 pthread_mutexattr_init(&mattr);
2372 pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
2373
2374 pthread_mutex_init(&indices_mutex, NULL);
2375 return NULL;
2376 }
2377
2378
version(void)2379 const char *version(void) {
2380 return plugin_version;
2381 }
2382
2383
init_cdata(lives_clip_data_t * data)2384 static lives_clip_data_t *init_cdata(lives_clip_data_t *data) {
2385 lives_clip_data_t *cdata;
2386
2387 if (!data) {
2388 cdata = cdata_new(NULL);
2389 cdata_stamp(cdata, plname, vmaj, vmin);
2390 cdata->palettes = (int *)malloc(2 * sizeof(int));
2391 cdata->palettes[1] = WEED_PALETTE_END;
2392 } else cdata = data;
2393
2394 cdata->priv = calloc(1, sizeof(lives_asf_priv_t));
2395
2396 return cdata;
2397 }
2398
2399
asf_clone(lives_clip_data_t * cdata)2400 static lives_clip_data_t *asf_clone(lives_clip_data_t *cdata) {
2401 lives_clip_data_t *clone = clone_cdata(cdata);
2402 //lives_clip_data_t *clone = init_cdata();
2403 lives_asf_priv_t *dpriv, *spriv;
2404
2405 cdata_stamp(clone, plname, vmaj, vmin);
2406
2407 // copy from cdata to clone, with a new context for clone
2408 spriv = cdata->priv;
2409
2410 if (spriv != NULL) {
2411 clone->priv = dpriv = (lives_asf_priv_t *)calloc(1, sizeof(lives_asf_priv_t));
2412 dpriv->filesize = spriv->filesize;
2413 dpriv->inited = TRUE;
2414 } else {
2415 clone = init_cdata(clone);
2416 dpriv = clone->priv;
2417 }
2418
2419 if (!clone->palettes) {
2420 clone->palettes = malloc(2 * sizeof(int));
2421 clone->palettes[1] = WEED_PALETTE_END;
2422 }
2423
2424 if (!attach_stream(clone, TRUE)) {
2425 clip_data_free(clone);
2426 return NULL;
2427 }
2428
2429 asf_reset_header(dpriv->s);
2430
2431 if (spriv != NULL) {
2432 dpriv->def_packet_size = spriv->def_packet_size;
2433 dpriv->start_dts = spriv->start_dts;
2434 dpriv->have_start_dts = TRUE;
2435 dpriv->st->duration = spriv->st->duration;
2436
2437 dpriv->last_frame = -1;
2438 dpriv->black_fill = FALSE;
2439 } else {
2440 clone->nclips = 1;
2441
2442 ///////////////////////////////////////////////////////////
2443
2444 sprintf(clone->container_name, "%s", "asf");
2445
2446 // clone->height was set when we attached the stream
2447
2448 clone->interlace = LIVES_INTERLACE_NONE;
2449
2450 clone->frame_width = clone->width + clone->offs_x * 2;
2451 clone->frame_height = clone->height + clone->offs_y * 2;
2452
2453 if (dpriv->ctx->width == clone->frame_width) clone->offs_x = 0;
2454 if (dpriv->ctx->height == clone->frame_height) clone->offs_y = 0;
2455
2456 ////////////////////////////////////////////////////////////////////
2457
2458 clone->asigned = TRUE;
2459 clone->ainterleaf = TRUE;
2460 }
2461
2462 if (dpriv->picture != NULL) av_frame_unref(dpriv->picture);
2463 dpriv->picture = NULL;
2464
2465 return clone;
2466 }
2467
2468
get_clip_data(const char * URI,lives_clip_data_t * cdata)2469 lives_clip_data_t *get_clip_data(const char *URI, lives_clip_data_t *cdata) {
2470 // the first time this is called, caller should pass NULL as the cdata
2471 // subsequent calls to this should re-use the same cdata
2472
2473 // if the host wants a different current_clip, this must be called again with the same
2474 // cdata as the second parameter
2475
2476 // value returned should be freed with clip_data_free() when no longer required
2477
2478 // should be thread-safe
2479
2480 lives_asf_priv_t *priv;
2481
2482 if (!URI && cdata) {
2483 // create a clone of cdata - we also need to be able to handle a "fake" clone with only URI, nframes and fps set (priv == NULL)
2484 return asf_clone(cdata);
2485 }
2486
2487 if (cdata != NULL && cdata->current_clip > 0) {
2488 // currently we only support one clip per container
2489 clip_data_free(cdata);
2490 return NULL;
2491 }
2492
2493 if (!cdata) {
2494 cdata = init_cdata(NULL);
2495 }
2496
2497 if (cdata->URI == NULL || strcmp(URI, cdata->URI)) {
2498 if (cdata->URI != NULL) {
2499 detach_stream(cdata);
2500 free(cdata->URI);
2501 }
2502 cdata->URI = strdup(URI);
2503 if (!attach_stream(cdata, FALSE)) {
2504 clip_data_free(cdata);
2505 return NULL;
2506 }
2507 //cdata->current_palette=cdata->palettes[0];
2508 cdata->current_clip = 0;
2509 }
2510
2511 cdata->nclips = 1;
2512
2513 ///////////////////////////////////////////////////////////
2514
2515 sprintf(cdata->container_name, "%s", "asf");
2516
2517 // cdata->height was set when we attached the stream
2518
2519 cdata->interlace = LIVES_INTERLACE_NONE;
2520
2521 cdata->frame_width = cdata->width + cdata->offs_x * 2;
2522 cdata->frame_height = cdata->height + cdata->offs_y * 2;
2523
2524 priv = cdata->priv;
2525
2526 if (priv->ctx->width == cdata->frame_width) cdata->offs_x = 0;
2527 if (priv->ctx->height == cdata->frame_height) cdata->offs_y = 0;
2528
2529 ////////////////////////////////////////////////////////////////////
2530
2531 cdata->asigned = TRUE;
2532 cdata->ainterleaf = TRUE;
2533
2534 if (priv->picture != NULL) av_frame_unref(priv->picture);
2535 priv->picture = NULL;
2536
2537 return cdata;
2538 }
2539
2540
write_black_pixel(unsigned char * idst,int pal,int npixels,int y_black)2541 static size_t write_black_pixel(unsigned char *idst, int pal, int npixels, int y_black) {
2542 unsigned char *dst = idst;
2543 register int i;
2544
2545 for (i = 0; i < npixels; i++) {
2546 switch (pal) {
2547 case WEED_PALETTE_RGBA32:
2548 case WEED_PALETTE_BGRA32:
2549 dst[0] = dst[1] = dst[2] = 0;
2550 dst[3] = 255;
2551 dst += 4;
2552 break;
2553 case WEED_PALETTE_ARGB32:
2554 dst[1] = dst[2] = dst[3] = 0;
2555 dst[0] = 255;
2556 dst += 4;
2557 break;
2558 case WEED_PALETTE_UYVY8888:
2559 dst[1] = dst[3] = y_black;
2560 dst[0] = dst[2] = 128;
2561 dst += 4;
2562 break;
2563 case WEED_PALETTE_YUYV8888:
2564 dst[0] = dst[2] = y_black;
2565 dst[1] = dst[3] = 128;
2566 dst += 4;
2567 break;
2568 case WEED_PALETTE_YUV888:
2569 dst[0] = y_black;
2570 dst[1] = dst[2] = 128;
2571 dst += 3;
2572 break;
2573 case WEED_PALETTE_YUVA8888:
2574 dst[0] = y_black;
2575 dst[1] = dst[2] = 128;
2576 dst[3] = 255;
2577 dst += 4;
2578 break;
2579 case WEED_PALETTE_YUV411:
2580 dst[0] = dst[3] = 128;
2581 dst[1] = dst[2] = dst[4] = dst[5] = y_black;
2582 dst += 6;
2583 default:
2584 break;
2585 }
2586 }
2587 return idst - dst;
2588 }
2589
2590
chill_out(const lives_clip_data_t * cdata)2591 boolean chill_out(const lives_clip_data_t *cdata) {
2592 // free buffers because we are going to chill out for a while
2593 // (seriously, host can call this to free any buffers when we arent palying sequentially)
2594 if (cdata != NULL) {
2595 lives_asf_priv_t *priv = cdata->priv;
2596 if (priv != NULL) {
2597 if (priv->picture != NULL) av_frame_unref(priv->picture);
2598 priv->picture = NULL;
2599 if (priv->ctx != NULL) avcodec_flush_buffers(priv->ctx);
2600 }
2601 }
2602 return TRUE;
2603 }
2604
2605
get_frame(const lives_clip_data_t * cdata,int64_t tframe,int * rowstrides,int height,void ** pixel_data)2606 boolean get_frame(const lives_clip_data_t *cdata, int64_t tframe, int *rowstrides, int height, void **pixel_data) {
2607 // seek to frame,
2608
2609 lives_asf_priv_t *priv = cdata->priv;
2610
2611 int64_t nextframe = 0;
2612 int64_t target_pts = frame_to_dts(cdata, tframe);
2613
2614 unsigned char *dst, *src;
2615 unsigned char black[4] = {0, 0, 0, 255};
2616
2617 boolean got_picture = FALSE;
2618 boolean hit_target = FALSE;
2619
2620 int tfrag = 0;
2621 int xheight = cdata->frame_height, pal = cdata->current_palette, nplanes = 1, dstwidth = cdata->width, psize = 1;
2622 int btop = cdata->offs_y, bbot = xheight - 1 - btop;
2623 int bleft = cdata->offs_x, bright = cdata->frame_width - cdata->width - bleft;
2624 int rescan_limit = 16; // pick some arbitrary value
2625 int y_black = (cdata->YUV_clamping == WEED_YUV_CLAMPING_CLAMPED) ? 16 : 0;
2626
2627 register int i, p;
2628
2629 #ifdef DEBUG_KFRAMES
2630 fprintf(stderr, "vals %ld %ld\n", tframe, priv->last_frame);
2631 #endif
2632
2633 if (pixel_data != NULL) {
2634
2635 // calc frame width and height, including any border
2636
2637 if (pal == WEED_PALETTE_YUV420P || pal == WEED_PALETTE_YVU420P || pal == WEED_PALETTE_YUV422P || pal == WEED_PALETTE_YUV444P) {
2638 nplanes = 3;
2639 black[0] = y_black;
2640 black[1] = black[2] = 128;
2641 } else if (pal == WEED_PALETTE_YUVA4444P) {
2642 nplanes = 4;
2643 black[0] = y_black;
2644 black[1] = black[2] = 128;
2645 black[3] = 255;
2646 }
2647
2648 if (pal == WEED_PALETTE_RGB24 || pal == WEED_PALETTE_BGR24) psize = 3;
2649
2650 if (pal == WEED_PALETTE_RGBA32 || pal == WEED_PALETTE_BGRA32 || pal == WEED_PALETTE_ARGB32 || pal == WEED_PALETTE_UYVY8888 ||
2651 pal == WEED_PALETTE_YUYV8888 || pal == WEED_PALETTE_YUV888 || pal == WEED_PALETTE_YUVA8888) psize = 4;
2652
2653 if (pal == WEED_PALETTE_YUV411) psize = 6;
2654
2655 if (pal == WEED_PALETTE_A1) dstwidth >>= 3;
2656
2657 dstwidth *= psize;
2658
2659 if (cdata->frame_height > cdata->height && height == cdata->height) {
2660 // host ignores vertical border
2661 btop = 0;
2662 xheight = cdata->height;
2663 bbot = xheight - 1;
2664 }
2665
2666 if (cdata->frame_width > cdata->width && rowstrides[0] < cdata->frame_width * psize) {
2667 // host ignores horizontal border
2668 bleft = bright = 0;
2669 }
2670 }
2671
2672 ////////////////////////////////////////////////////////////////////
2673
2674 if (tframe != priv->last_frame) {
2675
2676 if (priv->picture != NULL) av_frame_unref(priv->picture);
2677 priv->picture = NULL;
2678
2679 if (priv->last_frame == -1 || (tframe < priv->last_frame) || (tframe - priv->last_frame > rescan_limit)) {
2680
2681 if (priv->avpkt.data != NULL) free(priv->avpkt.data);
2682 priv->avpkt.data = NULL;
2683 priv->avpkt.size = 0;
2684
2685 pthread_mutex_lock(&priv->idxc->mutex);
2686 if ((priv->kframe = get_idx_for_pts(cdata, target_pts - priv->start_dts)) != NULL) {
2687 priv->input_position = priv->kframe->offs;
2688 nextframe = dts_to_frame(cdata, priv->kframe->dts + priv->start_dts);
2689 tfrag = priv->kframe->frag;
2690 } else priv->input_position = priv->data_start;
2691 pthread_mutex_unlock(&priv->idxc->mutex);
2692
2693 // we are now at the kframe before or at target - parse packets until we hit target
2694
2695 //#define DEBUG_KFRAMES
2696 #ifdef DEBUG_KFRAMES
2697 if (priv->kframe != NULL) printf("got kframe %ld frag %d for frame %ld\n",
2698 dts_to_frame(cdata, priv->kframe->dts + priv->start_dts), priv->kframe->frag, tframe);
2699 #endif
2700
2701 avcodec_flush_buffers(priv->ctx);
2702 asf_reset_header(priv->s);
2703 priv->black_fill = FALSE;
2704 } else {
2705 nextframe = priv->last_frame + 1;
2706 tfrag = -1;
2707 }
2708
2709 //priv->ctx->skip_frame=AVDISCARD_NONREF;
2710
2711 priv->last_frame = tframe;
2712
2713 // do this until we reach target frame //////////////
2714
2715 while (1) {
2716 int ret;
2717
2718 if (priv->avpkt.size == 0) {
2719 ret = get_next_video_packet(cdata, tfrag, -1);
2720 if (ret < 0) {
2721 free(priv->avpkt.data);
2722 priv->avpkt.data = NULL;
2723 priv->avpkt.size = 0;
2724 if (ret == -2) {
2725 // EOF
2726 if (pixel_data == NULL) return FALSE;
2727 priv->black_fill = TRUE;
2728 break;
2729 }
2730 fprintf(stderr, "asf_decoder: got frame decode error %d at frame %ld\n", ret, nextframe + 1);
2731 continue;
2732 }
2733 }
2734
2735 // decode any frames from this packet
2736 if (priv->picture == NULL) priv->picture = av_frame_alloc();
2737
2738 #if LIBAVCODEC_VERSION_MAJOR >= 52
2739 avcodec_decode_video2(priv->ctx, priv->picture, &got_picture, &priv->avpkt);
2740 #else
2741 avcodec_decode_video(priv->ctx, priv->picture, &got_picture, priv->avpkt.data, priv->avpkt.size);
2742 #endif
2743
2744 free(priv->avpkt.data);
2745 priv->avpkt.data = NULL;
2746 priv->avpkt.size = 0;
2747
2748 if (nextframe == tframe) hit_target = TRUE;
2749
2750 if (hit_target && got_picture) break;
2751
2752 // otherwise discard this frame
2753 if (got_picture) {
2754 av_frame_unref(priv->picture);
2755 priv->picture = NULL;
2756 tfrag = -1;
2757 nextframe++;
2758 }
2759 }
2760 }
2761
2762 if (priv->picture == NULL || pixel_data == NULL) return TRUE;
2763
2764 if (priv->black_fill) btop = cdata->frame_height;
2765
2766 for (p = 0; p < nplanes; p++) {
2767 dst = pixel_data[p];
2768 src = priv->picture->data[p];
2769
2770 for (i = 0; i < xheight; i++) {
2771 if (i < btop || i > bbot) {
2772 // top or bottom border, copy black row
2773 if (pal == WEED_PALETTE_YUV420P || pal == WEED_PALETTE_YVU420P || pal == WEED_PALETTE_YUV422P || pal == WEED_PALETTE_YUV444P ||
2774 pal == WEED_PALETTE_YUVA4444P || pal == WEED_PALETTE_RGB24 || pal == WEED_PALETTE_BGR24) {
2775 memset(dst, black[p], dstwidth + (bleft + bright)*psize);
2776 dst += dstwidth + (bleft + bright) * psize;
2777 } else dst += write_black_pixel(dst, pal, dstwidth / psize + bleft + bright, y_black);
2778 continue;
2779 }
2780
2781 if (bleft > 0) {
2782 if (pal == WEED_PALETTE_YUV420P || pal == WEED_PALETTE_YVU420P || pal == WEED_PALETTE_YUV422P || pal == WEED_PALETTE_YUV444P ||
2783 pal == WEED_PALETTE_YUVA4444P || pal == WEED_PALETTE_RGB24 || pal == WEED_PALETTE_BGR24) {
2784 memset(dst, black[p], bleft * psize);
2785 dst += bleft * psize;
2786 } else dst += write_black_pixel(dst, pal, bleft, y_black);
2787 }
2788
2789 memcpy(dst, src, dstwidth);
2790 dst += dstwidth;
2791
2792 if (bright > 0) {
2793 if (pal == WEED_PALETTE_YUV420P || pal == WEED_PALETTE_YVU420P || pal == WEED_PALETTE_YUV422P || pal == WEED_PALETTE_YUV444P ||
2794 pal == WEED_PALETTE_YUVA4444P || pal == WEED_PALETTE_RGB24 || pal == WEED_PALETTE_BGR24) {
2795 memset(dst, black[p], bright * psize);
2796 dst += bright * psize;
2797 } else dst += write_black_pixel(dst, pal, bright, y_black);
2798 }
2799
2800 src += priv->picture->linesize[p];
2801 }
2802 if (p == 0 && (pal == WEED_PALETTE_YUV420P || pal == WEED_PALETTE_YVU420P || pal == WEED_PALETTE_YUV422P)) {
2803 dstwidth >>= 1;
2804 bleft >>= 1;
2805 bright >>= 1;
2806 }
2807 if (p == 0 && (pal == WEED_PALETTE_YUV420P || pal == WEED_PALETTE_YVU420P)) {
2808 xheight >>= 1;
2809 btop >>= 1;
2810 bbot >>= 1;
2811 }
2812 }
2813
2814 return TRUE;
2815 }
2816
2817
clip_data_free(lives_clip_data_t * cdata)2818 void clip_data_free(lives_clip_data_t *cdata) {
2819 lives_asf_priv_t *priv = cdata->priv;
2820 if (priv->idxc != NULL)
2821 idxc_release(cdata);
2822
2823 priv->idxc = NULL;
2824
2825 if (cdata->URI != NULL) {
2826 detach_stream(cdata);
2827 }
2828 lives_struct_free(&cdata->lsd);
2829 }
2830
2831
module_unload(void)2832 void module_unload(void) {
2833 idxc_release_all();
2834 }
2835
2836