Index: configure =================================================================== --- configure (revision 9814) +++ configure (working copy) @@ -1095,7 +1095,7 @@ 2.9-beos-991026*|2.9-beos-000224*) echo "R5/GG gcc" mmx="no" ;; - *20010315*) echo "BeBits gcc" + *20010315*|2.95.3*) echo "BeBits gcc" add_cflags "-fno-expensive-optimizations" ;; esac Index: libavformat/Makefile =================================================================== --- libavformat/Makefile (revision 9814) +++ libavformat/Makefile (working copy) @@ -69,6 +69,7 @@ OBJS-$(CONFIG_IMAGE2PIPE_MUXER) += img2.o OBJS-$(CONFIG_INGENIENT_DEMUXER) += raw.o OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o +OBJS-$(CONFIG_IPOD_MUXER) += movenc.o riff.o isom.o OBJS-$(CONFIG_M4V_DEMUXER) += raw.o OBJS-$(CONFIG_M4V_MUXER) += raw.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o riff.o Index: libavformat/tcp.c =================================================================== --- libavformat/tcp.c (revision 9814) +++ libavformat/tcp.c (working copy) @@ -88,11 +88,13 @@ break; } +#ifndef __BEOS__ /* test error */ optlen = sizeof(ret); getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen); if (ret != 0) goto fail; +#endif } s->fd = fd; return 0; Index: libavformat/movenc.c =================================================================== --- libavformat/movenc.c (revision 9814) +++ libavformat/movenc.c (working copy) @@ -36,6 +36,7 @@ #define MODE_PSP 3 // example working PSP command line: // ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4 #define MODE_3G2 4 +#define MODE_IPOD 5 typedef struct MOVIentry { unsigned int flags, size; @@ -54,6 +55,7 @@ long time; int64_t trackDuration; long sampleCount; + long sampleDuration; long sampleSize; int hasKeyframes; int hasBframes; @@ -572,6 +574,18 @@ return tag; } +static int mov_write_colr_tag(ByteIOContext *pb) +{ + put_be32( pb, 0x12 ); + put_tag( pb, "colr" ); + put_tag( pb, "nclc" ); + put_be16( pb, 6 ); + put_be16( pb, 1 ); + put_be16( pb, 6 ); + put_be32( pb, 0 ); + return 0x12; +} + static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track) { offset_t pos = url_ftell(pb); @@ -621,9 +635,22 @@ mov_write_d263_tag(pb); else if(track->enc->codec_id == CODEC_ID_SVQ3) mov_write_svq3_tag(pb); - else if(track->enc->codec_id == CODEC_ID_H264) - mov_write_avcc_tag(pb, track); + else if(track->enc->codec_id == CODEC_ID_H264) { + mov_write_avcc_tag(pb, track); + if (track->mode == MODE_IPOD) { + put_be32(pb, 0x1C); /* size ... reports as 28 in mp4box! */ + put_tag(pb, "uuid"); + put_be32(pb, 0x6B6840F2); + put_be32(pb, 0x5F244FC5); + put_be32(pb, 0xBA39A51B); + put_be32(pb, 0xCF0323F3); + put_be32(pb, 0x00000001); + put_be32(pb, 0x0000039C); + } + } + mov_write_colr_tag(pb); + return updateSize (pb, pos); } @@ -674,46 +701,18 @@ return atom_size; } +/* TODO: */ /* Time to sample atom */ static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track) { - MOV_stts_t *stts_entries; - uint32_t entries = -1; - uint32_t atom_size; - int i; - - if (track->enc->codec_type == CODEC_TYPE_AUDIO && !track->audio_vbr) { - stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */ - stts_entries[0].count = track->sampleCount; - stts_entries[0].duration = 1; - entries = 1; - } else { - stts_entries = av_malloc(track->entry * sizeof(*stts_entries)); /* worst case */ - for (i=0; ientry; i++) { - int64_t duration = i + 1 == track->entry ? - track->trackDuration - track->cluster[i].dts + track->cluster[0].dts : /* readjusting */ - track->cluster[i+1].dts - track->cluster[i].dts; - if (i && duration == stts_entries[entries].duration) { - stts_entries[entries].count++; /* compress */ - } else { - entries++; - stts_entries[entries].duration = duration; - stts_entries[entries].count = 1; - } - } - entries++; /* last one */ - } - atom_size = 16 + (entries * 8); - put_be32(pb, atom_size); /* size */ + put_be32(pb, 0x18); /* size */ put_tag(pb, "stts"); put_be32(pb, 0); /* version & flags */ - put_be32(pb, entries); /* entry count */ - for (i=0; isampleCount); /* sample count */ + put_be32(pb, track->sampleDuration); /* sample duration */ + return 0x18; } static int mov_write_dref_tag(ByteIOContext *pb) @@ -911,6 +910,10 @@ /* Track width and height, for visual only */ if(track->enc->codec_type == CODEC_TYPE_VIDEO) { double sample_aspect_ratio = av_q2d(track->enc->sample_aspect_ratio); + if (track->mode == MODE_IPOD) { + /* FIXME , I do not believe this is needed, bad assumption */ + sample_aspect_ratio = 1; + } if( !sample_aspect_ratio ) sample_aspect_ratio = 1; put_be32(pb, sample_aspect_ratio * track->enc->width*0x10000); put_be32(pb, track->enc->height*0x10000); @@ -1322,6 +1325,8 @@ for (i=0; inb_streams; i++) { if(mov->tracks[i].entry <= 0) continue; + mov->tracks[i].trackDuration = + (int64_t)mov->tracks[i].sampleCount * mov->tracks[i].sampleDuration; mov->tracks[i].time = mov->time; mov->tracks[i].trackID = i+1; } @@ -1369,6 +1374,8 @@ put_tag(pb, "MSNV"); else if ( mov->mode == MODE_MP4 ) put_tag(pb, "isom"); + else if ( mov->mode == MODE_IPOD ) + put_tag(pb, "isom"); else put_tag(pb, "qt "); @@ -1380,6 +1387,8 @@ put_tag(pb, "3g2a"); else if ( mov->mode == MODE_PSP ) put_tag(pb, "MSNV"); + else if ( mov->mode == MODE_IPOD ) + put_tag(pb, "mp41"); else if ( mov->mode == MODE_MP4 ) put_tag(pb, "mp41"); else @@ -1466,7 +1475,8 @@ else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3G2; else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV; else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP; - + else if (!strcmp("ipod", s->oformat->name)) mov->mode = MODE_IPOD; + mov_write_ftyp_tag(pb,s); if ( mov->mode == MODE_PSP ) { if ( s->nb_streams != 2 ) { @@ -1487,6 +1497,7 @@ if(st->codec->codec_type == CODEC_TYPE_VIDEO){ track->tag = mov_find_video_codec_tag(s, track); track->timescale = st->codec->time_base.den; + track->sampleDuration = st->codec->time_base.num; av_set_pts_info(st, 64, 1, st->codec->time_base.den); if (track->timescale > 100000) av_log(NULL, AV_LOG_WARNING, @@ -1496,6 +1507,7 @@ }else if(st->codec->codec_type == CODEC_TYPE_AUDIO){ track->tag = mov_find_audio_codec_tag(s, track); track->timescale = st->codec->sample_rate; + track->sampleDuration = st->codec->frame_size; av_set_pts_info(st, 64, 1, st->codec->sample_rate); if(!st->codec->frame_size){ av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i); @@ -1675,6 +1687,21 @@ .flags = AVFMT_GLOBALHEADER, }; #endif +#ifdef CONFIG_IPOD_MUXER +AVOutputFormat ipod_muxer = { + "ipod", + "ipod mp4 format", + "application/mp4", + "mp4,m4v,ipod", + sizeof(MOVContext), + CODEC_ID_AAC, + CODEC_ID_MPEG4, + mov_write_header, + mov_write_packet, + mov_write_trailer, + .flags = AVFMT_GLOBALHEADER, +}; +#endif #ifdef CONFIG_PSP_MUXER AVOutputFormat psp_muxer = { "psp", Index: libavformat/allformats.c =================================================================== --- libavformat/allformats.c (revision 9814) +++ libavformat/allformats.c (working copy) @@ -89,6 +89,9 @@ REGISTER_MUXDEMUX(IMAGE2PIPE, image2pipe); REGISTER_DEMUXER (INGENIENT, ingenient); REGISTER_DEMUXER (IPMOVIE, ipmovie); +#ifdef CONFIG_IPOD_MUXER + REGISTER_MUXER (IPOD, ipod); +#endif if (!ENABLE_NUT_DEMUXER) REGISTER_DEMUXER (LIBNUT, libnut); REGISTER_MUXER (LIBNUT, libnut); REGISTER_MUXDEMUX(M4V, m4v); Index: libavformat/allformats.h =================================================================== --- libavformat/allformats.h (revision 9814) +++ libavformat/allformats.h (working copy) @@ -142,6 +142,7 @@ extern AVOutputFormat image2pipe_muxer; extern AVOutputFormat image_muxer; extern AVOutputFormat imagepipe_muxer; +extern AVOutputFormat ipod_muxer; extern AVOutputFormat libnut_muxer; extern AVOutputFormat m4v_muxer; extern AVOutputFormat mjpeg_muxer;