00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/fifo.h"
00023 #include "avformat.h"
00024 #include "gxf.h"
00025 #include "riff.h"
00026 #include "audiointerleave.h"
00027
00028 #define GXF_AUDIO_PACKET_SIZE 65536
00029
00030 typedef struct GXFStreamContext {
00031 AudioInterleaveContext aic;
00032 AVCodecContext *codec;
00033 uint32_t track_type;
00034 uint32_t sample_size;
00035 uint32_t sample_rate;
00036 uint16_t media_type;
00037 uint16_t media_info;
00038 uint8_t index;
00039 int frame_rate_index;
00040 int lines_index;
00041 int fields;
00042 int iframes;
00043 int pframes;
00044 int bframes;
00045 int p_per_gop;
00046 int b_per_i_or_p;
00047 int first_gop_closed;
00048 int64_t current_dts;
00049 int dts_delay;
00050 } GXFStreamContext;
00051
00052 typedef struct GXFContext {
00053 uint32_t nb_fields;
00054 uint32_t material_flags;
00055 uint16_t audio_tracks;
00056 uint16_t mpeg_tracks;
00057 int64_t creation_time;
00058 uint32_t umf_start_offset;
00059 uint32_t umf_track_offset;
00060 uint32_t umf_media_offset;
00061 uint32_t umf_user_data_offset;
00062 uint32_t umf_user_data_size;
00063 uint32_t umf_length;
00064 uint16_t umf_track_size;
00065 uint16_t umf_media_size;
00066 int audio_written;
00067 int sample_rate;
00068 int flags;
00069 AVFormatContext *fc;
00070 } GXFContext;
00071
00072 typedef struct GXF_Lines {
00073 int height;
00074 int index;
00075 } GXF_Lines;
00076
00077
00078
00079 static const GXF_Lines gxf_lines_tab[] = {
00080 { 480, 1 },
00081 { 512, 1 },
00082 { 576, 2 },
00083 { 608, 2 },
00084 { 1080, 4 },
00085 { 720, 6 },
00086 };
00087
00088 static const AVCodecTag gxf_media_types[] = {
00089 { CODEC_ID_MJPEG , 3 },
00090 { CODEC_ID_MJPEG , 4 },
00091 { CODEC_ID_PCM_S24LE , 9 },
00092 { CODEC_ID_PCM_S16LE , 10 },
00093 { CODEC_ID_MPEG2VIDEO, 11 },
00094 { CODEC_ID_MPEG2VIDEO, 12 },
00095 { CODEC_ID_DVVIDEO , 13 },
00096 { CODEC_ID_DVVIDEO , 14 },
00097 { CODEC_ID_DVVIDEO , 15 },
00098 { CODEC_ID_DVVIDEO , 16 },
00099 { CODEC_ID_AC3 , 17 },
00100
00101 { CODEC_ID_MPEG2VIDEO, 20 },
00102 { CODEC_ID_MPEG1VIDEO, 22 },
00103 { CODEC_ID_MPEG1VIDEO, 23 },
00104 { 0, 0 },
00105 };
00106
00107 #define SERVER_PATH "/space/"
00108 #define ES_NAME_PATTERN "ES."
00109
00110 static int gxf_find_lines_index(GXFStreamContext *ctx)
00111 {
00112 int i;
00113
00114 for (i = 0; i < 6; ++i) {
00115 if (ctx->codec->height == gxf_lines_tab[i].height) {
00116 ctx->lines_index = gxf_lines_tab[i].index;
00117 return 0;
00118 }
00119 }
00120 return -1;
00121 }
00122
00123 static void gxf_write_padding(ByteIOContext *pb, int64_t to_pad)
00124 {
00125 for (; to_pad > 0; to_pad--) {
00126 put_byte(pb, 0);
00127 }
00128 }
00129
00130 static int64_t updatePacketSize(ByteIOContext *pb, int64_t pos)
00131 {
00132 int64_t curpos;
00133 int size;
00134
00135 size = url_ftell(pb) - pos;
00136 if (size % 4) {
00137 gxf_write_padding(pb, 4 - size % 4);
00138 size = url_ftell(pb) - pos;
00139 }
00140 curpos = url_ftell(pb);
00141 url_fseek(pb, pos + 6, SEEK_SET);
00142 put_be32(pb, size);
00143 url_fseek(pb, curpos, SEEK_SET);
00144 return curpos - pos;
00145 }
00146
00147 static int64_t updateSize(ByteIOContext *pb, int64_t pos)
00148 {
00149 int64_t curpos;
00150
00151 curpos = url_ftell(pb);
00152 url_fseek(pb, pos, SEEK_SET);
00153 put_be16(pb, curpos - pos - 2);
00154 url_fseek(pb, curpos, SEEK_SET);
00155 return curpos - pos;
00156 }
00157
00158 static void gxf_write_packet_header(ByteIOContext *pb, GXFPktType type)
00159 {
00160 put_be32(pb, 0);
00161 put_byte(pb, 1);
00162 put_byte(pb, type);
00163 put_be32(pb, 0);
00164 put_be32(pb, 0);
00165 put_byte(pb, 0xE1);
00166 put_byte(pb, 0xE2);
00167 }
00168
00169 static int gxf_write_mpeg_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx)
00170 {
00171 char buffer[1024];
00172 int size, starting_line;
00173
00174 if (ctx->iframes) {
00175 ctx->p_per_gop = ctx->pframes / ctx->iframes;
00176 if (ctx->pframes % ctx->iframes)
00177 ctx->p_per_gop++;
00178 if (ctx->pframes) {
00179 ctx->b_per_i_or_p = ctx->bframes / ctx->pframes;
00180 if (ctx->bframes % ctx->pframes)
00181 ctx->b_per_i_or_p++;
00182 }
00183 if (ctx->p_per_gop > 9)
00184 ctx->p_per_gop = 9;
00185 if (ctx->b_per_i_or_p > 9)
00186 ctx->b_per_i_or_p = 9;
00187 }
00188 if (ctx->codec->height == 512 || ctx->codec->height == 608)
00189 starting_line = 7;
00190 else if (ctx->codec->height == 480)
00191 starting_line = 20;
00192 else
00193 starting_line = 23;
00194
00195 size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
00196 "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n",
00197 (float)ctx->codec->bit_rate, ctx->p_per_gop, ctx->b_per_i_or_p,
00198 ctx->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, ctx->first_gop_closed == 1,
00199 starting_line, ctx->codec->height / 16);
00200 put_byte(pb, TRACK_MPG_AUX);
00201 put_byte(pb, size + 1);
00202 put_buffer(pb, (uint8_t *)buffer, size + 1);
00203 return size + 3;
00204 }
00205
00206 static int gxf_write_timecode_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx)
00207 {
00208
00209 put_byte(pb, 0);
00210 put_byte(pb, 0);
00211 put_byte(pb, 0);
00212 put_byte(pb, 0);
00213
00214 put_be32(pb, 0);
00215 return 8;
00216 }
00217
00218 static int gxf_write_track_description(ByteIOContext *pb, GXFStreamContext *stream)
00219 {
00220 int64_t pos;
00221
00222
00223 put_byte(pb, stream->media_type + 0x80);
00224 put_byte(pb, stream->index + 0xC0);
00225
00226 pos = url_ftell(pb);
00227 put_be16(pb, 0);
00228
00229
00230 put_byte(pb, TRACK_NAME);
00231 put_byte(pb, strlen(ES_NAME_PATTERN) + 3);
00232 put_tag(pb, ES_NAME_PATTERN);
00233 put_be16(pb, stream->media_info);
00234 put_byte(pb, 0);
00235
00236 if (stream->codec->codec_id != CODEC_ID_MPEG2VIDEO) {
00237
00238 put_byte(pb, TRACK_AUX);
00239 put_byte(pb, 8);
00240 if (stream->codec->codec_id == CODEC_ID_NONE)
00241 gxf_write_timecode_auxiliary(pb, stream);
00242 else
00243 put_le64(pb, 0);
00244 }
00245
00246
00247 put_byte(pb, TRACK_VER);
00248 put_byte(pb, 4);
00249 put_be32(pb, 0);
00250
00251 if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO)
00252 gxf_write_mpeg_auxiliary(pb, stream);
00253
00254
00255 put_byte(pb, TRACK_FPS);
00256 put_byte(pb, 4);
00257 put_be32(pb, stream->frame_rate_index);
00258
00259
00260 put_byte(pb, TRACK_LINES);
00261 put_byte(pb, 4);
00262 put_be32(pb, stream->lines_index);
00263
00264
00265 put_byte(pb, TRACK_FPF);
00266 put_byte(pb, 4);
00267 put_be32(pb, stream->fields);
00268
00269 return updateSize(pb, pos);
00270 }
00271
00272 static int gxf_write_material_data_section(ByteIOContext *pb, GXFContext *ctx)
00273 {
00274 int64_t pos;
00275 const char *filename = strrchr(ctx->fc->filename, '/');
00276
00277 pos = url_ftell(pb);
00278 put_be16(pb, 0);
00279
00280
00281 if (filename)
00282 filename++;
00283 else
00284 filename = ctx->fc->filename;
00285 put_byte(pb, MAT_NAME);
00286 put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1);
00287 put_tag(pb, SERVER_PATH);
00288 put_tag(pb, filename);
00289 put_byte(pb, 0);
00290
00291
00292 put_byte(pb, MAT_FIRST_FIELD);
00293 put_byte(pb, 4);
00294 put_be32(pb, 0);
00295
00296
00297 put_byte(pb, MAT_LAST_FIELD);
00298 put_byte(pb, 4);
00299 put_be32(pb, ctx->nb_fields);
00300
00301
00302 put_byte(pb, MAT_MARK_IN);
00303 put_byte(pb, 4);
00304 put_be32(pb, 0);
00305
00306 put_byte(pb, MAT_MARK_OUT);
00307 put_byte(pb, 4);
00308 put_be32(pb, ctx->nb_fields);
00309
00310
00311 put_byte(pb, MAT_SIZE);
00312 put_byte(pb, 4);
00313 put_be32(pb, url_fsize(pb) / 1024);
00314
00315 return updateSize(pb, pos);
00316 }
00317
00318 static int gxf_write_track_description_section(ByteIOContext *pb, GXFContext *ctx)
00319 {
00320 int64_t pos;
00321 int i;
00322
00323 pos = url_ftell(pb);
00324 put_be16(pb, 0);
00325 for (i = 0; i < ctx->fc->nb_streams; ++i)
00326 gxf_write_track_description(pb, ctx->fc->streams[i]->priv_data);
00327 return updateSize(pb, pos);
00328 }
00329
00330 static int gxf_write_map_packet(ByteIOContext *pb, GXFContext *ctx)
00331 {
00332 int64_t pos = url_ftell(pb);
00333
00334 gxf_write_packet_header(pb, PKT_MAP);
00335
00336
00337 put_byte(pb, 0xE0);
00338 put_byte(pb, 0xFF);
00339
00340 gxf_write_material_data_section(pb, ctx);
00341 gxf_write_track_description_section(pb, ctx);
00342
00343 return updatePacketSize(pb, pos);
00344 }
00345
00346 #if 0
00347 static int gxf_write_flt_packet(ByteIOContext *pb, GXFContext *ctx)
00348 {
00349 int64_t pos = url_ftell(pb);
00350 int i;
00351
00352 gxf_write_packet_header(pb, PKT_FLT);
00353
00354 put_le32(pb, 1000);
00355 put_le32(pb, 0);
00356
00357 for (i = 0; i < 1000; ++i) {
00358 put_le32(pb, 0);
00359 }
00360 return updatePacketSize(pb, pos);
00361 }
00362 #endif
00363
00364 static int gxf_write_umf_material_description(ByteIOContext *pb, GXFContext *ctx)
00365 {
00366
00367 uint32_t timecode =
00368 ctx->nb_fields / (ctx->sample_rate * 3600) % 24 << 24 |
00369 ctx->nb_fields / (ctx->sample_rate * 60) % 60 << 16 |
00370 ctx->nb_fields / ctx->sample_rate % 60 << 8 |
00371 ctx->nb_fields % ctx->sample_rate;
00372
00373 put_le32(pb, ctx->flags);
00374 put_le32(pb, ctx->nb_fields);
00375 put_le32(pb, ctx->nb_fields);
00376 put_le32(pb, 0);
00377 put_le32(pb, ctx->nb_fields);
00378 put_le32(pb, 0);
00379 put_le32(pb, timecode);
00380 put_le64(pb, ctx->fc->timestamp);
00381 put_le64(pb, ctx->fc->timestamp);
00382 put_le16(pb, 0);
00383 put_le16(pb, 0);
00384 put_le16(pb, ctx->audio_tracks);
00385 put_le16(pb, 0);
00386 put_le16(pb, 0);
00387 put_le16(pb, ctx->mpeg_tracks);
00388 return 48;
00389 }
00390
00391 static int gxf_write_umf_payload(ByteIOContext *pb, GXFContext *ctx)
00392 {
00393 put_le32(pb, ctx->umf_length);
00394 put_le32(pb, 3);
00395 put_le32(pb, ctx->fc->nb_streams);
00396 put_le32(pb, ctx->umf_track_offset);
00397 put_le32(pb, ctx->umf_track_size);
00398 put_le32(pb, ctx->fc->nb_streams);
00399 put_le32(pb, ctx->umf_media_offset);
00400 put_le32(pb, ctx->umf_media_size);
00401 put_le32(pb, ctx->umf_user_data_offset);
00402 put_le32(pb, ctx->umf_user_data_size);
00403 put_le32(pb, 0);
00404 put_le32(pb, 0);
00405 return 48;
00406 }
00407
00408 static int gxf_write_umf_track_description(ByteIOContext *pb, GXFContext *ctx)
00409 {
00410 int64_t pos = url_ftell(pb);
00411 int tracks[255]={0};
00412 int i;
00413
00414 ctx->umf_track_offset = pos - ctx->umf_start_offset;
00415 for (i = 0; i < ctx->fc->nb_streams; ++i) {
00416 AVStream *st = ctx->fc->streams[i];
00417 GXFStreamContext *sc = st->priv_data;
00418 int id = 0;
00419
00420 switch (st->codec->codec_id) {
00421 case CODEC_ID_MPEG1VIDEO: id= 'L'; break;
00422 case CODEC_ID_MPEG2VIDEO: id= 'M'; break;
00423 case CODEC_ID_PCM_S16LE: id= 'A'; break;
00424 case CODEC_ID_DVVIDEO: id= sc->track_type == 6 ? 'E' : 'D'; break;
00425 case CODEC_ID_MJPEG: id= 'V'; break;
00426 default: break;
00427 }
00428 sc->media_info= id << 8;
00429
00430 sc->media_info |= '0' + (tracks[id]++);
00431 put_le16(pb, sc->media_info);
00432 put_le16(pb, 1);
00433 }
00434 return url_ftell(pb) - pos;
00435 }
00436
00437 static int gxf_write_umf_media_mpeg(ByteIOContext *pb, GXFStreamContext *stream)
00438 {
00439 if (stream->codec->pix_fmt == PIX_FMT_YUV422P)
00440 put_le32(pb, 2);
00441 else
00442 put_le32(pb, 1);
00443 put_le32(pb, stream->first_gop_closed == 1);
00444 put_le32(pb, 3);
00445 put_le32(pb, 1);
00446 put_le32(pb, stream->p_per_gop);
00447 put_le32(pb, stream->b_per_i_or_p);
00448 if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO)
00449 put_le32(pb, 2);
00450 else if (stream->codec->codec_id == CODEC_ID_MPEG1VIDEO)
00451 put_le32(pb, 1);
00452 else
00453 put_le32(pb, 0);
00454 put_le32(pb, 0);
00455 return 32;
00456 }
00457
00458 static int gxf_write_umf_media_timecode(ByteIOContext *pb, GXFStreamContext *track)
00459 {
00460
00461 put_be32(pb, 0);
00462 put_be32(pb, 0);
00463 put_be32(pb, 0);
00464 put_be32(pb, 0);
00465 put_be32(pb, 0);
00466 put_be32(pb, 0);
00467 put_be32(pb, 0);
00468 put_be32(pb, 0);
00469 return 32;
00470 }
00471
00472 static int gxf_write_umf_media_dv(ByteIOContext *pb, GXFStreamContext *track)
00473 {
00474 int i;
00475
00476 for (i = 0; i < 8; i++) {
00477 put_be32(pb, 0);
00478 }
00479 return 32;
00480 }
00481
00482 static int gxf_write_umf_media_audio(ByteIOContext *pb, GXFStreamContext *track)
00483 {
00484 put_le64(pb, av_dbl2int(1));
00485 put_le64(pb, av_dbl2int(1));
00486 put_le32(pb, 0);
00487 put_le32(pb, 0);
00488 put_le32(pb, 0);
00489 put_le32(pb, 0);
00490 return 32;
00491 }
00492
00493 #if 0
00494 static int gxf_write_umf_media_mjpeg(ByteIOContext *pb, GXFStreamContext *track)
00495 {
00496 put_be64(pb, 0);
00497 put_be64(pb, 0);
00498 put_be64(pb, 0);
00499 put_be64(pb, 0);
00500 return 32;
00501 }
00502 #endif
00503
00504 static int gxf_write_umf_media_description(ByteIOContext *pb, GXFContext *ctx)
00505 {
00506 int64_t pos;
00507 int i;
00508
00509 pos = url_ftell(pb);
00510 ctx->umf_media_offset = pos - ctx->umf_start_offset;
00511 for (i = 0; i < ctx->fc->nb_streams; ++i) {
00512 GXFStreamContext *sc = ctx->fc->streams[i]->priv_data;
00513 char buffer[88];
00514 int64_t startpos, curpos;
00515 int path_size = strlen(ES_NAME_PATTERN);
00516
00517 memset(buffer, 0, 88);
00518 startpos = url_ftell(pb);
00519 put_le16(pb, 0);
00520 put_le16(pb, sc->media_info);
00521 put_le16(pb, 0);
00522 put_le16(pb, 0);
00523 put_le32(pb, ctx->nb_fields);
00524 put_le32(pb, 0);
00525 put_le32(pb, 0);
00526 put_le32(pb, ctx->nb_fields);
00527 strncpy(buffer, ES_NAME_PATTERN, path_size);
00528 put_buffer(pb, (uint8_t *)buffer, path_size);
00529 put_be16(pb, sc->media_info);
00530 put_buffer(pb, (uint8_t *)buffer + path_size + 2, 88 - path_size - 2);
00531 put_le32(pb, sc->track_type);
00532 put_le32(pb, sc->sample_rate);
00533 put_le32(pb, sc->sample_size);
00534 put_le32(pb, 0);
00535 switch (sc->codec->codec_id) {
00536 case CODEC_ID_MPEG2VIDEO:
00537 gxf_write_umf_media_mpeg(pb, sc);
00538 break;
00539 case CODEC_ID_PCM_S16LE:
00540 gxf_write_umf_media_audio(pb, sc);
00541 break;
00542 case CODEC_ID_DVVIDEO:
00543 gxf_write_umf_media_dv(pb, sc);
00544 break;
00545 default:
00546 gxf_write_umf_media_timecode(pb, sc);
00547 }
00548 curpos = url_ftell(pb);
00549 url_fseek(pb, startpos, SEEK_SET);
00550 put_le16(pb, curpos - startpos);
00551 url_fseek(pb, curpos, SEEK_SET);
00552 }
00553 return url_ftell(pb) - pos;
00554 }
00555
00556 static int gxf_write_umf_user_data(ByteIOContext *pb, GXFContext *ctx)
00557 {
00558 int64_t pos = url_ftell(pb);
00559 ctx->umf_user_data_offset = pos - ctx->umf_start_offset;
00560 put_le32(pb, 20);
00561 put_le32(pb, 0);
00562 put_le16(pb, 0);
00563 put_le16(pb, 0);
00564 put_le32(pb, 0);
00565 put_byte(pb, 0);
00566 put_byte(pb, 0);
00567 put_byte(pb, 0);
00568 put_byte(pb, 0);
00569 return 20;
00570 }
00571
00572 static int gxf_write_umf_packet(ByteIOContext *pb, GXFContext *ctx)
00573 {
00574 int64_t pos = url_ftell(pb);
00575
00576 gxf_write_packet_header(pb, PKT_UMF);
00577
00578
00579 put_byte(pb, 3);
00580 put_be32(pb, ctx->umf_length);
00581
00582 ctx->umf_start_offset = url_ftell(pb);
00583 gxf_write_umf_payload(pb, ctx);
00584 gxf_write_umf_material_description(pb, ctx);
00585 ctx->umf_track_size = gxf_write_umf_track_description(pb, ctx);
00586 ctx->umf_media_size = gxf_write_umf_media_description(pb, ctx);
00587 ctx->umf_user_data_size = gxf_write_umf_user_data(pb, ctx);
00588 ctx->umf_length = url_ftell(pb) - ctx->umf_start_offset;
00589 return updatePacketSize(pb, pos);
00590 }
00591
00592 #define GXF_NODELAY -5000
00593
00594 static const int GXF_samples_per_frame[] = { 32768, 0 };
00595
00596 static int gxf_write_header(AVFormatContext *s)
00597 {
00598 ByteIOContext *pb = s->pb;
00599 GXFContext *gxf = s->priv_data;
00600 int i;
00601
00602 gxf->fc = s;
00603 gxf->flags |= 0x00080000;
00604 for (i = 0; i < s->nb_streams; ++i) {
00605 AVStream *st = s->streams[i];
00606 GXFStreamContext *sc = av_mallocz(sizeof(*sc));
00607 if (!sc)
00608 return AVERROR(ENOMEM);
00609 st->priv_data = sc;
00610
00611 sc->codec = st->codec;
00612 sc->index = i;
00613 sc->media_type = codec_get_tag(gxf_media_types, sc->codec->codec_id);
00614 if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
00615 if (st->codec->codec_id != CODEC_ID_PCM_S16LE) {
00616 av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n");
00617 return -1;
00618 }
00619 if (st->codec->sample_rate != 48000) {
00620 av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n");
00621 return -1;
00622 }
00623 if (st->codec->channels != 1) {
00624 av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
00625 return -1;
00626 }
00627 sc->track_type = 2;
00628 sc->sample_rate = st->codec->sample_rate;
00629 av_set_pts_info(st, 64, 1, sc->sample_rate);
00630 sc->sample_size = 16;
00631 sc->frame_rate_index = -2;
00632 sc->lines_index = -2;
00633 sc->fields = -2;
00634 gxf->audio_tracks++;
00635 gxf->flags |= 0x04000000;
00636 } else if (sc->codec->codec_type == CODEC_TYPE_VIDEO) {
00637
00638 if (sc->codec->height == 480 || sc->codec->height == 512) {
00639 sc->frame_rate_index = 5;
00640 sc->sample_rate = 60;
00641 gxf->flags |= 0x00000080;
00642 } else {
00643 sc->frame_rate_index = 6;
00644 sc->media_type++;
00645 sc->sample_rate = 50;
00646 gxf->flags |= 0x00000040;
00647 }
00648 gxf->sample_rate = sc->sample_rate;
00649 av_set_pts_info(st, 64, 1, st->codec->time_base.den);
00650 sc->dts_delay = GXF_NODELAY;
00651 if (gxf_find_lines_index(sc) < 0)
00652 sc->lines_index = -1;
00653 sc->sample_size = st->codec->bit_rate;
00654 sc->fields = 2;
00655 switch (sc->codec->codec_id) {
00656 case CODEC_ID_MPEG2VIDEO:
00657 sc->first_gop_closed = -1;
00658 sc->track_type = 4;
00659 gxf->mpeg_tracks++;
00660 gxf->flags |= 0x00008000;
00661 break;
00662 case CODEC_ID_DVVIDEO:
00663 if (sc->codec->pix_fmt == PIX_FMT_YUV422P) {
00664 sc->media_type += 2;
00665 sc->track_type = 6;
00666 gxf->flags |= 0x00002000;
00667 } else {
00668 sc->track_type = 5;
00669 gxf->flags |= 0x00001000;
00670 }
00671 break;
00672 default:
00673 av_log(s, AV_LOG_ERROR, "video codec not supported\n");
00674 return -1;
00675 }
00676 }
00677 }
00678
00679 if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
00680 return -1;
00681
00682 gxf_write_map_packet(pb, gxf);
00683
00684 gxf_write_umf_packet(pb, gxf);
00685 put_flush_packet(pb);
00686 return 0;
00687 }
00688
00689 static int gxf_write_eos_packet(ByteIOContext *pb, GXFContext *ctx)
00690 {
00691 int64_t pos = url_ftell(pb);
00692
00693 gxf_write_packet_header(pb, PKT_EOS);
00694 return updatePacketSize(pb, pos);
00695 }
00696
00697 static int gxf_write_trailer(AVFormatContext *s)
00698 {
00699 ByteIOContext *pb = s->pb;
00700 GXFContext *gxf = s->priv_data;
00701 int64_t end;
00702
00703 ff_audio_interleave_close(s);
00704
00705 gxf_write_eos_packet(pb, gxf);
00706 end = url_ftell(pb);
00707 url_fseek(pb, 0, SEEK_SET);
00708
00709 gxf_write_map_packet(pb, gxf);
00710
00711 gxf_write_umf_packet(pb, gxf);
00712 url_fseek(pb, end, SEEK_SET);
00713 return 0;
00714 }
00715
00716 static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
00717 {
00718 uint32_t c=-1;
00719 int i;
00720 for(i=0; i<size-4 && c!=0x100; i++){
00721 c = (c<<8) + buf[i];
00722 if(c == 0x1B8 && sc->first_gop_closed == -1)
00723 sc->first_gop_closed= (buf[i+4]>>6)&1;
00724 }
00725 return (buf[i+1]>>3)&7;
00726 }
00727
00728 static int gxf_write_media_preamble(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt, int size)
00729 {
00730 GXFStreamContext *sc = ctx->fc->streams[pkt->stream_index]->priv_data;
00731 unsigned field_nb;
00732
00733
00734
00735 if (sc->codec->codec_type == CODEC_TYPE_VIDEO) {
00736 field_nb = ctx->nb_fields;
00737 } else {
00738 field_nb = av_rescale_rnd(pkt->dts, ctx->sample_rate, sc->codec->time_base.den, AV_ROUND_UP);
00739 }
00740
00741 put_byte(pb, sc->media_type);
00742 put_byte(pb, sc->index);
00743 put_be32(pb, field_nb);
00744 if (sc->codec->codec_type == CODEC_TYPE_AUDIO) {
00745 put_be16(pb, 0);
00746 put_be16(pb, size / 2);
00747 } else if (sc->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
00748 int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size);
00749 if (frame_type == FF_I_TYPE) {
00750 put_byte(pb, 0x0d);
00751 sc->iframes++;
00752 } else if (frame_type == FF_B_TYPE) {
00753 put_byte(pb, 0x0f);
00754 sc->bframes++;
00755 } else {
00756 put_byte(pb, 0x0e);
00757 sc->pframes++;
00758 }
00759 put_be24(pb, size);
00760 } else if (sc->codec->codec_id == CODEC_ID_DVVIDEO) {
00761 put_byte(pb, size / 4096);
00762 put_be24(pb, 0);
00763 } else
00764 put_be32(pb, size);
00765 put_be32(pb, field_nb);
00766 put_byte(pb, 1);
00767 put_byte(pb, 0);
00768 return 16;
00769 }
00770
00771 static int gxf_write_media_packet(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt)
00772 {
00773 GXFStreamContext *sc = ctx->fc->streams[pkt->stream_index]->priv_data;
00774 int64_t pos = url_ftell(pb);
00775 int padding = 0;
00776
00777 gxf_write_packet_header(pb, PKT_MEDIA);
00778 if (sc->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4)
00779 padding = 4 - pkt->size % 4;
00780 else if (sc->codec->codec_type == CODEC_TYPE_AUDIO)
00781 padding = GXF_AUDIO_PACKET_SIZE - pkt->size;
00782 gxf_write_media_preamble(pb, ctx, pkt, pkt->size + padding);
00783 put_buffer(pb, pkt->data, pkt->size);
00784 gxf_write_padding(pb, padding);
00785
00786 if (sc->codec->codec_type == CODEC_TYPE_VIDEO)
00787 ctx->nb_fields += 2;
00788
00789 return updatePacketSize(pb, pos);
00790 }
00791
00792 static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
00793 {
00794 GXFContext *gxf = s->priv_data;
00795
00796 gxf_write_media_packet(s->pb, gxf, pkt);
00797 put_flush_packet(s->pb);
00798 return 0;
00799 }
00800
00801 static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
00802 {
00803 return ff_audio_rechunk_interleave(s, out, pkt, flush,
00804 av_interleave_packet_per_dts, ff_interleave_compare_dts);
00805 }
00806
00807 AVOutputFormat gxf_muxer = {
00808 "gxf",
00809 NULL_IF_CONFIG_SMALL("GXF format"),
00810 NULL,
00811 "gxf",
00812 sizeof(GXFContext),
00813 CODEC_ID_PCM_S16LE,
00814 CODEC_ID_MPEG2VIDEO,
00815 gxf_write_header,
00816 gxf_write_packet,
00817 gxf_write_trailer,
00818 0,
00819 NULL,
00820 gxf_interleave_packet,
00821 };