mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-19 21:36:54 +00:00
minimum handling for mpeg4 video multicast from avi files
Originally committed as revision 1262 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
6891b9d458
commit
0fa45e19ce
89
ffserver.c
89
ffserver.c
@ -482,9 +482,9 @@ static void start_multicast(void)
|
|||||||
dest_addr.sin_port = htons(stream->multicast_port +
|
dest_addr.sin_port = htons(stream->multicast_port +
|
||||||
2 * stream_index);
|
2 * stream_index);
|
||||||
if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr) < 0) {
|
if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr) < 0) {
|
||||||
fprintf(stderr, "Could not open input stream %d for stream '%s'\n",
|
fprintf(stderr, "Could not open output stream '%s/streamid=%d'\n",
|
||||||
stream_index, stream->filename);
|
stream->filename, stream_index);
|
||||||
continue;
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2605,7 +2605,7 @@ static int prepare_sdp_description(FFStream *stream, UINT8 **pbuffer,
|
|||||||
struct in_addr my_ip)
|
struct in_addr my_ip)
|
||||||
{
|
{
|
||||||
ByteIOContext pb1, *pb = &pb1;
|
ByteIOContext pb1, *pb = &pb1;
|
||||||
int i, payload_type, port;
|
int i, payload_type, port, private_payload_type, j;
|
||||||
const char *ipstr, *title, *mediatype;
|
const char *ipstr, *title, *mediatype;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
|
|
||||||
@ -2627,6 +2627,7 @@ static int prepare_sdp_description(FFStream *stream, UINT8 **pbuffer,
|
|||||||
url_fprintf(pb, "c=IN IP4 %s\n", inet_ntoa(stream->multicast_ip));
|
url_fprintf(pb, "c=IN IP4 %s\n", inet_ntoa(stream->multicast_ip));
|
||||||
}
|
}
|
||||||
/* for each stream, we output the necessary info */
|
/* for each stream, we output the necessary info */
|
||||||
|
private_payload_type = 96;
|
||||||
for(i = 0; i < stream->nb_streams; i++) {
|
for(i = 0; i < stream->nb_streams; i++) {
|
||||||
st = stream->streams[i];
|
st = stream->streams[i];
|
||||||
switch(st->codec.codec_type) {
|
switch(st->codec.codec_type) {
|
||||||
@ -2643,6 +2644,8 @@ static int prepare_sdp_description(FFStream *stream, UINT8 **pbuffer,
|
|||||||
/* NOTE: the port indication is not correct in case of
|
/* NOTE: the port indication is not correct in case of
|
||||||
unicast. It is not an issue because RTSP gives it */
|
unicast. It is not an issue because RTSP gives it */
|
||||||
payload_type = rtp_get_payload_type(&st->codec);
|
payload_type = rtp_get_payload_type(&st->codec);
|
||||||
|
if (payload_type < 0)
|
||||||
|
payload_type = private_payload_type++;
|
||||||
if (stream->is_multicast) {
|
if (stream->is_multicast) {
|
||||||
port = stream->multicast_port + 2 * i;
|
port = stream->multicast_port + 2 * i;
|
||||||
} else {
|
} else {
|
||||||
@ -2650,9 +2653,37 @@ static int prepare_sdp_description(FFStream *stream, UINT8 **pbuffer,
|
|||||||
}
|
}
|
||||||
url_fprintf(pb, "m=%s %d RTP/AVP %d\n",
|
url_fprintf(pb, "m=%s %d RTP/AVP %d\n",
|
||||||
mediatype, port, payload_type);
|
mediatype, port, payload_type);
|
||||||
|
if (payload_type >= 96) {
|
||||||
|
/* for private payload type, we need to give more info */
|
||||||
|
switch(st->codec.codec_id) {
|
||||||
|
case CODEC_ID_MPEG4:
|
||||||
|
{
|
||||||
|
uint8_t *data;
|
||||||
|
url_fprintf(pb, "a=rtpmap:%d MP4V-ES/%d\n",
|
||||||
|
payload_type, 90000);
|
||||||
|
/* we must also add the mpeg4 header */
|
||||||
|
data = st->codec.extradata;
|
||||||
|
if (data) {
|
||||||
|
url_fprintf(pb, "a=fmtp:%d config=");
|
||||||
|
for(j=0;j<st->codec.extradata_size;j++) {
|
||||||
|
url_fprintf(pb, "%02x", data[j]);
|
||||||
|
}
|
||||||
|
url_fprintf(pb, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* XXX: add other codecs ? */
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
url_fprintf(pb, "a=control:streamid=%d\n", i);
|
url_fprintf(pb, "a=control:streamid=%d\n", i);
|
||||||
}
|
}
|
||||||
return url_close_dyn_buf(pb, pbuffer);
|
return url_close_dyn_buf(pb, pbuffer);
|
||||||
|
fail:
|
||||||
|
url_close_dyn_buf(pb, pbuffer);
|
||||||
|
av_free(*pbuffer);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtsp_cmd_describe(HTTPContext *c, const char *url)
|
static void rtsp_cmd_describe(HTTPContext *c, const char *url)
|
||||||
@ -3183,6 +3214,54 @@ void remove_stream(FFStream *stream)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* specific mpeg4 handling : we extract the raw parameters */
|
||||||
|
void extract_mpeg4_header(AVFormatContext *infile)
|
||||||
|
{
|
||||||
|
int mpeg4_count, i, size;
|
||||||
|
AVPacket pkt;
|
||||||
|
AVStream *st;
|
||||||
|
const UINT8 *p;
|
||||||
|
|
||||||
|
mpeg4_count = 0;
|
||||||
|
for(i=0;i<infile->nb_streams;i++) {
|
||||||
|
st = infile->streams[i];
|
||||||
|
if (st->codec.codec_id == CODEC_ID_MPEG4 &&
|
||||||
|
st->codec.extradata == NULL) {
|
||||||
|
mpeg4_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!mpeg4_count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("MPEG4 without extra data: trying to find header\n");
|
||||||
|
while (mpeg4_count > 0) {
|
||||||
|
if (av_read_packet(infile, &pkt) < 0)
|
||||||
|
break;
|
||||||
|
st = infile->streams[pkt.stream_index];
|
||||||
|
if (st->codec.codec_id == CODEC_ID_MPEG4 &&
|
||||||
|
st->codec.extradata == NULL) {
|
||||||
|
/* fill extradata with the header */
|
||||||
|
/* XXX: we make hard suppositions here ! */
|
||||||
|
p = pkt.data;
|
||||||
|
while (p < pkt.data + pkt.size - 4) {
|
||||||
|
/* stop when vop header is found */
|
||||||
|
if (p[0] == 0x00 && p[1] == 0x00 &&
|
||||||
|
p[2] == 0x01 && p[3] == 0xb6) {
|
||||||
|
size = p - pkt.data;
|
||||||
|
// av_hex_dump(pkt.data, size);
|
||||||
|
st->codec.extradata = av_malloc(size);
|
||||||
|
st->codec.extradata_size = size;
|
||||||
|
memcpy(st->codec.extradata, pkt.data, size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
mpeg4_count--;
|
||||||
|
}
|
||||||
|
av_free_packet(&pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* compute the needed AVStream for each file */
|
/* compute the needed AVStream for each file */
|
||||||
void build_file_streams(void)
|
void build_file_streams(void)
|
||||||
{
|
{
|
||||||
@ -3213,6 +3292,8 @@ void build_file_streams(void)
|
|||||||
av_close_input_file(infile);
|
av_close_input_file(infile);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
extract_mpeg4_header(infile);
|
||||||
|
|
||||||
for(i=0;i<infile->nb_streams;i++) {
|
for(i=0;i<infile->nb_streams;i++) {
|
||||||
add_av_stream1(stream, &infile->streams[i]->codec);
|
add_av_stream1(stream, &infile->streams[i]->codec);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user