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 | #include "libavutil/crc.h" | 22 | #include "libavutil/crc.h" |
| 23 | #include "libavutil/random_seed.h" | ||
| 23 | #include "libavcodec/xiph.h" | 24 | #include "libavcodec/xiph.h" |
| 24 | #include "libavcodec/bytestream.h" | 25 | #include "libavcodec/bytestream.h" |
| 25 | #include "libavcodec/flac.h" | 26 | #include "libavcodec/flac.h" |
| @@ -50,6 +51,7 @@ typedef struct { · 24 unmodified lines | |||
| 50 | int eos; | 51 | int eos; |
| 51 | unsigned page_count; ///< number of page buffered | 52 | unsigned page_count; ///< number of page buffered |
| 52 | OGGPage page; ///< current page | 53 | OGGPage page; ///< current page |
| 54 | unsigned serial_num; ///< serial number | ||
| 53 | } OGGStreamContext; | 55 | } OGGStreamContext; |
| 54 | 56 | ||
| 55 | typedef struct OGGPageList { | 57 | typedef struct OGGPageList { |
| @@ -80,7 +82,7 @@ static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags) · 24 unmodified lines | |||
| 80 | put_byte(s->pb, 0); | 82 | put_byte(s->pb, 0); |
| 81 | put_byte(s->pb, page->flags | extra_flags); | 83 | put_byte(s->pb, page->flags | extra_flags); |
| 82 | put_le64(s->pb, page->granule); | 84 | put_le64(s->pb, page->granule); |
| 83 | put_le32(s->pb, page->stream_index); | 85 | put_le32(s->pb, oggstream->serial_num); |
| 84 | put_le32(s->pb, oggstream->page_counter++); | 86 | put_le32(s->pb, oggstream->page_counter++); |
| 85 | crc_offset = url_ftell(s->pb); | 87 | crc_offset = url_ftell(s->pb); |
| 86 | put_le32(s->pb, 0); // crc | 88 | put_le32(s->pb, 0); // crc |
| @@ -280,8 +282,11 @@ static int ogg_write_header(AVFormatContext *s) · 193 unmodified lines | |||
| 280 | { | 282 | { |
| 281 | OGGStreamContext *oggstream; | 283 | OGGStreamContext *oggstream; |
| 282 | int i, j; | 284 | int i, j; |
| 285 | |||
| 283 | for (i = 0; i < s->nb_streams; i++) { | 286 | for (i = 0; i < s->nb_streams; i++) { |
| 284 | AVStream *st = s->streams[i]; | 287 | AVStream *st = s->streams[i]; |
| 288 | unsigned serial_num = i; | ||
| 289 | |||
| 285 | if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) | 290 | if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) |
| 286 | av_set_pts_info(st, 64, 1, st->codec->sample_rate); | 291 | av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
| 287 | else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) | 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 | oggstream = av_mallocz(sizeof(*oggstream)); | 306 | oggstream = av_mallocz(sizeof(*oggstream)); |
| 302 | oggstream->page.stream_index = i; | 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 | st->priv_data = oggstream; | 320 | st->priv_data = oggstream; |
| 304 | if (st->codec->codec_id == CODEC_ID_FLAC) { | 321 | if (st->codec->codec_id == CODEC_ID_FLAC) { |
| 305 | int err = ogg_build_flac_headers(st->codec, oggstream, | 322 | int err = ogg_build_flac_headers(st->codec, oggstream, |