| 278 | } |
| 279 | |
| 280 | static int ogg_write_header(AVFormatContext *s) |
| 281 | { |
| 282 | OGGStreamContext *oggstream; |
| 283 | int i, j; |
| 284 | for (i = 0; i < s->nb_streams; i++) { |
| 285 | AVStream *st = s->streams[i]; |
| 286 | if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) |
| 287 | av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
| 288 | else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) |
| 289 | av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den); |
| 290 | if (st->codec->codec_id != CODEC_ID_VORBIS && |
| 291 | st->codec->codec_id != CODEC_ID_THEORA && |
| 292 | st->codec->codec_id != CODEC_ID_SPEEX && |
| 293 | st->codec->codec_id != CODEC_ID_FLAC) { |
| 294 | av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i); |
| 295 | return -1; |
| 296 | } |
| 297 | |
| 298 | if (!st->codec->extradata || !st->codec->extradata_size) { |
| 299 | av_log(s, AV_LOG_ERROR, "No extradata present\n"); |
| 300 | return -1; |
| 301 | } |
| 302 | oggstream = av_mallocz(sizeof(*oggstream)); |
| 303 | oggstream->page.stream_index = i; |
| 304 | st->priv_data = oggstream; |
| 305 | if (st->codec->codec_id == CODEC_ID_FLAC) { |
| 306 | int err = ogg_build_flac_headers(st->codec, oggstream, |
| 307 | st->codec->flags & CODEC_FLAG_BITEXACT, |
| 308 | s->metadata); |
| 309 | if (err) { |
| 310 | av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n"); |
| 311 | av_freep(&st->priv_data); |
| 312 | return err; |
| 313 | } |
| 314 | } else if (st->codec->codec_id == CODEC_ID_SPEEX) { |
| 315 | int err = ogg_build_speex_headers(st->codec, oggstream, |
| 316 | st->codec->flags & CODEC_FLAG_BITEXACT, |
| 317 | s->metadata); |
| 318 | if (err) { |
| 319 | av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n"); |
| 320 | av_freep(&st->priv_data); |
| 321 | return err; |
| 322 | } |
| 323 | } else { |
| 324 | if (ff_split_xiph_headers(st->codec->extradata, st->codec->extradata_size, |
| 325 | st->codec->codec_id == CODEC_ID_VORBIS ? 30 : 42, |
| 326 | oggstream->header, oggstream->header_len) < 0) { |
| 327 | av_log(s, AV_LOG_ERROR, "Extradata corrupted\n"); |
| 328 | av_freep(&st->priv_data); |
| 329 | return -1; |
| 330 | } |
| 331 | if (st->codec->codec_id == CODEC_ID_THEORA) { |
| 332 | /** KFGSHIFT is the width of the less significant section of the granule position |
| 333 | The less significant section is the frame count since the last keyframe */ |
| 334 | oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5); |
| 335 | oggstream->vrev = oggstream->header[0][9]; |
| 336 | av_log(s, AV_LOG_DEBUG, "theora kfgshift %d, vrev %d\n", |
| 337 | oggstream->kfgshift, oggstream->vrev); |
nothing calls this directly
no test coverage detected