Originally committed as revision 23302 to svn://svn.ffmpeg.org/ffmpeg/trunk
Unified · Split
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | 22 | #include "libavutil/crc.h" |
| 23 | +#include "libavutil/random_seed.h" | |
| 23 | 24 | #include "libavcodec/xiph.h" |
| 24 | 25 | #include "libavcodec/bytestream.h" |
| 25 | 26 | #include "libavcodec/flac.h" |
| @@ -50,6 +51,7 @@ typedef struct { · 24 unmodified lines | ||
| 50 | 51 | int eos; |
| 51 | 52 | unsigned page_count; ///< number of page buffered |
| 52 | 53 | OGGPage page; ///< current page |
| 54 | + unsigned serial_num; ///< serial number | |
| 53 | 55 | } OGGStreamContext; |
| 54 | 56 | |
| 55 | 57 | typedef struct OGGPageList { |
| @@ -80,7 +82,7 @@ static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags) · 24 unmodified lines | ||
| 80 | 82 | put_byte(s->pb, 0); |
| 81 | 83 | put_byte(s->pb, page->flags | extra_flags); |
| 82 | 84 | put_le64(s->pb, page->granule); |
| 83 | − put_le32(s->pb, page->stream_index); | |
| 85 | + put_le32(s->pb, oggstream->serial_num); | |
| 84 | 86 | put_le32(s->pb, oggstream->page_counter++); |
| 85 | 87 | crc_offset = url_ftell(s->pb); |
| 86 | 88 | put_le32(s->pb, 0); // crc |
| @@ -280,8 +282,11 @@ static int ogg_write_header(AVFormatContext *s) · 193 unmodified lines | ||
| 280 | 282 | { |
| 281 | 283 | OGGStreamContext *oggstream; |
| 282 | 284 | int i, j; |
| 285 | + | |
| 283 | 286 | for (i = 0; i < s->nb_streams; i++) { |
| 284 | 287 | AVStream *st = s->streams[i]; |
| 288 | + unsigned serial_num = i; | |
| 289 | + | |
| 285 | 290 | if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) |
| 286 | 291 | av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
| 287 | 292 | else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) |
| @@ -300,6 +305,18 @@ static int ogg_write_header(AVFormatContext *s) · 12 unmodified lines | ||
| 300 | 305 | } |
| 301 | 306 | oggstream = av_mallocz(sizeof(*oggstream)); |
| 302 | 307 | oggstream->page.stream_index = i; |
| 308 | + | |
| 309 | + if (!(st->codec->flags & CODEC_FLAG_BITEXACT)) | |
| 310 | + do { | |
| 311 | + serial_num = av_get_random_seed(); | |
| 312 | + for (j = 0; j < i; j++) { | |
| 313 | + OGGStreamContext *sc = s->streams[j]->priv_data; | |
| 314 | + if (serial_num == sc->serial_num) | |
| 315 | + break; | |
| 316 | + } | |
| 317 | + } while (j < i); | |
| 318 | + oggstream->serial_num = serial_num; | |
| 319 | + | |
| 303 | 320 | st->priv_data = oggstream; |
| 304 | 321 | if (st->codec->codec_id == CODEC_ID_FLAC) { |
| 305 | 322 | int err = ogg_build_flac_headers(st->codec, oggstream, |