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