1/* 2 * GXF muxer. 3 * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com> 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "libavutil/fifo.h" 23#include "avformat.h" 24#include "gxf.h" 25#include "riff.h" 26#include "audiointerleave.h" 27 28#define GXF_AUDIO_PACKET_SIZE 65536 29 30typedef struct GXFStreamContext { 31 AudioInterleaveContext aic; 32 AVCodecContext *codec; 33 uint32_t track_type; 34 uint32_t sample_size; 35 uint32_t sample_rate; 36 uint16_t media_type; 37 uint16_t media_info; 38 uint8_t index; 39 int frame_rate_index; 40 int lines_index; 41 int fields; 42 int iframes; 43 int pframes; 44 int bframes; 45 int p_per_gop; 46 int b_per_i_or_p; ///< number of B frames per I frame or P frame 47 int first_gop_closed; 48 int64_t current_dts; 49 int dts_delay; 50} GXFStreamContext; 51 52typedef struct GXFContext { 53 uint32_t nb_fields; 54 uint32_t material_flags; 55 uint16_t audio_tracks; 56 uint16_t mpeg_tracks; 57 int64_t creation_time; 58 uint32_t umf_start_offset; 59 uint32_t umf_track_offset; 60 uint32_t umf_media_offset; 61 uint32_t umf_user_data_offset; 62 uint32_t umf_user_data_size; 63 uint32_t umf_length; 64 uint16_t umf_track_size; 65 uint16_t umf_media_size; 66 int audio_written; 67 int sample_rate; 68 int flags; 69 AVFormatContext *fc; 70} GXFContext; 71 72typedef struct GXF_Lines { 73 int height; 74 int index; 75} GXF_Lines; 76 77 78/* FIXME check if it is relevant */ 79static const GXF_Lines gxf_lines_tab[] = { 80 { 480, 1 }, /* NTSC */ 81 { 512, 1 }, /* NTSC + VBI */ 82 { 576, 2 }, /* PAL */ 83 { 608, 2 }, /* PAL + VBI */ 84 { 1080, 4 }, 85 { 720, 6 }, 86}; 87 88static const AVCodecTag gxf_media_types[] = { 89 { CODEC_ID_MJPEG , 3 }, /* NTSC */ 90 { CODEC_ID_MJPEG , 4 }, /* PAL */ 91 { CODEC_ID_PCM_S24LE , 9 }, 92 { CODEC_ID_PCM_S16LE , 10 }, 93 { CODEC_ID_MPEG2VIDEO, 11 }, /* NTSC */ 94 { CODEC_ID_MPEG2VIDEO, 12 }, /* PAL */ 95 { CODEC_ID_DVVIDEO , 13 }, /* NTSC */ 96 { CODEC_ID_DVVIDEO , 14 }, /* PAL */ 97 { CODEC_ID_DVVIDEO , 15 }, /* 50M NTSC */ 98 { CODEC_ID_DVVIDEO , 16 }, /* 50M PAL */ 99 { CODEC_ID_AC3 , 17 }, 100 //{ CODEC_ID_NONE, , 18 }, /* Non compressed 24 bit audio */ 101 { CODEC_ID_MPEG2VIDEO, 20 }, /* MPEG HD */ 102 { CODEC_ID_MPEG1VIDEO, 22 }, /* NTSC */ 103 { CODEC_ID_MPEG1VIDEO, 23 }, /* PAL */ 104 { 0, 0 }, 105}; 106 107#define SERVER_PATH "/space/" 108#define ES_NAME_PATTERN "ES." 109 110static int gxf_find_lines_index(GXFStreamContext *ctx) 111{ 112 int i; 113 114 for (i = 0; i < 6; ++i) { 115 if (ctx->codec->height == gxf_lines_tab[i].height) { 116 ctx->lines_index = gxf_lines_tab[i].index; 117 return 0; 118 } 119 } 120 return -1; 121} 122 123static void gxf_write_padding(ByteIOContext *pb, int64_t to_pad) 124{ 125 for (; to_pad > 0; to_pad--) { 126 put_byte(pb, 0); 127 } 128} 129 130static int64_t updatePacketSize(ByteIOContext *pb, int64_t pos) 131{ 132 int64_t curpos; 133 int size; 134 135 size = url_ftell(pb) - pos; 136 if (size % 4) { 137 gxf_write_padding(pb, 4 - size % 4); 138 size = url_ftell(pb) - pos; 139 } 140 curpos = url_ftell(pb); 141 url_fseek(pb, pos + 6, SEEK_SET); 142 put_be32(pb, size); 143 url_fseek(pb, curpos, SEEK_SET); 144 return curpos - pos; 145} 146 147static int64_t updateSize(ByteIOContext *pb, int64_t pos) 148{ 149 int64_t curpos; 150 151 curpos = url_ftell(pb); 152 url_fseek(pb, pos, SEEK_SET); 153 put_be16(pb, curpos - pos - 2); 154 url_fseek(pb, curpos, SEEK_SET); 155 return curpos - pos; 156} 157 158static void gxf_write_packet_header(ByteIOContext *pb, GXFPktType type) 159{ 160 put_be32(pb, 0); /* packet leader for synchro */ 161 put_byte(pb, 1); 162 put_byte(pb, type); /* map packet */ 163 put_be32(pb, 0); /* size */ 164 put_be32(pb, 0); /* reserved */ 165 put_byte(pb, 0xE1); /* trailer 1 */ 166 put_byte(pb, 0xE2); /* trailer 2 */ 167} 168 169static int gxf_write_mpeg_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx) 170{ 171 char buffer[1024]; 172 int size, starting_line; 173 174 if (ctx->iframes) { 175 ctx->p_per_gop = ctx->pframes / ctx->iframes; 176 if (ctx->pframes % ctx->iframes) 177 ctx->p_per_gop++; 178 if (ctx->pframes) { 179 ctx->b_per_i_or_p = ctx->bframes / ctx->pframes; 180 if (ctx->bframes % ctx->pframes) 181 ctx->b_per_i_or_p++; 182 } 183 if (ctx->p_per_gop > 9) 184 ctx->p_per_gop = 9; /* ensure value won't take more than one char */ 185 if (ctx->b_per_i_or_p > 9) 186 ctx->b_per_i_or_p = 9; /* ensure value won't take more than one char */ 187 } 188 if (ctx->codec->height == 512 || ctx->codec->height == 608) 189 starting_line = 7; // VBI 190 else if (ctx->codec->height == 480) 191 starting_line = 20; 192 else 193 starting_line = 23; // default PAL 194 195 size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n" 196 "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n", 197 (float)ctx->codec->bit_rate, ctx->p_per_gop, ctx->b_per_i_or_p, 198 ctx->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, ctx->first_gop_closed == 1, 199 starting_line, ctx->codec->height / 16); 200 put_byte(pb, TRACK_MPG_AUX); 201 put_byte(pb, size + 1); 202 put_buffer(pb, (uint8_t *)buffer, size + 1); 203 return size + 3; 204} 205 206static int gxf_write_timecode_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx) 207{ 208 /* FIXME implement that */ 209 put_byte(pb, 0); /* fields */ 210 put_byte(pb, 0); /* seconds */ 211 put_byte(pb, 0); /* minutes */ 212 put_byte(pb, 0); /* flags + hours */ 213 /* reserved */ 214 put_be32(pb, 0); 215 return 8; 216} 217 218static int gxf_write_track_description(ByteIOContext *pb, GXFStreamContext *stream) 219{ 220 int64_t pos; 221 222 /* track description section */ 223 put_byte(pb, stream->media_type + 0x80); 224 put_byte(pb, stream->index + 0xC0); 225 226 pos = url_ftell(pb); 227 put_be16(pb, 0); /* size */ 228 229 /* media file name */ 230 put_byte(pb, TRACK_NAME); 231 put_byte(pb, strlen(ES_NAME_PATTERN) + 3); 232 put_tag(pb, ES_NAME_PATTERN); 233 put_be16(pb, stream->media_info); 234 put_byte(pb, 0); 235 236 if (stream->codec->codec_id != CODEC_ID_MPEG2VIDEO) { 237 /* auxiliary information */ 238 put_byte(pb, TRACK_AUX); 239 put_byte(pb, 8); 240 if (stream->codec->codec_id == CODEC_ID_NONE) 241 gxf_write_timecode_auxiliary(pb, stream); 242 else 243 put_le64(pb, 0); 244 } 245 246 /* file system version */ 247 put_byte(pb, TRACK_VER); 248 put_byte(pb, 4); 249 put_be32(pb, 0); 250 251 if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO) 252 gxf_write_mpeg_auxiliary(pb, stream); 253 254 /* frame rate */ 255 put_byte(pb, TRACK_FPS); 256 put_byte(pb, 4); 257 put_be32(pb, stream->frame_rate_index); 258 259 /* lines per frame */ 260 put_byte(pb, TRACK_LINES); 261 put_byte(pb, 4); 262 put_be32(pb, stream->lines_index); 263 264 /* fields per frame */ 265 put_byte(pb, TRACK_FPF); 266 put_byte(pb, 4); 267 put_be32(pb, stream->fields); 268 269 return updateSize(pb, pos); 270} 271 272static int gxf_write_material_data_section(ByteIOContext *pb, GXFContext *ctx) 273{ 274 int64_t pos; 275 const char *filename = strrchr(ctx->fc->filename, '/'); 276 277 pos = url_ftell(pb); 278 put_be16(pb, 0); /* size */ 279 280 /* name */ 281 if (filename) 282 filename++; 283 else 284 filename = ctx->fc->filename; 285 put_byte(pb, MAT_NAME); 286 put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1); 287 put_tag(pb, SERVER_PATH); 288 put_tag(pb, filename); 289 put_byte(pb, 0); 290 291 /* first field */ 292 put_byte(pb, MAT_FIRST_FIELD); 293 put_byte(pb, 4); 294 put_be32(pb, 0); 295 296 /* last field */ 297 put_byte(pb, MAT_LAST_FIELD); 298 put_byte(pb, 4); 299 put_be32(pb, ctx->nb_fields); 300 301 /* reserved */ 302 put_byte(pb, MAT_MARK_IN); 303 put_byte(pb, 4); 304 put_be32(pb, 0); 305 306 put_byte(pb, MAT_MARK_OUT); 307 put_byte(pb, 4); 308 put_be32(pb, ctx->nb_fields); 309 310 /* estimated size */ 311 put_byte(pb, MAT_SIZE); 312 put_byte(pb, 4); 313 put_be32(pb, url_fsize(pb) / 1024); 314 315 return updateSize(pb, pos); 316} 317 318static int gxf_write_track_description_section(ByteIOContext *pb, GXFContext *ctx) 319{ 320 int64_t pos; 321 int i; 322 323 pos = url_ftell(pb); 324 put_be16(pb, 0); /* size */ 325 for (i = 0; i < ctx->fc->nb_streams; ++i) 326 gxf_write_track_description(pb, ctx->fc->streams[i]->priv_data); 327 return updateSize(pb, pos); 328} 329 330static int gxf_write_map_packet(ByteIOContext *pb, GXFContext *ctx) 331{ 332 int64_t pos = url_ftell(pb); 333 334 gxf_write_packet_header(pb, PKT_MAP); 335 336 /* preamble */ 337 put_byte(pb, 0xE0); /* version */ 338 put_byte(pb, 0xFF); /* reserved */ 339 340 gxf_write_material_data_section(pb, ctx); 341 gxf_write_track_description_section(pb, ctx); 342 343 return updatePacketSize(pb, pos); 344} 345 346#if 0 347static int gxf_write_flt_packet(ByteIOContext *pb, GXFContext *ctx) 348{ 349 int64_t pos = url_ftell(pb); 350 int i; 351 352 gxf_write_packet_header(pb, PKT_FLT); 353 354 put_le32(pb, 1000); /* number of fields */ 355 put_le32(pb, 0); /* number of active flt entries */ 356 357 for (i = 0; i < 1000; ++i) { 358 put_le32(pb, 0); 359 } 360 return updatePacketSize(pb, pos); 361} 362#endif 363 364static int gxf_write_umf_material_description(ByteIOContext *pb, GXFContext *ctx) 365{ 366 // XXX drop frame 367 uint32_t timecode = 368 ctx->nb_fields / (ctx->sample_rate * 3600) % 24 << 24 | // hours 369 ctx->nb_fields / (ctx->sample_rate * 60) % 60 << 16 | // minutes 370 ctx->nb_fields / ctx->sample_rate % 60 << 8 | // seconds 371 ctx->nb_fields % ctx->sample_rate; // fields 372 373 put_le32(pb, ctx->flags); 374 put_le32(pb, ctx->nb_fields); /* length of the longest track */ 375 put_le32(pb, ctx->nb_fields); /* length of the shortest track */ 376 put_le32(pb, 0); /* mark in */ 377 put_le32(pb, ctx->nb_fields); /* mark out */ 378 put_le32(pb, 0); /* timecode mark in */ 379 put_le32(pb, timecode); /* timecode mark out */ 380 put_le64(pb, ctx->fc->timestamp); /* modification time */ 381 put_le64(pb, ctx->fc->timestamp); /* creation time */ 382 put_le16(pb, 0); /* reserved */ 383 put_le16(pb, 0); /* reserved */ 384 put_le16(pb, ctx->audio_tracks); 385 put_le16(pb, 0); /* timecode track count */ 386 put_le16(pb, 0); /* reserved */ 387 put_le16(pb, ctx->mpeg_tracks); 388 return 48; 389} 390 391static int gxf_write_umf_payload(ByteIOContext *pb, GXFContext *ctx) 392{ 393 put_le32(pb, ctx->umf_length); /* total length of the umf data */ 394 put_le32(pb, 3); /* version */ 395 put_le32(pb, ctx->fc->nb_streams); 396 put_le32(pb, ctx->umf_track_offset); /* umf track section offset */ 397 put_le32(pb, ctx->umf_track_size); 398 put_le32(pb, ctx->fc->nb_streams); 399 put_le32(pb, ctx->umf_media_offset); 400 put_le32(pb, ctx->umf_media_size); 401 put_le32(pb, ctx->umf_user_data_offset); /* user data offset */ 402 put_le32(pb, ctx->umf_user_data_size); /* user data size */ 403 put_le32(pb, 0); /* reserved */ 404 put_le32(pb, 0); /* reserved */ 405 return 48; 406} 407 408static int gxf_write_umf_track_description(ByteIOContext *pb, GXFContext *ctx) 409{ 410 int64_t pos = url_ftell(pb); 411 int tracks[255]={0}; 412 int i; 413 414 ctx->umf_track_offset = pos - ctx->umf_start_offset; 415 for (i = 0; i < ctx->fc->nb_streams; ++i) { 416 AVStream *st = ctx->fc->streams[i]; 417 GXFStreamContext *sc = st->priv_data; 418 int id = 0; 419 420 switch (st->codec->codec_id) { 421 case CODEC_ID_MPEG1VIDEO: id= 'L'; break; 422 case CODEC_ID_MPEG2VIDEO: id= 'M'; break; 423 case CODEC_ID_PCM_S16LE: id= 'A'; break; 424 case CODEC_ID_DVVIDEO: id= sc->track_type == 6 ? 'E' : 'D'; break; 425 case CODEC_ID_MJPEG: id= 'V'; break; 426 default: break; 427 } 428 sc->media_info= id << 8; 429 /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */ 430 sc->media_info |= '0' + (tracks[id]++); 431 put_le16(pb, sc->media_info); 432 put_le16(pb, 1); 433 } 434 return url_ftell(pb) - pos; 435} 436 437static int gxf_write_umf_media_mpeg(ByteIOContext *pb, GXFStreamContext *stream) 438{ 439 if (stream->codec->pix_fmt == PIX_FMT_YUV422P) 440 put_le32(pb, 2); 441 else 442 put_le32(pb, 1); /* default to 420 */ 443 put_le32(pb, stream->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */ 444 put_le32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */ 445 put_le32(pb, 1); /* I picture per GOP */ 446 put_le32(pb, stream->p_per_gop); 447 put_le32(pb, stream->b_per_i_or_p); 448 if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO) 449 put_le32(pb, 2); 450 else if (stream->codec->codec_id == CODEC_ID_MPEG1VIDEO) 451 put_le32(pb, 1); 452 else 453 put_le32(pb, 0); 454 put_le32(pb, 0); /* reserved */ 455 return 32; 456} 457 458static int gxf_write_umf_media_timecode(ByteIOContext *pb, GXFStreamContext *track) 459{ 460 /* FIXME implement */ 461 put_be32(pb, 0); /* drop frame flag */ 462 put_be32(pb, 0); /* reserved */ 463 put_be32(pb, 0); /* reserved */ 464 put_be32(pb, 0); /* reserved */ 465 put_be32(pb, 0); /* reserved */ 466 put_be32(pb, 0); /* reserved */ 467 put_be32(pb, 0); /* reserved */ 468 put_be32(pb, 0); /* reserved */ 469 return 32; 470} 471 472static int gxf_write_umf_media_dv(ByteIOContext *pb, GXFStreamContext *track) 473{ 474 int i; 475 476 for (i = 0; i < 8; i++) { 477 put_be32(pb, 0); 478 } 479 return 32; 480} 481 482static int gxf_write_umf_media_audio(ByteIOContext *pb, GXFStreamContext *track) 483{ 484 put_le64(pb, av_dbl2int(1)); /* sound level to begin to */ 485 put_le64(pb, av_dbl2int(1)); /* sound level to begin to */ 486 put_le32(pb, 0); /* number of fields over which to ramp up sound level */ 487 put_le32(pb, 0); /* number of fields over which to ramp down sound level */ 488 put_le32(pb, 0); /* reserved */ 489 put_le32(pb, 0); /* reserved */ 490 return 32; 491} 492 493#if 0 494static int gxf_write_umf_media_mjpeg(ByteIOContext *pb, GXFStreamContext *track) 495{ 496 put_be64(pb, 0); /* FIXME FLOAT max chroma quant level */ 497 put_be64(pb, 0); /* FIXME FLOAT max luma quant level */ 498 put_be64(pb, 0); /* FIXME FLOAT min chroma quant level */ 499 put_be64(pb, 0); /* FIXME FLOAT min luma quant level */ 500 return 32; 501} 502#endif 503 504static int gxf_write_umf_media_description(ByteIOContext *pb, GXFContext *ctx) 505{ 506 int64_t pos; 507 int i; 508 509 pos = url_ftell(pb); 510 ctx->umf_media_offset = pos - ctx->umf_start_offset; 511 for (i = 0; i < ctx->fc->nb_streams; ++i) { 512 GXFStreamContext *sc = ctx->fc->streams[i]->priv_data; 513 char buffer[88]; 514 int64_t startpos, curpos; 515 int path_size = strlen(ES_NAME_PATTERN); 516 517 memset(buffer, 0, 88); 518 startpos = url_ftell(pb); 519 put_le16(pb, 0); /* length */ 520 put_le16(pb, sc->media_info); 521 put_le16(pb, 0); /* reserved */ 522 put_le16(pb, 0); /* reserved */ 523 put_le32(pb, ctx->nb_fields); 524 put_le32(pb, 0); /* attributes rw, ro */ 525 put_le32(pb, 0); /* mark in */ 526 put_le32(pb, ctx->nb_fields); /* mark out */ 527 strncpy(buffer, ES_NAME_PATTERN, path_size); 528 put_buffer(pb, (uint8_t *)buffer, path_size); 529 put_be16(pb, sc->media_info); 530 put_buffer(pb, (uint8_t *)buffer + path_size + 2, 88 - path_size - 2); 531 put_le32(pb, sc->track_type); 532 put_le32(pb, sc->sample_rate); 533 put_le32(pb, sc->sample_size); 534 put_le32(pb, 0); /* reserved */ 535 switch (sc->codec->codec_id) { 536 case CODEC_ID_MPEG2VIDEO: 537 gxf_write_umf_media_mpeg(pb, sc); 538 break; 539 case CODEC_ID_PCM_S16LE: 540 gxf_write_umf_media_audio(pb, sc); 541 break; 542 case CODEC_ID_DVVIDEO: 543 gxf_write_umf_media_dv(pb, sc); 544 break; 545 default: 546 gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */ 547 } 548 curpos = url_ftell(pb); 549 url_fseek(pb, startpos, SEEK_SET); 550 put_le16(pb, curpos - startpos); 551 url_fseek(pb, curpos, SEEK_SET); 552 } 553 return url_ftell(pb) - pos; 554} 555 556static int gxf_write_umf_user_data(ByteIOContext *pb, GXFContext *ctx) 557{ 558 int64_t pos = url_ftell(pb); 559 ctx->umf_user_data_offset = pos - ctx->umf_start_offset; 560 put_le32(pb, 20); 561 put_le32(pb, 0); 562 put_le16(pb, 0); 563 put_le16(pb, 0); 564 put_le32(pb, 0); 565 put_byte(pb, 0); 566 put_byte(pb, 0); 567 put_byte(pb, 0); 568 put_byte(pb, 0); 569 return 20; 570} 571 572static int gxf_write_umf_packet(ByteIOContext *pb, GXFContext *ctx) 573{ 574 int64_t pos = url_ftell(pb); 575 576 gxf_write_packet_header(pb, PKT_UMF); 577 578 /* preamble */ 579 put_byte(pb, 3); /* first and last (only) packet */ 580 put_be32(pb, ctx->umf_length); /* data length */ 581 582 ctx->umf_start_offset = url_ftell(pb); 583 gxf_write_umf_payload(pb, ctx); 584 gxf_write_umf_material_description(pb, ctx); 585 ctx->umf_track_size = gxf_write_umf_track_description(pb, ctx); 586 ctx->umf_media_size = gxf_write_umf_media_description(pb, ctx); 587 ctx->umf_user_data_size = gxf_write_umf_user_data(pb, ctx); 588 ctx->umf_length = url_ftell(pb) - ctx->umf_start_offset; 589 return updatePacketSize(pb, pos); 590} 591 592#define GXF_NODELAY -5000 593 594static const int GXF_samples_per_frame[] = { 32768, 0 }; 595 596static int gxf_write_header(AVFormatContext *s) 597{ 598 ByteIOContext *pb = s->pb; 599 GXFContext *gxf = s->priv_data; 600 int i; 601 602 gxf->fc = s; 603 gxf->flags |= 0x00080000; /* material is simple clip */ 604 for (i = 0; i < s->nb_streams; ++i) { 605 AVStream *st = s->streams[i]; 606 GXFStreamContext *sc = av_mallocz(sizeof(*sc)); 607 if (!sc) 608 return AVERROR(ENOMEM); 609 st->priv_data = sc; 610 611 sc->codec = st->codec; 612 sc->index = i; 613 sc->media_type = codec_get_tag(gxf_media_types, sc->codec->codec_id); 614 if (st->codec->codec_type == CODEC_TYPE_AUDIO) { 615 if (st->codec->codec_id != CODEC_ID_PCM_S16LE) { 616 av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n"); 617 return -1; 618 } 619 if (st->codec->sample_rate != 48000) { 620 av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n"); 621 return -1; 622 } 623 if (st->codec->channels != 1) { 624 av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n"); 625 return -1; 626 } 627 sc->track_type = 2; 628 sc->sample_rate = st->codec->sample_rate; 629 av_set_pts_info(st, 64, 1, sc->sample_rate); 630 sc->sample_size = 16; 631 sc->frame_rate_index = -2; 632 sc->lines_index = -2; 633 sc->fields = -2; 634 gxf->audio_tracks++; 635 gxf->flags |= 0x04000000; /* audio is 16 bit pcm */ 636 } else if (sc->codec->codec_type == CODEC_TYPE_VIDEO) { 637 /* FIXME check from time_base ? */ 638 if (sc->codec->height == 480 || sc->codec->height == 512) { /* NTSC or NTSC+VBI */ 639 sc->frame_rate_index = 5; 640 sc->sample_rate = 60; 641 gxf->flags |= 0x00000080; 642 } else { /* assume PAL */ 643 sc->frame_rate_index = 6; 644 sc->media_type++; 645 sc->sample_rate = 50; 646 gxf->flags |= 0x00000040; 647 } 648 gxf->sample_rate = sc->sample_rate; 649 av_set_pts_info(st, 64, 1, st->codec->time_base.den); 650 sc->dts_delay = GXF_NODELAY; 651 if (gxf_find_lines_index(sc) < 0) 652 sc->lines_index = -1; 653 sc->sample_size = st->codec->bit_rate; 654 sc->fields = 2; /* interlaced */ 655 switch (sc->codec->codec_id) { 656 case CODEC_ID_MPEG2VIDEO: 657 sc->first_gop_closed = -1; 658 sc->track_type = 4; 659 gxf->mpeg_tracks++; 660 gxf->flags |= 0x00008000; 661 break; 662 case CODEC_ID_DVVIDEO: 663 if (sc->codec->pix_fmt == PIX_FMT_YUV422P) { 664 sc->media_type += 2; 665 sc->track_type = 6; 666 gxf->flags |= 0x00002000; 667 } else { 668 sc->track_type = 5; 669 gxf->flags |= 0x00001000; 670 } 671 break; 672 default: 673 av_log(s, AV_LOG_ERROR, "video codec not supported\n"); 674 return -1; 675 } 676 } 677 } 678 679 if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0) 680 return -1; 681 682 gxf_write_map_packet(pb, gxf); 683 //gxf_write_flt_packet(pb, gxf); 684 gxf_write_umf_packet(pb, gxf); 685 put_flush_packet(pb); 686 return 0; 687} 688 689static int gxf_write_eos_packet(ByteIOContext *pb, GXFContext *ctx) 690{ 691 int64_t pos = url_ftell(pb); 692 693 gxf_write_packet_header(pb, PKT_EOS); 694 return updatePacketSize(pb, pos); 695} 696 697static int gxf_write_trailer(AVFormatContext *s) 698{ 699 ByteIOContext *pb = s->pb; 700 GXFContext *gxf = s->priv_data; 701 int64_t end; 702 703 ff_audio_interleave_close(s); 704 705 gxf_write_eos_packet(pb, gxf); 706 end = url_ftell(pb); 707 url_fseek(pb, 0, SEEK_SET); 708 /* overwrite map and umf packets with new values */ 709 gxf_write_map_packet(pb, gxf); 710 //gxf_write_flt_packet(pb, gxf); 711 gxf_write_umf_packet(pb, gxf); 712 url_fseek(pb, end, SEEK_SET); 713 return 0; 714} 715 716static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size) 717{ 718 uint32_t c=-1; 719 int i; 720 for(i=0; i<size-4 && c!=0x100; i++){ 721 c = (c<<8) + buf[i]; 722 if(c == 0x1B8 && sc->first_gop_closed == -1) /* GOP start code */ 723 sc->first_gop_closed= (buf[i+4]>>6)&1; 724 } 725 return (buf[i+1]>>3)&7; 726} 727 728static int gxf_write_media_preamble(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt, int size) 729{ 730 GXFStreamContext *sc = ctx->fc->streams[pkt->stream_index]->priv_data; 731 unsigned field_nb; 732 /* If the video is frame-encoded, the frame numbers shall be represented by 733 * even field numbers. 734 * see SMPTE360M-2004 6.4.2.1.3 Media field number */ 735 if (sc->codec->codec_type == CODEC_TYPE_VIDEO) { 736 field_nb = ctx->nb_fields; 737 } else { 738 field_nb = av_rescale_rnd(pkt->dts, ctx->sample_rate, sc->codec->time_base.den, AV_ROUND_UP); 739 } 740 741 put_byte(pb, sc->media_type); 742 put_byte(pb, sc->index); 743 put_be32(pb, field_nb); 744 if (sc->codec->codec_type == CODEC_TYPE_AUDIO) { 745 put_be16(pb, 0); 746 put_be16(pb, size / 2); 747 } else if (sc->codec->codec_id == CODEC_ID_MPEG2VIDEO) { 748 int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size); 749 if (frame_type == FF_I_TYPE) { 750 put_byte(pb, 0x0d); 751 sc->iframes++; 752 } else if (frame_type == FF_B_TYPE) { 753 put_byte(pb, 0x0f); 754 sc->bframes++; 755 } else { 756 put_byte(pb, 0x0e); 757 sc->pframes++; 758 } 759 put_be24(pb, size); 760 } else if (sc->codec->codec_id == CODEC_ID_DVVIDEO) { 761 put_byte(pb, size / 4096); 762 put_be24(pb, 0); 763 } else 764 put_be32(pb, size); 765 put_be32(pb, field_nb); 766 put_byte(pb, 1); /* flags */ 767 put_byte(pb, 0); /* reserved */ 768 return 16; 769} 770 771static int gxf_write_media_packet(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt) 772{ 773 GXFStreamContext *sc = ctx->fc->streams[pkt->stream_index]->priv_data; 774 int64_t pos = url_ftell(pb); 775 int padding = 0; 776 777 gxf_write_packet_header(pb, PKT_MEDIA); 778 if (sc->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */ 779 padding = 4 - pkt->size % 4; 780 else if (sc->codec->codec_type == CODEC_TYPE_AUDIO) 781 padding = GXF_AUDIO_PACKET_SIZE - pkt->size; 782 gxf_write_media_preamble(pb, ctx, pkt, pkt->size + padding); 783 put_buffer(pb, pkt->data, pkt->size); 784 gxf_write_padding(pb, padding); 785 786 if (sc->codec->codec_type == CODEC_TYPE_VIDEO) 787 ctx->nb_fields += 2; // count fields 788 789 return updatePacketSize(pb, pos); 790} 791 792static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt) 793{ 794 GXFContext *gxf = s->priv_data; 795 796 gxf_write_media_packet(s->pb, gxf, pkt); 797 put_flush_packet(s->pb); 798 return 0; 799} 800 801static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) 802{ 803 return ff_audio_rechunk_interleave(s, out, pkt, flush, 804 av_interleave_packet_per_dts, ff_interleave_compare_dts); 805} 806 807AVOutputFormat gxf_muxer = { 808 "gxf", 809 NULL_IF_CONFIG_SMALL("GXF format"), 810 NULL, 811 "gxf", 812 sizeof(GXFContext), 813 CODEC_ID_PCM_S16LE, 814 CODEC_ID_MPEG2VIDEO, 815 gxf_write_header, 816 gxf_write_packet, 817 gxf_write_trailer, 818 0, 819 NULL, 820 gxf_interleave_packet, 821}; 822