* added some missing bits and removed obsolete files in ffmpeg-0.6

* replaced .. with $(DOTDOT) in Jamfiles
* added __STDC_CONSTANT_MACROS define for C++ files (required for UINT64_C)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39537 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2010-11-20 15:59:05 +00:00
parent f3ed9d3a45
commit cf85a555b0
18 changed files with 138 additions and 1864 deletions

View File

@ -9,6 +9,8 @@ SubDirHdrs [ FDirName $(SUBDIR) libavformat ] ;
SubDirHdrs [ FDirName $(SUBDIR) libavutil ] ;
SubDirHdrs [ FDirName $(SUBDIR) libswscale ] ;
SubDirC++Flags -D__STDC_CONSTANT_MACROS ;
Addon ffmpeg :
AVCodecDecoder.cpp
AVCodecEncoder.cpp

View File

@ -1,13 +1,13 @@
SubDir HAIKU_TOP src add-ons media plugins ffmpeg libavcodec ;
SubDirHdrs [ FDirName $(SUBDIR) .. ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(TARGET_ARCH) ] ;
SubDirHdrs [ FDirName $(SUBDIR) .. libavutil ] ;
SubDirHdrs [ FDirName $(SUBDIR) .. libswscale ] ;
SubDirSysHdrs [ FDirName $(SUBDIR) .. libogg include ] ;
SubDirSysHdrs [ FDirName $(SUBDIR) .. libtheora include ] ;
SubDirSysHdrs [ FDirName $(SUBDIR) .. libvorbis include ] ;
SubDirSysHdrs [ FDirName $(SUBDIR) .. libspeex include ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) libavutil ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) libswscale ] ;
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) libogg include ] ;
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) libtheora include ] ;
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) libvorbis include ] ;
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) libspeex include ] ;
UseLibraryHeaders zlib ;

View File

@ -19,7 +19,6 @@ StaticLibrary libavformat.a :
4xm.c
adtsenc.c
aea.c
aiff.c
aiffdec.c
aiffenc.c
allformats.c
@ -148,9 +147,6 @@ StaticLibrary libavformat.a :
rmenc.c
rpl.c
rtp.c
rtp_aac.c
rtp_h264.c
rtp_mpv.c
rtpdec.c
rtpdec_amr.c
rtpdec_asf.c

View File

@ -1,467 +0,0 @@
/*
* AIFF/AIFF-C muxer and demuxer
* Copyright (c) 2006 Patrick Guimond
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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/intfloat_readwrite.h"
#include "avformat.h"
#include "raw.h"
#include "riff.h"
static const AVCodecTag codec_aiff_tags[] = {
{ CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') },
{ CODEC_ID_PCM_S8, MKTAG('N','O','N','E') },
{ CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') },
{ CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') },
{ CODEC_ID_PCM_F32BE, MKTAG('f','l','3','2') },
{ CODEC_ID_PCM_F64BE, MKTAG('f','l','6','4') },
{ CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') },
{ CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') },
{ CODEC_ID_MACE3, MKTAG('M','A','C','3') },
{ CODEC_ID_MACE6, MKTAG('M','A','C','6') },
{ CODEC_ID_GSM, MKTAG('G','S','M',' ') },
{ CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') },
{ CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') },
{ CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
{ CODEC_ID_QDM2, MKTAG('Q','D','M','2') },
{ 0, 0 },
};
#define AIFF 0
#define AIFF_C_VERSION1 0xA2805140
static enum CodecID aiff_codec_get_id(int bps)
{
if (bps <= 8)
return CODEC_ID_PCM_S8;
if (bps <= 16)
return CODEC_ID_PCM_S16BE;
if (bps <= 24)
return CODEC_ID_PCM_S24BE;
if (bps <= 32)
return CODEC_ID_PCM_S32BE;
/* bigger than 32 isn't allowed */
return CODEC_ID_NONE;
}
/* returns the size of the found tag */
static int get_tag(ByteIOContext *pb, uint32_t * tag)
{
int size;
if (url_feof(pb))
return AVERROR(EIO);
*tag = get_le32(pb);
size = get_be32(pb);
if (size < 0)
size = 0x7fffffff;
return size;
}
/* Metadata string read */
static void get_meta(AVFormatContext *s, const char *key, int size)
{
uint8_t str[1024];
int res = get_buffer(s->pb, str, FFMIN(sizeof(str)-1, size));
if (res < 0)
return;
str[res] = 0;
if (size & 1)
size++;
size -= res;
if (size)
url_fskip(s->pb, size);
av_metadata_set(&s->metadata, key, str);
}
/* Returns the number of sound data frames or negative on error */
static unsigned int get_aiff_header(ByteIOContext *pb, AVCodecContext *codec,
int size, unsigned version)
{
AVExtFloat ext;
double sample_rate;
unsigned int num_frames;
if (size & 1)
size++;
codec->codec_type = CODEC_TYPE_AUDIO;
codec->channels = get_be16(pb);
num_frames = get_be32(pb);
codec->bits_per_coded_sample = get_be16(pb);
get_buffer(pb, (uint8_t*)&ext, sizeof(ext));/* Sample rate is in */
sample_rate = av_ext2dbl(ext); /* 80 bits BE IEEE extended float */
codec->sample_rate = sample_rate;
size -= 18;
/* Got an AIFF-C? */
if (version == AIFF_C_VERSION1) {
codec->codec_tag = get_le32(pb);
codec->codec_id = ff_codec_get_id(codec_aiff_tags, codec->codec_tag);
switch (codec->codec_id) {
case CODEC_ID_PCM_S16BE:
codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample);
codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id);
break;
case CODEC_ID_ADPCM_IMA_QT:
codec->block_align = 34*codec->channels;
codec->frame_size = 64;
break;
case CODEC_ID_MACE3:
codec->block_align = 2*codec->channels;
codec->frame_size = 6;
break;
case CODEC_ID_MACE6:
codec->block_align = 1*codec->channels;
codec->frame_size = 6;
break;
case CODEC_ID_GSM:
codec->block_align = 33;
codec->frame_size = 160;
break;
default:
break;
}
size -= 4;
} else {
/* Need the codec type */
codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample);
codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id);
}
/* Block align needs to be computed in all cases, as the definition
* is specific to applications -> here we use the WAVE format definition */
if (!codec->block_align)
codec->block_align = (codec->bits_per_coded_sample * codec->channels) >> 3;
codec->bit_rate = (codec->frame_size ? codec->sample_rate/codec->frame_size :
codec->sample_rate) * (codec->block_align << 3);
/* Chunk is over */
if (size)
url_fseek(pb, size, SEEK_CUR);
return num_frames;
}
#if CONFIG_AIFF_MUXER
typedef struct {
int64_t form;
int64_t frames;
int64_t ssnd;
} AIFFOutputContext;
static int aiff_write_header(AVFormatContext *s)
{
AIFFOutputContext *aiff = s->priv_data;
ByteIOContext *pb = s->pb;
AVCodecContext *enc = s->streams[0]->codec;
AVExtFloat sample_rate;
int aifc = 0;
/* First verify if format is ok */
if (!enc->codec_tag)
return -1;
if (enc->codec_tag != MKTAG('N','O','N','E'))
aifc = 1;
/* FORM AIFF header */
put_tag(pb, "FORM");
aiff->form = url_ftell(pb);
put_be32(pb, 0); /* file length */
put_tag(pb, aifc ? "AIFC" : "AIFF");
if (aifc) { // compressed audio
enc->bits_per_coded_sample = 16;
if (!enc->block_align) {
av_log(s, AV_LOG_ERROR, "block align not set\n");
return -1;
}
/* Version chunk */
put_tag(pb, "FVER");
put_be32(pb, 4);
put_be32(pb, 0xA2805140);
}
/* Common chunk */
put_tag(pb, "COMM");
put_be32(pb, aifc ? 24 : 18); /* size */
put_be16(pb, enc->channels); /* Number of channels */
aiff->frames = url_ftell(pb);
put_be32(pb, 0); /* Number of frames */
if (!enc->bits_per_coded_sample)
enc->bits_per_coded_sample = av_get_bits_per_sample(enc->codec_id);
if (!enc->bits_per_coded_sample) {
av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
return -1;
}
if (!enc->block_align)
enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3;
put_be16(pb, enc->bits_per_coded_sample); /* Sample size */
sample_rate = av_dbl2ext((double)enc->sample_rate);
put_buffer(pb, (uint8_t*)&sample_rate, sizeof(sample_rate));
if (aifc) {
put_le32(pb, enc->codec_tag);
put_be16(pb, 0);
}
/* Sound data chunk */
put_tag(pb, "SSND");
aiff->ssnd = url_ftell(pb); /* Sound chunk size */
put_be32(pb, 0); /* Sound samples data size */
put_be32(pb, 0); /* Data offset */
put_be32(pb, 0); /* Block-size (block align) */
av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
/* Data is starting here */
put_flush_packet(pb);
return 0;
}
static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
{
ByteIOContext *pb = s->pb;
put_buffer(pb, pkt->data, pkt->size);
return 0;
}
static int aiff_write_trailer(AVFormatContext *s)
{
ByteIOContext *pb = s->pb;
AIFFOutputContext *aiff = s->priv_data;
AVCodecContext *enc = s->streams[0]->codec;
/* Chunks sizes must be even */
int64_t file_size, end_size;
end_size = file_size = url_ftell(pb);
if (file_size & 1) {
put_byte(pb, 0);
end_size++;
}
if (!url_is_streamed(s->pb)) {
/* File length */
url_fseek(pb, aiff->form, SEEK_SET);
put_be32(pb, file_size - aiff->form - 4);
/* Number of sample frames */
url_fseek(pb, aiff->frames, SEEK_SET);
put_be32(pb, (file_size-aiff->ssnd-12)/enc->block_align);
/* Sound Data chunk size */
url_fseek(pb, aiff->ssnd, SEEK_SET);
put_be32(pb, file_size - aiff->ssnd - 4);
/* return to the end */
url_fseek(pb, end_size, SEEK_SET);
put_flush_packet(pb);
}
return 0;
}
#endif /* CONFIG_AIFF_MUXER */
static int aiff_probe(AVProbeData *p)
{
/* check file header */
if (p->buf[0] == 'F' && p->buf[1] == 'O' &&
p->buf[2] == 'R' && p->buf[3] == 'M' &&
p->buf[8] == 'A' && p->buf[9] == 'I' &&
p->buf[10] == 'F' && (p->buf[11] == 'F' || p->buf[11] == 'C'))
return AVPROBE_SCORE_MAX;
else
return 0;
}
/* aiff input */
static int aiff_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
int size, filesize;
int64_t offset = 0;
uint32_t tag;
unsigned version = AIFF_C_VERSION1;
ByteIOContext *pb = s->pb;
AVStream * st;
/* check FORM header */
filesize = get_tag(pb, &tag);
if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M'))
return AVERROR_INVALIDDATA;
/* AIFF data type */
tag = get_le32(pb);
if (tag == MKTAG('A', 'I', 'F', 'F')) /* Got an AIFF file */
version = AIFF;
else if (tag != MKTAG('A', 'I', 'F', 'C')) /* An AIFF-C file then */
return AVERROR_INVALIDDATA;
filesize -= 4;
st = av_new_stream(s, 0);
if (!st)
return AVERROR(ENOMEM);
while (filesize > 0) {
/* parse different chunks */
size = get_tag(pb, &tag);
if (size < 0)
return size;
filesize -= size + 8;
switch (tag) {
case MKTAG('C', 'O', 'M', 'M'): /* Common chunk */
/* Then for the complete header info */
st->nb_frames = get_aiff_header(pb, st->codec, size, version);
if (st->nb_frames < 0)
return st->nb_frames;
if (offset > 0) // COMM is after SSND
goto got_sound;
break;
case MKTAG('F', 'V', 'E', 'R'): /* Version chunk */
version = get_be32(pb);
break;
case MKTAG('N', 'A', 'M', 'E'): /* Sample name chunk */
get_meta(s, "title" , size);
break;
case MKTAG('A', 'U', 'T', 'H'): /* Author chunk */
get_meta(s, "author" , size);
break;
case MKTAG('(', 'c', ')', ' '): /* Copyright chunk */
get_meta(s, "copyright", size);
break;
case MKTAG('A', 'N', 'N', 'O'): /* Annotation chunk */
get_meta(s, "comment" , size);
break;
case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */
offset = get_be32(pb); /* Offset of sound data */
get_be32(pb); /* BlockSize... don't care */
offset += url_ftell(pb); /* Compute absolute data offset */
if (st->codec->block_align) /* Assume COMM already parsed */
goto got_sound;
if (url_is_streamed(pb)) {
av_log(s, AV_LOG_ERROR, "file is not seekable\n");
return -1;
}
url_fskip(pb, size - 8);
break;
case MKTAG('w', 'a', 'v', 'e'):
if ((uint64_t)size > (1<<30))
return -1;
st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
st->codec->extradata_size = size;
get_buffer(pb, st->codec->extradata, size);
break;
default: /* Jump */
if (size & 1) /* Always even aligned */
size++;
url_fskip (pb, size);
}
}
if (!st->codec->block_align) {
av_log(s, AV_LOG_ERROR, "could not find COMM tag\n");
return -1;
}
got_sound:
/* Now positioned, get the sound data start and end */
if (st->nb_frames)
s->file_size = st->nb_frames * st->codec->block_align;
av_set_pts_info(st, 64, 1, st->codec->sample_rate);
st->start_time = 0;
st->duration = st->codec->frame_size ?
st->nb_frames * st->codec->frame_size : st->nb_frames;
/* Position the stream at the first block */
url_fseek(pb, offset, SEEK_SET);
return 0;
}
#define MAX_SIZE 4096
static int aiff_read_packet(AVFormatContext *s,
AVPacket *pkt)
{
AVStream *st = s->streams[0];
int res;
/* End of stream may be reached */
if (url_feof(s->pb))
return AVERROR(EIO);
/* Now for that packet */
res = av_get_packet(s->pb, pkt, (MAX_SIZE / st->codec->block_align) * st->codec->block_align);
if (res < 0)
return res;
/* Only one stream in an AIFF file */
pkt->stream_index = 0;
return 0;
}
#if CONFIG_AIFF_DEMUXER
AVInputFormat aiff_demuxer = {
"aiff",
NULL_IF_CONFIG_SMALL("Audio IFF"),
0,
aiff_probe,
aiff_read_header,
aiff_read_packet,
NULL,
pcm_read_seek,
.codec_tag= (const AVCodecTag* const []){codec_aiff_tags, 0},
};
#endif
#if CONFIG_AIFF_MUXER
AVOutputFormat aiff_muxer = {
"aiff",
NULL_IF_CONFIG_SMALL("Audio IFF"),
"audio/aiff",
"aif,aiff,afc,aifc",
sizeof(AIFFOutputContext),
CODEC_ID_PCM_S16BE,
CODEC_ID_NONE,
aiff_write_header,
aiff_write_packet,
aiff_write_trailer,
.codec_tag= (const AVCodecTag* const []){codec_aiff_tags, 0},
};
#endif

View File

@ -1,85 +0,0 @@
/*
* copyright (c) 2007 Luca Abeni
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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 "avformat.h"
#include "rtpenc.h"
void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size)
{
RTPMuxContext *s = s1->priv_data;
int len, max_packet_size;
uint8_t *p;
const int max_frames_per_packet = s->max_frames_per_packet ? s->max_frames_per_packet : 5;
const int max_au_headers_size = 2 + 2 * max_frames_per_packet;
/* skip ADTS header, if present */
if ((s1->streams[0]->codec->extradata_size) == 0) {
size -= 7;
buff += 7;
}
max_packet_size = s->max_payload_size - max_au_headers_size;
/* test if the packet must be sent */
len = (s->buf_ptr - s->buf);
if ((s->num_frames == max_frames_per_packet) || (len && (len + size) > s->max_payload_size)) {
int au_size = s->num_frames * 2;
p = s->buf + max_au_headers_size - au_size - 2;
if (p != s->buf) {
memmove(p + 2, s->buf + 2, au_size);
}
/* Write the AU header size */
p[0] = ((au_size * 8) & 0xFF) >> 8;
p[1] = (au_size * 8) & 0xFF;
ff_rtp_send_data(s1, p, s->buf_ptr - p, 1);
s->num_frames = 0;
}
if (s->num_frames == 0) {
s->buf_ptr = s->buf + max_au_headers_size;
s->timestamp = s->cur_timestamp;
}
if (size <= max_packet_size) {
p = s->buf + s->num_frames++ * 2 + 2;
*p++ = size >> 5;
*p = (size & 0x1F) << 3;
memcpy(s->buf_ptr, buff, size);
s->buf_ptr += size;
} else {
int au_size = size;
max_packet_size = s->max_payload_size - 4;
p = s->buf;
p[0] = 0;
p[1] = 16;
while (size > 0) {
len = FFMIN(size, max_packet_size);
p[2] = au_size >> 5;
p[3] = (au_size & 0x1F) << 3;
memcpy(p + 4, buff, len);
ff_rtp_send_data(s1, p, len + 4, len == size);
size -= len;
buff += len;
}
}
}

View File

@ -1,66 +0,0 @@
/*
* RTP packetization for AMR audio
* Copyright (c) 2007 Luca Abeni
* Copyright (c) 2009 Martin Storsjo
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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 "avformat.h"
#include "rtpenc.h"
/**
* Packetize AMR frames into RTP packets according to RFC 3267,
* in octet-aligned mode.
*/
void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size)
{
RTPMuxContext *s = s1->priv_data;
int max_header_toc_size = 1 + s->max_frames_per_packet;
uint8_t *p;
int len;
/* Test if the packet must be sent. */
len = s->buf_ptr - s->buf;
if (s->num_frames == s->max_frames_per_packet || (len && len + size - 1 > s->max_payload_size)) {
int header_size = s->num_frames + 1;
p = s->buf + max_header_toc_size - header_size;
if (p != s->buf)
memmove(p, s->buf, header_size);
ff_rtp_send_data(s1, p, s->buf_ptr - p, 1);
s->num_frames = 0;
}
if (!s->num_frames) {
s->buf[0] = 0xf0;
s->buf_ptr = s->buf + max_header_toc_size;
s->timestamp = s->cur_timestamp;
} else {
/* Mark the previous TOC entry as having more entries following. */
s->buf[1 + s->num_frames - 1] |= 0x80;
}
/* Copy the frame type and quality bits. */
s->buf[1 + s->num_frames++] = buff[0] & 0x7C;
buff++;
size--;
memcpy(s->buf_ptr, buff, size);
s->buf_ptr += size;
}

View File

@ -1,281 +0,0 @@
/*
* Microsoft RTP/ASF support.
* Copyright (c) 2008 Ronald S. Bultje
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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
*/
/**
* @file libavformat/rtp_asf.c
* @brief Microsoft RTP/ASF support
* @author Ronald S. Bultje <rbultje@ronald.bitfreak.net>
*/
#include <libavutil/base64.h>
#include <libavutil/avstring.h>
#include <libavutil/intreadwrite.h>
#include "rtp.h"
#include "rtp_asf.h"
#include "rtsp.h"
#include "asf.h"
/**
* From MSDN 2.2.1.4, we learn that ASF data packets over RTP should not
* contain any padding. Unfortunately, the header min/max_pktsize are not
* updated (thus making min_pktsize invalid). Here, we "fix" these faulty
* min_pktsize values in the ASF file header.
* @return 0 on success, <0 on failure (currently -1).
*/
static int rtp_asf_fix_header(uint8_t *buf, int len)
{
uint8_t *p = buf, *end = buf + len;
if (len < sizeof(ff_asf_guid) * 2 + 22 ||
memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) {
return -1;
}
p += sizeof(ff_asf_guid) + 14;
do {
uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid));
if (memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) {
if (chunksize > end - p)
return -1;
p += chunksize;
continue;
}
/* skip most of the file header, to min_pktsize */
p += 6 * 8 + 3 * 4 + sizeof(ff_asf_guid) * 2;
if (p + 8 <= end && AV_RL32(p) == AV_RL32(p + 4)) {
/* and set that to zero */
AV_WL32(p, 0);
return 0;
}
break;
} while (end - p >= sizeof(ff_asf_guid) + 8);
return -1;
}
/**
* The following code is basically a buffered ByteIOContext,
* with the added benefit of returning -EAGAIN (instead of 0)
* on packet boundaries, such that the ASF demuxer can return
* safely and resume business at the next packet.
*/
static int packetizer_read(void *opaque, uint8_t *buf, int buf_size)
{
return AVERROR(EAGAIN);
}
static void init_packetizer(ByteIOContext *pb, uint8_t *buf, int len)
{
init_put_byte(pb, buf, len, 0, NULL, packetizer_read, NULL, NULL);
/* this "fills" the buffer with its current content */
pb->pos = len;
pb->buf_end = buf + len;
}
void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
{
if (av_strstart(p, "pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,", &p)) {
ByteIOContext pb;
RTSPState *rt = s->priv_data;
int len = strlen(p) * 6 / 8;
char *buf = av_mallocz(len);
av_base64_decode(buf, p, len);
if (rtp_asf_fix_header(buf, len) < 0)
av_log(s, AV_LOG_ERROR,
"Failed to fix invalid RTSP-MS/ASF min_pktsize\n");
init_packetizer(&pb, buf, len);
if (rt->asf_ctx) {
av_close_input_stream(rt->asf_ctx);
rt->asf_ctx = NULL;
}
av_open_input_stream(&rt->asf_ctx, &pb, "", &asf_demuxer, NULL);
rt->asf_pb_pos = url_ftell(&pb);
av_free(buf);
rt->asf_ctx->pb = NULL;
}
}
static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index,
PayloadContext *asf, const char *line)
{
if (av_strstart(line, "stream:", &line)) {
RTSPState *rt = s->priv_data;
s->streams[stream_index]->id = strtol(line, NULL, 10);
if (rt->asf_ctx) {
int i;
for (i = 0; i < rt->asf_ctx->nb_streams; i++) {
if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) {
*s->streams[stream_index]->codec =
*rt->asf_ctx->streams[i]->codec;
rt->asf_ctx->streams[i]->codec->extradata_size = 0;
rt->asf_ctx->streams[i]->codec->extradata = NULL;
av_set_pts_info(s->streams[stream_index], 32, 1, 1000);
}
}
}
}
return 0;
}
struct PayloadContext {
ByteIOContext *pktbuf, pb;
char *buf;
};
/**
* @return 0 when a packet was written into /p pkt, and no more data is left;
* 1 when a packet was written into /p pkt, and more packets might be left;
* <0 when not enough data was provided to return a full packet, or on error.
*/
static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
AVStream *st, AVPacket *pkt,
uint32_t *timestamp,
const uint8_t *buf, int len, int flags)
{
ByteIOContext *pb = &asf->pb;
int res, mflags, len_off;
RTSPState *rt = s->priv_data;
if (!rt->asf_ctx)
return -1;
if (len > 0) {
int off, out_len;
if (len < 4)
return -1;
init_put_byte(pb, buf, len, 0, NULL, NULL, NULL, NULL);
mflags = get_byte(pb);
if (mflags & 0x80)
flags |= RTP_FLAG_KEY;
len_off = get_be24(pb);
if (mflags & 0x20) /**< relative timestamp */
url_fskip(pb, 4);
if (mflags & 0x10) /**< has duration */
url_fskip(pb, 4);
if (mflags & 0x8) /**< has location ID */
url_fskip(pb, 4);
off = url_ftell(pb);
av_freep(&asf->buf);
if (!(mflags & 0x40)) {
/**
* If 0x40 is not set, the len_off field specifies an offset of this
* packet's payload data in the complete (reassembled) ASF packet.
* This is used to spread one ASF packet over multiple RTP packets.
*/
if (asf->pktbuf && len_off != url_ftell(asf->pktbuf)) {
uint8_t *p;
url_close_dyn_buf(asf->pktbuf, &p);
asf->pktbuf = NULL;
av_free(p);
}
if (!len_off && !asf->pktbuf &&
!(res = url_open_dyn_packet_buf(&asf->pktbuf, rt->asf_ctx->packet_size)))
return res;
if (!asf->pktbuf)
return AVERROR(EIO);
put_buffer(asf->pktbuf, buf + off, len - off);
if (!(flags & RTP_FLAG_MARKER))
return -1;
out_len = url_close_dyn_buf(asf->pktbuf, &asf->buf);
asf->pktbuf = NULL;
} else {
/**
* If 0x40 is set, the len_off field specifies the length of the
* next ASF packet that can be read from this payload data alone.
* This is commonly the same as the payload size, but could be
* less in case of packet splitting (i.e. multiple ASF packets in
* one RTP packet).
*/
if (len_off != len) {
av_log_missing_feature(s,
"RTSP-MS packet splitting", 1);
return -1;
}
asf->buf = av_malloc(len - off);
out_len = len - off;
memcpy(asf->buf, buf + off, len - off);
}
init_packetizer(pb, asf->buf, out_len);
pb->pos += rt->asf_pb_pos;
pb->eof_reached = 0;
rt->asf_ctx->pb = pb;
}
for (;;) {
int i;
res = av_read_packet(rt->asf_ctx, pkt);
rt->asf_pb_pos = url_ftell(pb);
if (res != 0)
break;
for (i = 0; i < s->nb_streams; i++) {
if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {
pkt->stream_index = i;
return 1; // FIXME: return 0 if last packet
}
}
av_free_packet(pkt);
}
return res == 1 ? -1 : res;
}
static PayloadContext *asfrtp_new_context(void)
{
return av_mallocz(sizeof(PayloadContext));
}
static void asfrtp_free_context(PayloadContext *asf)
{
if (asf->pktbuf) {
uint8_t *p = NULL;
url_close_dyn_buf(asf->pktbuf, &p);
asf->pktbuf = NULL;
av_free(p);
}
av_freep(&asf->buf);
av_free(asf);
}
#define RTP_ASF_HANDLER(n, s, t) \
RTPDynamicProtocolHandler ff_ms_rtp_ ## n ## _handler = { \
.enc_name = s, \
.codec_type = t, \
.codec_id = CODEC_ID_NONE, \
.parse_sdp_a_line = asfrtp_parse_sdp_line, \
.open = asfrtp_new_context, \
.close = asfrtp_free_context, \
.parse_packet = asfrtp_parse_packet, \
};
RTP_ASF_HANDLER(asf_pfv, "x-asf-pf", CODEC_TYPE_VIDEO);
RTP_ASF_HANDLER(asf_pfa, "x-asf-pf", CODEC_TYPE_AUDIO);

View File

@ -1,43 +0,0 @@
/*
* Microsoft RTP/ASF support.
* Copyright (c) 2008 Ronald S. Bultje
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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
*/
#ifndef AVFORMAT_RTP_ASF_H
#define AVFORMAT_RTP_ASF_H
#include "avformat.h"
#include "rtpdec.h"
/**
* Parse a Windows Media Server-specific SDP line
*
* @param s RTSP demux context
* @param line the SDP line to be parsed
*/
void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
/**
* Handlers for the x-asf-pf payloads (the payload ID for RTP/ASF).
* Defined and implemented in rtp_asf.c, registered in rtpdec.c.
*/
extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler,
ff_ms_rtp_asf_pfa_handler;
#endif /* AVFORMAT_RTP_ASF_H */

View File

@ -1,80 +0,0 @@
/*
* RTP packetization for H.263 video
* Copyright (c) 2009 Luca Abeni
* Copyright (c) 2009 Martin Storsjo
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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 "avformat.h"
#include "rtpenc.h"
static const uint8_t *find_resync_marker_reverse(const uint8_t *restrict start,
const uint8_t *restrict end)
{
const uint8_t *p = end - 1;
start += 1; /* Make sure we never return the original start. */
for (; p > start; p -= 2) {
if (!*p) {
if (!p[ 1] && p[2]) return p;
else if (!p[-1] && p[1]) return p - 1;
}
}
return end;
}
/**
* Packetize H.263 frames into RTP packets according to RFC 4629
*/
void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size)
{
RTPMuxContext *s = s1->priv_data;
int len, max_packet_size;
uint8_t *q;
max_packet_size = s->max_payload_size;
while (size > 0) {
q = s->buf;
if ((buf1[0] == 0) && (buf1[1] == 0)) {
*q++ = 0x04;
buf1 += 2;
size -= 2;
} else {
*q++ = 0;
}
*q++ = 0;
len = FFMIN(max_packet_size - 2, size);
/* Look for a better place to split the frame into packets. */
if (len < size) {
const uint8_t *end = find_resync_marker_reverse(buf1, buf1 + len);
len = end - buf1;
}
memcpy(q, buf1, len);
q += len;
/* 90 KHz time stamp */
s->timestamp = s->cur_timestamp;
ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size));
buf1 += len;
size -= len;
}
}

View File

@ -1,416 +0,0 @@
/*
* RTP H264 Protocol (RFC3984)
* Copyright (c) 2006 Ryan Martell
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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
*/
/**
* @file libavformat/rtp_h264.c
* @brief H.264 / RTP Code (RFC3984)
* @author Ryan Martell <rdm4@martellventures.com>
*
* @note Notes:
* Notes:
* This currently supports packetization mode:
* Single Nal Unit Mode (0), or
* Non-Interleaved Mode (1). It currently does not support
* Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, FU-B packet types)
*
* @note TODO:
* 1) RTCP sender reports for udp streams are required..
*
*/
#include "libavutil/base64.h"
#include "libavutil/avstring.h"
#include "libavcodec/get_bits.h"
#include "avformat.h"
#include "mpegts.h"
#include <unistd.h>
#include "network.h"
#include <assert.h>
#include "rtpdec.h"
#include "rtp_h264.h"
/**
RTP/H264 specific private data.
*/
struct PayloadContext {
unsigned long cookie; ///< sanity check, to make sure we get the pointer we're expecting.
//sdp setup parameters
uint8_t profile_idc; ///< from the sdp setup parameters.
uint8_t profile_iop; ///< from the sdp setup parameters.
uint8_t level_idc; ///< from the sdp setup parameters.
int packetization_mode; ///< from the sdp setup parameters.
#ifdef DEBUG
int packet_types_received[32];
#endif
};
#define MAGIC_COOKIE (0xdeadbeef) ///< Cookie for the extradata; to verify we are what we think we are, and that we haven't been freed.
#define DEAD_COOKIE (0xdeaddead) ///< Cookie for the extradata; once it is freed.
/* ---------------- private code */
static void sdp_parse_fmtp_config_h264(AVStream * stream,
PayloadContext * h264_data,
char *attr, char *value)
{
AVCodecContext *codec = stream->codec;
assert(codec->codec_id == CODEC_ID_H264);
assert(h264_data != NULL);
if (!strcmp(attr, "packetization-mode")) {
av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value));
h264_data->packetization_mode = atoi(value);
/*
Packetization Mode:
0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed.
*/
if (h264_data->packetization_mode > 1)
av_log(codec, AV_LOG_ERROR,
"Interleaved RTP mode is not supported yet.");
} else if (!strcmp(attr, "profile-level-id")) {
if (strlen(value) == 6) {
char buffer[3];
// 6 characters=3 bytes, in hex.
uint8_t profile_idc;
uint8_t profile_iop;
uint8_t level_idc;
buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0';
profile_idc = strtol(buffer, NULL, 16);
buffer[0] = value[2]; buffer[1] = value[3];
profile_iop = strtol(buffer, NULL, 16);
buffer[0] = value[4]; buffer[1] = value[5];
level_idc = strtol(buffer, NULL, 16);
// set the parameters...
av_log(codec, AV_LOG_DEBUG,
"RTP Profile IDC: %x Profile IOP: %x Level: %x\n",
profile_idc, profile_iop, level_idc);
h264_data->profile_idc = profile_idc;
h264_data->profile_iop = profile_iop;
h264_data->level_idc = level_idc;
}
} else if (!strcmp(attr, "sprop-parameter-sets")) {
uint8_t start_sequence[]= { 0, 0, 1 };
codec->extradata_size= 0;
codec->extradata= NULL;
while (*value) {
char base64packet[1024];
uint8_t decoded_packet[1024];
uint32_t packet_size;
char *dst = base64packet;
while (*value && *value != ','
&& (dst - base64packet) < sizeof(base64packet) - 1) {
*dst++ = *value++;
}
*dst++ = '\0';
if (*value == ',')
value++;
packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet));
if (packet_size) {
uint8_t *dest= av_malloc(packet_size+sizeof(start_sequence)+codec->extradata_size);
if(dest)
{
if(codec->extradata_size)
{
// av_realloc?
memcpy(dest, codec->extradata, codec->extradata_size);
av_free(codec->extradata);
}
memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence));
memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size);
codec->extradata= dest;
codec->extradata_size+= sizeof(start_sequence)+packet_size;
} else {
av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!");
}
}
}
av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size);
}
}
// return 0 on packet, no more left, 1 on packet, 1 on partial packet...
static int h264_handle_packet(AVFormatContext *ctx,
PayloadContext *data,
AVStream *st,
AVPacket * pkt,
uint32_t * timestamp,
const uint8_t * buf,
int len, int flags)
{
uint8_t nal = buf[0];
uint8_t type = (nal & 0x1f);
int result= 0;
uint8_t start_sequence[]= {0, 0, 1};
#ifdef DEBUG
assert(data);
assert(data->cookie == MAGIC_COOKIE);
#endif
assert(buf);
if (type >= 1 && type <= 23)
type = 1; // simplify the case. (these are all the nal types used internally by the h264 codec)
switch (type) {
case 0: // undefined;
result= -1;
break;
case 1:
av_new_packet(pkt, len+sizeof(start_sequence));
memcpy(pkt->data, start_sequence, sizeof(start_sequence));
memcpy(pkt->data+sizeof(start_sequence), buf, len);
#ifdef DEBUG
data->packet_types_received[nal & 0x1f]++;
#endif
break;
case 24: // STAP-A (one packet, multiple nals)
// consume the STAP-A NAL
buf++;
len--;
// first we are going to figure out the total size....
{
int pass= 0;
int total_length= 0;
uint8_t *dst= NULL;
for(pass= 0; pass<2; pass++) {
const uint8_t *src= buf;
int src_len= len;
do {
uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?)
// consume the length of the aggregate...
src += 2;
src_len -= 2;
if (nal_size <= src_len) {
if(pass==0) {
// counting...
total_length+= sizeof(start_sequence)+nal_size;
} else {
// copying
assert(dst);
memcpy(dst, start_sequence, sizeof(start_sequence));
dst+= sizeof(start_sequence);
memcpy(dst, src, nal_size);
#ifdef DEBUG
data->packet_types_received[*src & 0x1f]++;
#endif
dst+= nal_size;
}
} else {
av_log(ctx, AV_LOG_ERROR,
"nal size exceeds length: %d %d\n", nal_size, src_len);
}
// eat what we handled...
src += nal_size;
src_len -= nal_size;
if (src_len < 0)
av_log(ctx, AV_LOG_ERROR,
"Consumed more bytes than we got! (%d)\n", src_len);
} while (src_len > 2); // because there could be rtp padding..
if(pass==0) {
// now we know the total size of the packet (with the start sequences added)
av_new_packet(pkt, total_length);
dst= pkt->data;
} else {
assert(dst-pkt->data==total_length);
}
}
}
break;
case 25: // STAP-B
case 26: // MTAP-16
case 27: // MTAP-24
case 29: // FU-B
av_log(ctx, AV_LOG_ERROR,
"Unhandled type (%d) (See RFC for implementation details\n",
type);
result= -1;
break;
case 28: // FU-A (fragmented nal)
buf++;
len--; // skip the fu_indicator
{
// these are the same as above, we just redo them here for clarity...
uint8_t fu_indicator = nal;
uint8_t fu_header = *buf; // read the fu_header.
uint8_t start_bit = fu_header >> 7;
// uint8_t end_bit = (fu_header & 0x40) >> 6;
uint8_t nal_type = (fu_header & 0x1f);
uint8_t reconstructed_nal;
// reconstruct this packet's true nal; only the data follows..
reconstructed_nal = fu_indicator & (0xe0); // the original nal forbidden bit and NRI are stored in this packet's nal;
reconstructed_nal |= nal_type;
// skip the fu_header...
buf++;
len--;
#ifdef DEBUG
if (start_bit)
data->packet_types_received[nal_type]++;
#endif
if(start_bit) {
// copy in the start sequence, and the reconstructed nal....
av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len);
memcpy(pkt->data, start_sequence, sizeof(start_sequence));
pkt->data[sizeof(start_sequence)]= reconstructed_nal;
memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len);
} else {
av_new_packet(pkt, len);
memcpy(pkt->data, buf, len);
}
}
break;
case 30: // undefined
case 31: // undefined
default:
av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type);
result= -1;
break;
}
pkt->stream_index = st->index;
return result;
}
/* ---------------- public code */
static PayloadContext *h264_new_context(void)
{
PayloadContext *data =
av_mallocz(sizeof(PayloadContext) +
FF_INPUT_BUFFER_PADDING_SIZE);
if (data) {
data->cookie = MAGIC_COOKIE;
}
return data;
}
static void h264_free_context(PayloadContext *data)
{
#ifdef DEBUG
int ii;
for (ii = 0; ii < 32; ii++) {
if (data->packet_types_received[ii])
av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n",
data->packet_types_received[ii], ii);
}
#endif
assert(data);
assert(data->cookie == MAGIC_COOKIE);
// avoid stale pointers (assert)
data->cookie = DEAD_COOKIE;
// and clear out this...
av_free(data);
}
static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
PayloadContext *h264_data, const char *line)
{
AVStream *stream = s->streams[st_index];
AVCodecContext *codec = stream->codec;
const char *p = line;
assert(h264_data->cookie == MAGIC_COOKIE);
if (av_strstart(p, "framesize:", &p)) {
char buf1[50];
char *dst = buf1;
// remove the protocol identifier..
while (*p && *p == ' ') p++; // strip spaces.
while (*p && *p != ' ') p++; // eat protocol identifier
while (*p && *p == ' ') p++; // strip trailing spaces.
while (*p && *p != '-' && (buf1 - dst) < sizeof(buf1) - 1) {
*dst++ = *p++;
}
*dst = '\0';
// a='framesize:96 320-240'
// set our parameters..
codec->width = atoi(buf1);
codec->height = atoi(p + 1); // skip the -
codec->pix_fmt = PIX_FMT_YUV420P;
} else if (av_strstart(p, "fmtp:", &p)) {
char attr[256];
char value[4096];
// remove the protocol identifier..
while (*p && *p == ' ') p++; // strip spaces.
while (*p && *p != ' ') p++; // eat protocol identifier
while (*p && *p == ' ') p++; // strip trailing spaces.
/* loop on each attribute */
while (rtsp_next_attr_and_value
(&p, attr, sizeof(attr), value, sizeof(value))) {
/* grab the codec extra_data from the config parameter of the fmtp line */
sdp_parse_fmtp_config_h264(stream, h264_data, attr, value);
}
} else if (av_strstart(p, "cliprect:", &p)) {
// could use this if we wanted.
}
av_set_pts_info(stream, 33, 1, 90000); // 33 should be right, because the pts is 64 bit? (done elsewhere; this is a one time thing)
return 0; // keep processing it the normal way...
}
/**
This is the structure for expanding on the dynamic rtp protocols (makes everything static. yay!)
*/
RTPDynamicProtocolHandler ff_h264_dynamic_handler = {
.enc_name = "H264",
.codec_type = CODEC_TYPE_VIDEO,
.codec_id = CODEC_ID_H264,
.parse_sdp_a_line = parse_h264_sdp_line,
.open = h264_new_context,
.close = h264_free_context,
.parse_packet = h264_handle_packet
};

View File

@ -1,30 +0,0 @@
/*
* RTP H264 Protocol (RFC3984)
* Copyright (c) 2006 Ryan Martell
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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
*/
#ifndef AVFORMAT_RTP_H264_H
#define AVFORMAT_RTP_H264_H
#include "rtpdec.h"
extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size);
#endif /* AVFORMAT_RTP_H264_H */

View File

@ -1,119 +0,0 @@
/*
* RTP packetization for MPEG video
* Copyright (c) 2002 Fabrice Bellard
* Copyright (c) 2007 Luca Abeni
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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 "libavcodec/mpegvideo.h"
#include "avformat.h"
#include "rtpenc.h"
/* NOTE: a single frame must be passed with sequence header if
needed. XXX: use slices. */
void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size)
{
RTPMuxContext *s = s1->priv_data;
int len, h, max_packet_size;
uint8_t *q;
const uint8_t *end = buf1 + size;
int begin_of_slice, end_of_slice, frame_type, temporal_reference;
max_packet_size = s->max_payload_size;
begin_of_slice = 1;
end_of_slice = 0;
frame_type = 0;
temporal_reference = 0;
while (size > 0) {
int begin_of_sequence;
begin_of_sequence = 0;
len = max_packet_size - 4;
if (len >= size) {
len = size;
end_of_slice = 1;
} else {
const uint8_t *r, *r1;
int start_code;
r1 = buf1;
while (1) {
start_code = -1;
r = ff_find_start_code(r1, end, &start_code);
if((start_code & 0xFFFFFF00) == 0x100) {
/* New start code found */
if (start_code == 0x100) {
frame_type = (r[1] & 0x38) >> 3;
temporal_reference = (int)r[0] << 2 | r[1] >> 6;
}
if (start_code == 0x1B8) {
begin_of_sequence = 1;
}
if (r - buf1 - 4 <= len) {
/* The current slice fits in the packet */
if (begin_of_slice == 0) {
/* no slice at the beginning of the packet... */
end_of_slice = 1;
len = r - buf1 - 4;
break;
}
r1 = r;
} else {
if ((r1 - buf1 > 4) && (r - r1 < max_packet_size)) {
len = r1 - buf1 - 4;
end_of_slice = 1;
}
break;
}
} else {
break;
}
}
}
h = 0;
h |= temporal_reference << 16;
h |= begin_of_sequence << 13;
h |= begin_of_slice << 12;
h |= end_of_slice << 11;
h |= frame_type << 8;
q = s->buf;
*q++ = h >> 24;
*q++ = h >> 16;
*q++ = h >> 8;
*q++ = h;
memcpy(q, buf1, len);
q += len;
/* 90kHz time stamp */
s->timestamp = s->cur_timestamp;
ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size));
buf1 += len;
size -= len;
begin_of_slice = end_of_slice;
end_of_slice = 0;
}
}

View File

@ -1,218 +0,0 @@
/*
* RTP Vorbis Protocol (RFC5215)
* Copyright (c) 2009 Colin McQuillan
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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
*/
/**
* @file libavformat/rtp_vorbis.c
* @brief Vorbis / RTP Code (RFC 5215)
* @author Colin McQuillan <m.niloc@gmail.com>
*/
#include "libavutil/base64.h"
#include "libavutil/avstring.h"
#include "libavcodec/bytestream.h"
#include <assert.h>
#include "rtpdec.h"
#include "rtp_vorbis.h"
/**
* RTP/Vorbis specific private data.
*/
struct PayloadContext {
unsigned ident; ///< 24-bit stream configuration identifier
};
/**
* Length encoding described in RFC5215 section 3.1.1.
*/
static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
{
int n = 0;
for (; *buf < buf_end; ++*buf) {
n <<= 7;
n += **buf & 0x7f;
if (!(**buf & 0x80)) {
++*buf;
return n;
}
}
return 0;
}
/**
* Out-of-band headers, described in RFC 5251 section 3.2.1
*/
static unsigned int
parse_packed_headers(const uint8_t * packed_headers,
const uint8_t * packed_headers_end,
AVCodecContext * codec, PayloadContext * vorbis_data)
{
unsigned num_packed, num_headers, length, length1, length2;
uint8_t *ptr;
num_packed = bytestream_get_be32(&packed_headers);
vorbis_data->ident = bytestream_get_be24(&packed_headers);
length = bytestream_get_be16(&packed_headers);
num_headers = get_base128(&packed_headers, packed_headers_end);
length1 = get_base128(&packed_headers, packed_headers_end);
length2 = get_base128(&packed_headers, packed_headers_end);
if (num_packed != 1 || num_headers > 3) {
av_log(codec, AV_LOG_ERROR,
"Unimplemented number of headers: %d packed headers, %d headers\n",
num_packed, num_headers);
return AVERROR_PATCHWELCOME;
}
if (packed_headers_end - packed_headers != length ||
length1 > length || length2 > length - length1) {
av_log(codec, AV_LOG_ERROR,
"Bad packed header lengths (%d,%d,%d,%d)\n", length1,
length2, packed_headers_end - packed_headers, length);
return AVERROR_INVALIDDATA;
}
ptr = codec->extradata = av_mallocz(length + length / 255 + 64);
if (!ptr) {
av_log(codec, AV_LOG_ERROR, "Out of memory");
return AVERROR_NOMEM;
}
*ptr++ = 2;
ptr += av_xiphlacing(ptr, length1);
ptr += av_xiphlacing(ptr, length2);
memcpy(ptr, packed_headers, length);
ptr += length;
codec->extradata_size = ptr - codec->extradata;
return 0;
}
int
ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
void *vorbis_data, char *attr, char *value)
{
int result = 0;
assert(codec->codec_id == CODEC_ID_VORBIS);
assert(vorbis_data);
// The configuration value is a base64 encoded packed header
if (!strcmp(attr, "configuration")) {
uint8_t *decoded_packet = NULL;
int packet_size;
size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
if (decoded_alloc <= INT_MAX) {
decoded_packet = av_malloc(decoded_alloc);
if (decoded_packet) {
packet_size =
av_base64_decode(decoded_packet, value, decoded_alloc);
result = parse_packed_headers
(decoded_packet, decoded_packet + packet_size, codec,
vorbis_data);
} else {
av_log(codec, AV_LOG_ERROR,
"Out of memory while decoding SDP configuration.\n");
result = AVERROR_NOMEM;
}
} else {
av_log(codec, AV_LOG_ERROR, "Packet too large\n");
result = AVERROR_INVALIDDATA;
}
av_free(decoded_packet);
}
return result;
}
static PayloadContext *vorbis_new_context(void)
{
return av_mallocz(sizeof(PayloadContext));
}
static void vorbis_free_context(PayloadContext * data)
{
av_free(data);
}
/**
* Handle payload as described in RFC 5215 section 2.2
*/
static int
vorbis_handle_packet(AVFormatContext * ctx,
PayloadContext * data,
AVStream * st,
AVPacket * pkt,
uint32_t * timestamp,
const uint8_t * buf, int len, int flags)
{
int ident, fragmented, vdt, num_pkts, pkt_len;
if (len < 6) {
av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
return AVERROR_INVALIDDATA;
}
ident = AV_RB24(buf);
fragmented = buf[3] >> 6;
vdt = (buf[3] >> 4) & 3;
num_pkts = buf[3] & 7;
pkt_len = AV_RB16(buf + 4);
if (pkt_len > len - 6) {
av_log(ctx, AV_LOG_ERROR,
"Invalid packet length %d in %d byte packet\n", pkt_len,
len);
return AVERROR_INVALIDDATA;
}
if (ident != data->ident) {
av_log(ctx, AV_LOG_ERROR,
"Unimplemented Vorbis SDP configuration change detected\n");
return AVERROR_PATCHWELCOME;
}
if (fragmented != 0 || vdt != 0 || num_pkts != 1) {
av_log(ctx, AV_LOG_ERROR,
"Unimplemented RTP Vorbis packet settings (%d,%d,%d)\n",
fragmented, vdt, num_pkts);
return AVERROR_PATCHWELCOME;
}
if (av_new_packet(pkt, pkt_len)) {
av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
return AVERROR_NOMEM;
}
memcpy(pkt->data, buf + 6, pkt_len);
pkt->stream_index = st->index;
return 0;
}
RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = {
.enc_name = "vorbis",
.codec_type = CODEC_TYPE_AUDIO,
.codec_id = CODEC_ID_VORBIS,
.parse_sdp_a_line = NULL,
.open = vorbis_new_context,
.close = vorbis_free_context,
.parse_packet = vorbis_handle_packet
};

View File

@ -1,45 +0,0 @@
/*
* RTP Vorbis Protocol (RFC 5215)
* Copyright (c) 2009 Colin McQuillan
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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
*/
#ifndef AVFORMAT_RTP_VORBIS_H
#define AVFORMAT_RTP_VORBIS_H
#include "libavcodec/avcodec.h"
#include "rtpdec.h"
/**
* Handle a Vorbis-specific FMTP parameter
*
* @param codec The context of the codec
* @param ctx Private Vorbis RTP context
* @param attr Format-specific parameter name
* @param value Format-specific paremeter value
*/
int
ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
void *ctx, char *attr, char *value);
/**
* Vorbis RTP callbacks.
*/
extern RTPDynamicProtocolHandler ff_vorbis_dynamic_handler;
#endif /* AVFORMAT_RTP_VORBIS_H */

View File

@ -4,8 +4,8 @@ SubDir HAIKU_TOP src add-ons media plugins ffmpeg libavutil ;
TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS)
: -Wall -Wmissing-prototypes -Wsign-compare -Wpointer-arith ] ;
SubDirHdrs [ FDirName $(SUBDIR) .. ] ;
SubDirHdrs [ FDirName $(SUBDIR) ../libavcodec ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) libavcodec ] ;
# filter warnings we don't want here
TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS)

View File

@ -0,0 +1,72 @@
/*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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
*/
#ifndef AVUTIL_ARM_BSWAP_H
#define AVUTIL_ARM_BSWAP_H
#include <stdint.h>
#include "config.h"
#include "libavutil/attributes.h"
#ifdef __ARMCC_VERSION
#if HAVE_ARMV6
#define bswap_16 bswap_16
static av_always_inline av_const unsigned bswap_16(unsigned x)
{
__asm { rev16 x, x }
return x;
}
#define bswap_32 bswap_32
static av_always_inline av_const uint32_t bswap_32(uint32_t x)
{
return __rev(x);
}
#endif /* HAVE_ARMV6 */
#elif HAVE_INLINE_ASM
#if HAVE_ARMV6
#define bswap_16 bswap_16
static av_always_inline av_const unsigned bswap_16(unsigned x)
{
__asm__("rev16 %0, %0" : "+r"(x));
return x;
}
#endif
#define bswap_32 bswap_32
static av_always_inline av_const uint32_t bswap_32(uint32_t x)
{
#if HAVE_ARMV6
__asm__("rev %0, %0" : "+r"(x));
#else
uint32_t t;
__asm__ ("eor %1, %0, %0, ror #16 \n\t"
"bic %1, %1, #0xFF0000 \n\t"
"mov %0, %0, ror #8 \n\t"
"eor %0, %0, %1, lsr #8 \n\t"
: "+r"(x), "=&r"(t));
#endif /* HAVE_ARMV6 */
return x;
}
#endif /* __ARMCC_VERSION */
#endif /* AVUTIL_ARM_BSWAP_H */

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
*
* This file is part of FFmpeg.
*
* 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
* Lesser General Public License for more details.
*
* 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
*/
#ifndef AVUTIL_ARM_INTMATH_H
#define AVUTIL_ARM_INTMATH_H
#include "config.h"
#include "libavutil/attributes.h"
#if HAVE_INLINE_ASM
#if HAVE_ARMV6
static inline av_const int FASTDIV(int a, int b)
{
int r, t;
__asm__ volatile("cmp %3, #2 \n\t"
"ldr %1, [%4, %3, lsl #2] \n\t"
"lsrle %0, %2, #1 \n\t"
"smmulgt %0, %1, %2 \n\t"
: "=&r"(r), "=&r"(t) : "r"(a), "r"(b), "r"(ff_inverse));
return r;
}
#else
static inline av_const int FASTDIV(int a, int b)
{
int r, t;
__asm__ volatile("umull %1, %0, %2, %3"
: "=&r"(r), "=&r"(t) : "r"(a), "r"(ff_inverse[b]));
return r;
}
#endif
#define FASTDIV FASTDIV
#endif /* HAVE_INLINE_ASM */
#endif /* AVUTIL_ARM_INTMATH_H */

View File

@ -151,7 +151,7 @@ static inline av_const int16_t av_clip_int16(int a)
*/
static inline av_const int32_t av_clipl_int32(int64_t a)
{
if ((a+0x80000000u) & ~(0xFFFFFFFFULL)) return (a>>63) ^ 0x7FFFFFFF;
if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (a>>63) ^ 0x7FFFFFFF;
else return a;
}