*
* 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 this program; 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
{ 720, 6 },
};
-static const CodecTag gxf_media_types[] = {
+static const AVCodecTag gxf_media_types[] = {
{ CODEC_ID_MJPEG , 3 }, /* NTSC */
{ CODEC_ID_MJPEG , 4 }, /* PAL */
{ CODEC_ID_PCM_S24LE , 9 },
(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;
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);
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);
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_trailer(AVFormatContext *s)
{
- ByteIOContext *pb = &s->pb;
+ ByteIOContext *pb = s->pb;
GXFContext *gxf = s->priv_data;
offset_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);
{
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;
}
}