*
* This file is part of FFmpeg.
*
- * FFmpeg is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with FFmpeg; if not, write to the Free Software
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/fifo.h"
#include "avformat.h"
#include "gxf.h"
#include "riff.h"
-#include "fifo.h"
#define GXF_AUDIO_PACKET_SIZE 65536
return -1;
}
-static void gxf_write_padding(ByteIOContext *pb, offset_t to_pad)
+static void gxf_write_padding(ByteIOContext *pb, int64_t to_pad)
{
for (; to_pad > 0; to_pad--) {
put_byte(pb, 0);
}
}
-static offset_t updatePacketSize(ByteIOContext *pb, offset_t pos)
+static int64_t updatePacketSize(ByteIOContext *pb, int64_t pos)
{
- offset_t curpos;
+ int64_t curpos;
int size;
size = url_ftell(pb) - pos;
return curpos - pos;
}
-static offset_t updateSize(ByteIOContext *pb, offset_t pos)
+static int64_t updateSize(ByteIOContext *pb, int64_t pos)
{
- offset_t curpos;
+ int64_t curpos;
curpos = url_ftell(pb);
url_fseek(pb, pos, SEEK_SET);
(float)ctx->codec->bit_rate, ctx->p_per_gop, ctx->b_per_gop,
ctx->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, ctx->first_gop_closed == 1,
ctx->codec->height / 16);
- put_byte(pb, 0x4F);
+ put_byte(pb, TRACK_MPG_AUX);
put_byte(pb, size + 1);
put_buffer(pb, (uint8_t *)buffer, size + 1);
return size + 3;
static int gxf_write_track_description(ByteIOContext *pb, GXFStreamContext *stream)
{
- offset_t pos;
+ int64_t pos;
/* track description section */
put_byte(pb, stream->media_type + 0x80);
put_be16(pb, 0); /* size */
/* media file name */
- put_byte(pb, 0x4C);
+ put_byte(pb, TRACK_NAME);
put_byte(pb, strlen(ES_NAME_PATTERN) + 3);
put_tag(pb, ES_NAME_PATTERN);
put_be16(pb, stream->media_info);
if (stream->codec->codec_id != CODEC_ID_MPEG2VIDEO) {
/* auxiliary information */
- put_byte(pb, 0x4D);
+ put_byte(pb, TRACK_AUX);
put_byte(pb, 8);
if (stream->codec->codec_id == CODEC_ID_NONE)
gxf_write_timecode_auxiliary(pb, stream);
}
/* file system version */
- put_byte(pb, 0x4E);
+ put_byte(pb, TRACK_VER);
put_byte(pb, 4);
put_be32(pb, 0);
gxf_write_mpeg_auxiliary(pb, stream);
/* frame rate */
- put_byte(pb, 0x50);
+ put_byte(pb, TRACK_FPS);
put_byte(pb, 4);
put_be32(pb, stream->frame_rate_index);
/* lines per frame */
- put_byte(pb, 0x51);
+ put_byte(pb, TRACK_LINES);
put_byte(pb, 4);
put_be32(pb, stream->lines_index);
/* fields per frame */
- put_byte(pb, 0x52);
+ put_byte(pb, TRACK_FPF);
put_byte(pb, 4);
put_be32(pb, stream->fields);
static int gxf_write_material_data_section(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos;
+ int64_t pos;
const char *filename = strrchr(ctx->fc->filename, '/');
pos = url_ftell(pb);
filename++;
else
filename = ctx->fc->filename;
- put_byte(pb, 0x40);
+ put_byte(pb, MAT_NAME);
put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1);
put_tag(pb, SERVER_PATH);
put_tag(pb, filename);
put_byte(pb, 0);
/* first field */
- put_byte(pb, 0x41);
+ put_byte(pb, MAT_FIRST_FIELD);
put_byte(pb, 4);
put_be32(pb, 0);
/* last field */
- put_byte(pb, 0x42);
+ put_byte(pb, MAT_LAST_FIELD);
put_byte(pb, 4);
put_be32(pb, ctx->nb_frames);
/* reserved */
- put_byte(pb, 0x43);
+ put_byte(pb, MAT_MARK_IN);
put_byte(pb, 4);
put_be32(pb, 0);
- put_byte(pb, 0x44);
+ put_byte(pb, MAT_MARK_OUT);
put_byte(pb, 4);
put_be32(pb, ctx->nb_frames);
/* estimated size */
- put_byte(pb, 0x45);
+ put_byte(pb, MAT_SIZE);
put_byte(pb, 4);
put_be32(pb, url_fsize(pb) / 1024);
static int gxf_write_track_description_section(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos;
+ int64_t pos;
int i;
pos = url_ftell(pb);
static int gxf_write_map_packet(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos = url_ftell(pb);
+ int64_t pos = url_ftell(pb);
gxf_write_packet_header(pb, PKT_MAP);
#if 0
static int gxf_write_flt_packet(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos = url_ftell(pb);
+ int64_t pos = url_ftell(pb);
int i;
gxf_write_packet_header(pb, PKT_FLT);
static int gxf_write_umf_track_description(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos = url_ftell(pb);
+ int64_t pos = url_ftell(pb);
int tracks[255]={0};
int i;
static int gxf_write_umf_media_description(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos;
+ int64_t pos;
int i;
pos = url_ftell(pb);
for (i = 0; i < ctx->fc->nb_streams; ++i) {
GXFStreamContext *sc = &ctx->streams[i];
char buffer[88];
- offset_t startpos, curpos;
+ int64_t startpos, curpos;
int path_size = strlen(ES_NAME_PATTERN);
memset(buffer, 0, 88);
static int gxf_write_umf_user_data(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos = url_ftell(pb);
+ int64_t pos = url_ftell(pb);
ctx->umf_user_data_offset = pos - ctx->umf_start_offset;
put_le32(pb, 20);
put_le32(pb, 0);
static int gxf_write_umf_packet(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos = url_ftell(pb);
+ int64_t pos = url_ftell(pb);
gxf_write_packet_header(pb, PKT_UMF);
return updatePacketSize(pb, pos);
}
+#define GXF_NODELAY -5000
+
static int gxf_write_header(AVFormatContext *s)
{
- ByteIOContext *pb = &s->pb;
+ ByteIOContext *pb = s->pb;
GXFContext *gxf = s->priv_data;
int i;
gxf->flags |= 0x00000040;
}
gxf->sample_rate = sc->sample_rate;
- av_set_pts_info(st, 64, 1, sc->sample_rate);
+ av_set_pts_info(st, 64, 1, st->codec->time_base.den);
+ sc->dts_delay = GXF_NODELAY;
if (gxf_find_lines_index(sc) < 0)
sc->lines_index = -1;
sc->sample_size = st->codec->bit_rate;
static int gxf_write_eos_packet(ByteIOContext *pb, GXFContext *ctx)
{
- offset_t pos = url_ftell(pb);
+ int64_t pos = url_ftell(pb);
gxf_write_packet_header(pb, PKT_EOS);
return updatePacketSize(pb, pos);
static int gxf_write_trailer(AVFormatContext *s)
{
- ByteIOContext *pb = &s->pb;
+ ByteIOContext *pb = s->pb;
GXFContext *gxf = s->priv_data;
- offset_t end;
+ int64_t end;
int i;
for (i = 0; i < s->nb_streams; ++i) {
if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
av_fifo_free(&gxf->streams[i].audio_buffer);
- }
- if (s->streams[i]->codec->frame_number > gxf->nb_frames)
+ } else if (s->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
gxf->nb_frames = 2 * s->streams[i]->codec->frame_number;
+ }
}
gxf_write_eos_packet(pb, gxf);
static int gxf_write_media_preamble(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt, int size)
{
GXFStreamContext *sc = &ctx->streams[pkt->stream_index];
- int64_t dts = av_rescale(pkt->dts, ctx->sample_rate, sc->sample_rate);
+ int64_t dts = av_rescale_rnd(pkt->dts, ctx->sample_rate, sc->codec->time_base.den, AV_ROUND_UP);
put_byte(pb, sc->media_type);
put_byte(pb, sc->index);
static int gxf_write_media_packet(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt)
{
GXFStreamContext *sc = &ctx->streams[pkt->stream_index];
- offset_t pos = url_ftell(pb);
+ int64_t pos = url_ftell(pb);
int padding = 0;
gxf_write_packet_header(pb, PKT_MEDIA);
{
GXFContext *gxf = s->priv_data;
- gxf_write_media_packet(&s->pb, gxf, pkt);
- put_flush_packet(&s->pb);
+ gxf_write_media_packet(s->pb, gxf, pkt);
+ put_flush_packet(s->pb);
return 0;
}
GXFStreamContext *sc = &gxf->streams[i];
if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
if (pkt && pkt->stream_index == i) {
- av_fifo_write(&sc->audio_buffer, pkt->data, pkt->size);
+ av_fifo_generic_write(&sc->audio_buffer, pkt->data, pkt->size, NULL);
pkt = NULL;
}
if (flush || av_fifo_size(&sc->audio_buffer) >= GXF_AUDIO_PACKET_SIZE) {
break; /* add pkt right now into list */
}
}
- } else if (pkt) {
- /* adjust dts if negative */
- if (pkt->dts < 0 && !sc->dts_delay) {
- /* XXX: rescale if codec time base is different from stream time base */
- sc->dts_delay = av_rescale_q(pkt->dts, st->codec->time_base, st->time_base);
- pkt->dts = sc->dts_delay; /* set to 0 */
- }
+ } else if (pkt && pkt->stream_index == i) {
+ if (sc->dts_delay == GXF_NODELAY) /* adjust dts if needed */
+ sc->dts_delay = pkt->dts;
pkt->dts -= sc->dts_delay;
}
}
AVOutputFormat gxf_muxer = {
"gxf",
- "GXF format",
+ NULL_IF_CONFIG_SMALL("GXF format"),
NULL,
"gxf",
sizeof(GXFContext),