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