| 1830 | } |
| 1831 | |
| 1832 | static int xma_decode_packet(AVCodecContext *avctx, AVFrame *frame, |
| 1833 | int *got_frame_ptr, AVPacket *avpkt) |
| 1834 | { |
| 1835 | XMADecodeCtx *s = avctx->priv_data; |
| 1836 | int got_stream_frame_ptr = 0; |
| 1837 | int i, ret = 0, eof = 0; |
| 1838 | |
| 1839 | if (!s->frames[s->current_stream]->data[0]) { |
| 1840 | avctx->internal->skip_samples = 64; |
| 1841 | s->frames[s->current_stream]->nb_samples = 512; |
| 1842 | if ((ret = ff_get_buffer(avctx, s->frames[s->current_stream], 0)) < 0) |
| 1843 | return ret; |
| 1844 | } else if (s->frames[s->current_stream]->nb_samples != 512) { |
| 1845 | avctx->internal->skip_samples = 64; |
| 1846 | av_frame_unref(s->frames[s->current_stream]); |
| 1847 | s->frames[s->current_stream]->nb_samples = 512; |
| 1848 | if ((ret = ff_get_buffer(avctx, s->frames[s->current_stream], 0)) < 0) |
| 1849 | return ret; |
| 1850 | } |
| 1851 | /* decode current stream packet */ |
| 1852 | if (!s->xma[s->current_stream].eof_done) { |
| 1853 | ret = decode_packet(avctx, &s->xma[s->current_stream], s->frames[s->current_stream], |
| 1854 | &got_stream_frame_ptr, avpkt); |
| 1855 | } |
| 1856 | |
| 1857 | if (!avpkt->size) { |
| 1858 | eof = 1; |
| 1859 | |
| 1860 | for (i = 0; i < s->num_streams; i++) { |
| 1861 | if (!s->xma[i].eof_done && s->frames[i]->data[0]) { |
| 1862 | ret = decode_packet(avctx, &s->xma[i], s->frames[i], |
| 1863 | &got_stream_frame_ptr, avpkt); |
| 1864 | } |
| 1865 | |
| 1866 | eof &= s->xma[i].eof_done; |
| 1867 | } |
| 1868 | } |
| 1869 | |
| 1870 | if (s->xma[0].trim_start) |
| 1871 | s->trim_start = s->xma[0].trim_start; |
| 1872 | if (s->xma[0].trim_end) |
| 1873 | s->trim_end = s->xma[0].trim_end; |
| 1874 | |
| 1875 | /* copy stream samples (1/2ch) to sample buffer (Nch) */ |
| 1876 | if (got_stream_frame_ptr) { |
| 1877 | const int nb_samples = s->frames[s->current_stream]->nb_samples; |
| 1878 | void *left[1] = { s->frames[s->current_stream]->extended_data[0] }; |
| 1879 | void *right[1] = { s->frames[s->current_stream]->extended_data[1] }; |
| 1880 | |
| 1881 | av_audio_fifo_write(s->samples[0][s->current_stream], left, nb_samples); |
| 1882 | if (s->xma[s->current_stream].nb_channels > 1) |
| 1883 | av_audio_fifo_write(s->samples[1][s->current_stream], right, nb_samples); |
| 1884 | } else if (ret < 0) { |
| 1885 | s->current_stream = 0; |
| 1886 | return ret; |
| 1887 | } |
| 1888 | |
| 1889 | /* find next XMA packet's owner stream, and update. |
nothing calls this directly
no test coverage detected