(newConcurrency bool)
| 215 | } |
| 216 | |
| 217 | func (d *downloader) sendChunkTask(newConcurrency bool) (err error) { |
| 218 | d.mu.Lock() |
| 219 | defer d.mu.Unlock() |
| 220 | if d.pos >= d.maxPos { |
| 221 | return nil |
| 222 | } |
| 223 | if newConcurrency { |
| 224 | if d.concurrency <= 0 { |
| 225 | return nil |
| 226 | } |
| 227 | if d.nextChunk > 0 { // 第一个不检查,因为已经检查过了 |
| 228 | if err := d.cfg.ConcurrencyLimit.Acquire(); err != nil { |
| 229 | return err |
| 230 | } |
| 231 | defer func() { |
| 232 | if err != nil { |
| 233 | d.cfg.ConcurrencyLimit.Release() |
| 234 | } |
| 235 | }() |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | br := d.bufMap[d.nextChunk] |
| 240 | if br == nil { |
| 241 | var b buffer.Block |
| 242 | b, err = d.hc.NextBlock() |
| 243 | if err != nil { |
| 244 | return err |
| 245 | } |
| 246 | br = buffer.NewPipeBuffer(d.ctx, b) |
| 247 | d.bufMap[d.nextChunk] = br |
| 248 | } |
| 249 | |
| 250 | finalSize := int64(d.cfg.PartSize) |
| 251 | switch d.nextChunk { |
| 252 | case 0: |
| 253 | // 最小分片在前面有助视频播放? |
| 254 | firstSize := d.params.Range.Length % finalSize |
| 255 | if firstSize > 0 { |
| 256 | minSize := finalSize / 2 |
| 257 | // 最小分片太小就调整到一半 |
| 258 | finalSize = max(firstSize, minSize) |
| 259 | } |
| 260 | case 1: |
| 261 | firstSize := d.params.Range.Length % finalSize |
| 262 | minSize := finalSize / 2 |
| 263 | if firstSize > 0 && firstSize < minSize { |
| 264 | finalSize += firstSize - minSize |
| 265 | } |
| 266 | } |
| 267 | err = br.Reset(int(finalSize)) |
| 268 | if err != nil { |
| 269 | return err // 分片算法错误或者下载中断 |
| 270 | } |
| 271 | if newConcurrency { |
| 272 | go d.downloadPart() |
| 273 | d.concurrency-- |
| 274 | } |
no test coverage detected