1 | diff --git a/ext/faad/gstfaad.c b/ext/faad/gstfaad.c |
---|
2 | index b9de36d..bb49da1 100644 |
---|
3 | --- a/ext/faad/gstfaad.c |
---|
4 | +++ b/ext/faad/gstfaad.c |
---|
5 | @@ -210,6 +210,7 @@ gst_faad_init (GstFaad * faad) |
---|
6 | faad->handle = NULL; |
---|
7 | faad->samplerate = -1; |
---|
8 | faad->channels = -1; |
---|
9 | + faad->fr_channels = 0; |
---|
10 | faad->tempbuf = NULL; |
---|
11 | faad->need_channel_setup = TRUE; |
---|
12 | faad->channel_positions = NULL; |
---|
13 | @@ -1115,6 +1116,8 @@ gst_faad_update_caps (GstFaad * faad, faacDecFrameInfo * info) |
---|
14 | gboolean channel_map_failed; |
---|
15 | GstCaps *caps; |
---|
16 | |
---|
17 | + GST_DEBUG_OBJECT (faad, "update_caps. ch:%d->%d sr:%d->%d", |
---|
18 | + faad->channels, info->channels, faad->samplerate, info->samplerate); |
---|
19 | /* store new negotiation information */ |
---|
20 | faad->samplerate = info->samplerate; |
---|
21 | faad->channels = info->channels; |
---|
22 | @@ -1193,6 +1196,9 @@ gst_faad_sync (GstBuffer * buf, guint * off) |
---|
23 | *off = n; |
---|
24 | len = ((data[n + 3] & 0x03) << 11) | |
---|
25 | (data[n + 4] << 3) | ((data[n + 5] & 0xe0) >> 5); |
---|
26 | + // rescue un-labled framed input |
---|
27 | + if (!n && n + len + 2 == size) |
---|
28 | + return TRUE; |
---|
29 | if (n + len + 2 >= size) { |
---|
30 | GST_DEBUG ("Next frame is not within reach"); |
---|
31 | return FALSE; |
---|
32 | @@ -1342,7 +1348,7 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer) |
---|
33 | run_loop = (input_size >= FAAD_MIN_STREAMSIZE); |
---|
34 | } |
---|
35 | |
---|
36 | - while ((input_size > 0) && run_loop) { |
---|
37 | + while ((input_size > FAAD_MIN_STREAMSIZE) && run_loop) { |
---|
38 | |
---|
39 | if (faad->packetised) { |
---|
40 | /* Only one packet per buffer, no matter how much is really consumed */ |
---|
41 | @@ -1353,6 +1359,53 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer) |
---|
42 | } |
---|
43 | } |
---|
44 | |
---|
45 | + /* sync */ |
---|
46 | + while (input_size > FAAD_MIN_STREAMSIZE) { |
---|
47 | + if (looks_like_valid_header (input_data, input_size)) |
---|
48 | + break; |
---|
49 | + input_data++; |
---|
50 | + input_size--; |
---|
51 | + } |
---|
52 | + if (input_size <= FAAD_MIN_STREAMSIZE) { |
---|
53 | + GST_DEBUG_OBJECT (faad, "found some garbage data."); |
---|
54 | + goto next; |
---|
55 | + } |
---|
56 | + |
---|
57 | + if ((GST_READ_UINT16_BE (input_data) & 0xFFF6) == 0xFFF0) { |
---|
58 | + guint fr_ch; |
---|
59 | + static const guint32 sample_rate[] = { |
---|
60 | + 96000, 88200, 64000, 48000, 44100, 32000, |
---|
61 | + 24000, 22050, 16000, 12000, 11025, 8000, 0, 0, 0, 0 |
---|
62 | + }; |
---|
63 | +#if FAAD2_MINOR_VERSION >= 7 |
---|
64 | + unsigned long rate; |
---|
65 | +#else |
---|
66 | + guint32 rate; |
---|
67 | +#endif |
---|
68 | + guint8 ch; |
---|
69 | + /* guint profile; */ |
---|
70 | + |
---|
71 | + fr_ch = (input_data[2] & 0x01) << 2 | (input_data[3] >> 6); |
---|
72 | + rate = sample_rate[(input_data[2] & 0x3C) >> 2]; |
---|
73 | + /* profile = (input_data[2] & 0xC0) >> 6; */ |
---|
74 | + |
---|
75 | + if (faad->fr_channels != fr_ch || faad->samplerate != rate) { |
---|
76 | + GST_INFO_OBJECT (faad, "Changing configuration. rate=%u,channels=%u", |
---|
77 | + rate, fr_ch); |
---|
78 | + faacDecClose (faad->handle); |
---|
79 | + faad->init = FALSE; |
---|
80 | + if (!gst_faad_open_decoder (faad) || |
---|
81 | + faacDecInit (faad->handle, input_data, input_size, &rate, &ch) < 0) |
---|
82 | + goto out; |
---|
83 | + |
---|
84 | + faad->init = TRUE; |
---|
85 | + faad->fr_channels = fr_ch; |
---|
86 | + faad->samplerate = rate; |
---|
87 | + /* make sure we create new caps below */ |
---|
88 | + faad->channels = 0; |
---|
89 | + } |
---|
90 | + } |
---|
91 | + |
---|
92 | out = faacDecDecode (faad->handle, &info, input_data + skip_bytes, |
---|
93 | input_size - skip_bytes); |
---|
94 | |
---|
95 | @@ -1552,6 +1605,7 @@ gst_faad_change_state (GstElement * element, GstStateChange transition) |
---|
96 | case GST_STATE_CHANGE_PAUSED_TO_READY: |
---|
97 | faad->samplerate = -1; |
---|
98 | faad->channels = -1; |
---|
99 | + faad->fr_channels = 0; |
---|
100 | faad->need_channel_setup = TRUE; |
---|
101 | faad->init = FALSE; |
---|
102 | g_free (faad->channel_positions); |
---|
103 | diff --git a/ext/faad/gstfaad.h b/ext/faad/gstfaad.h |
---|
104 | index fd989b6..424ddf8 100644 |
---|
105 | --- a/ext/faad/gstfaad.h |
---|
106 | +++ b/ext/faad/gstfaad.h |
---|
107 | @@ -48,6 +48,7 @@ typedef struct _GstFaad { |
---|
108 | |
---|
109 | guint samplerate; /* sample rate of the last MPEG frame */ |
---|
110 | guint channels; /* number of channels of the last frame */ |
---|
111 | + guint fr_channels;/* number of input channels of the last frame */ |
---|
112 | guint bps; /* bytes per sample */ |
---|
113 | |
---|
114 | guint8 fake_codec_data[2]; |
---|
115 | |
---|