void ff_parse_specific_params(AVStream *st, int *au_rate, int *au_ssize, int *au_scale) { AVCodecContext *codec = st->codec; int gcd; int audio_frame_size; audio_frame_size = av_get_audio_frame_duration(codec, 0); *au_ssize = codec->block_align; if (audio_frame_size && codec->sample_rate) { *au_scale = audio_frame_size; *au_rate = codec->sample_rate; } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO || codec->codec_type == AVMEDIA_TYPE_DATA || codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { *au_scale = st->time_base.num; *au_rate = st->time_base.den; } else { *au_scale = codec->block_align ? codec->block_align * 8 : 8; *au_rate = codec->bit_rate ? codec->bit_rate : 8 * codec->sample_rate; } gcd = av_gcd(*au_scale, *au_rate); *au_scale /= gcd; *au_rate /= gcd; }
void ff_parse_specific_params(AVStream *st, int *au_rate, int *au_ssize, int *au_scale) { AVCodecContext *codec = st->codec; int gcd; int audio_frame_size; /* We use the known constant frame size for the codec if known, otherwise * fall back on using AVCodecContext.frame_size, which is not as reliable * for indicating packet duration. */ audio_frame_size = av_get_audio_frame_duration(codec, 0); if (!audio_frame_size) audio_frame_size = codec->frame_size; *au_ssize = codec->block_align; if (audio_frame_size && codec->sample_rate) { *au_scale = audio_frame_size; *au_rate = codec->sample_rate; } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO || codec->codec_type == AVMEDIA_TYPE_DATA || codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { *au_scale = st->time_base.num; *au_rate = st->time_base.den; } else { *au_scale = codec->block_align ? codec->block_align * 8 : 8; *au_rate = codec->bit_rate ? codec->bit_rate : 8 * codec->sample_rate; } gcd = av_gcd(*au_scale, *au_rate); *au_scale /= gcd; *au_rate /= gcd; }
static int rm_write_header(AVFormatContext *s) { RMMuxContext *rm = s->priv_data; StreamInfo *stream; int n; AVCodecContext *codec; if (s->nb_streams > 2) { av_log(s, AV_LOG_ERROR, "At most 2 streams are currently supported for muxing in RM\n"); return AVERROR_PATCHWELCOME; } for(n=0;n<s->nb_streams;n++) { AVStream *st = s->streams[n]; int frame_size; s->streams[n]->id = n; codec = s->streams[n]->codec; stream = &rm->streams[n]; memset(stream, 0, sizeof(StreamInfo)); stream->num = n; stream->bit_rate = codec->bit_rate; stream->enc = codec; switch(codec->codec_type) { case AVMEDIA_TYPE_AUDIO: rm->audio_stream = stream; frame_size = av_get_audio_frame_duration(codec, 0); stream->frame_rate = (AVRational){codec->sample_rate, frame_size}; /* XXX: dummy values */ stream->packet_max_size = 1024; stream->nb_packets = 0; stream->total_frames = stream->nb_packets; break; case AVMEDIA_TYPE_VIDEO: rm->video_stream = stream; // TODO: should be avg_frame_rate stream->frame_rate = av_inv_q(st->time_base); /* XXX: dummy values */ stream->packet_max_size = 4096; stream->nb_packets = 0; stream->total_frames = stream->nb_packets; break; default: return -1; } } if (rv10_write_header(s, 0, 0)) return AVERROR_INVALIDDATA; avio_flush(s->pb); return 0; }
static int rm_write_header(AVFormatContext *s) { RMMuxContext *rm = s->priv_data; StreamInfo *stream; int n; AVCodecContext *codec; for(n=0;n<s->nb_streams;n++) { AVStream *st = s->streams[n]; int frame_size; s->streams[n]->id = n; codec = s->streams[n]->codec; stream = &rm->streams[n]; memset(stream, 0, sizeof(StreamInfo)); stream->num = n; stream->bit_rate = codec->bit_rate; stream->enc = codec; switch(codec->codec_type) { case AVMEDIA_TYPE_AUDIO: rm->audio_stream = stream; frame_size = av_get_audio_frame_duration(codec, 0); stream->frame_rate = (float)codec->sample_rate / (float)frame_size; /* XXX: dummy values */ stream->packet_max_size = 1024; stream->nb_packets = 0; stream->total_frames = stream->nb_packets; break; case AVMEDIA_TYPE_VIDEO: rm->video_stream = stream; // TODO: should be avg_frame_rate stream->frame_rate = (float)st->time_base.den / (float)st->time_base.num; /* XXX: dummy values */ stream->packet_max_size = 4096; stream->nb_packets = 0; stream->total_frames = stream->nb_packets; break; default: return -1; } } if (rv10_write_header(s, 0, 0)) return AVERROR_INVALIDDATA; avio_flush(s->pb); return 0; }
static int adp_read_header(AVFormatContext *s) { AVStream *st; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_ADPCM_DTK; st->codec->channel_layout = AV_CH_LAYOUT_STEREO; st->codec->channels = 2; st->codec->sample_rate = 48000; st->start_time = 0; if (s->pb->seekable) st->duration = av_get_audio_frame_duration(st->codec, avio_size(s->pb)); avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); return 0; }
static int msf_read_header(AVFormatContext *s) { unsigned codec, align, size; AVStream *st; avio_skip(s->pb, 4); st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; codec = avio_rb32(s->pb); st->codec->channels = avio_rb32(s->pb); if (st->codec->channels <= 0) return AVERROR_INVALIDDATA; size = avio_rb32(s->pb); st->codec->sample_rate = avio_rb32(s->pb); if (st->codec->sample_rate <= 0) return AVERROR_INVALIDDATA; align = avio_rb32(s->pb) ; if (align > INT_MAX / st->codec->channels) return AVERROR_INVALIDDATA; st->codec->block_align = align; switch (codec) { case 0: st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; break; case 3: st->codec->block_align = 16 * st->codec->channels; st->codec->codec_id = AV_CODEC_ID_ADPCM_PSX; break; case 7: st->need_parsing = AVSTREAM_PARSE_FULL_RAW; st->codec->codec_id = AV_CODEC_ID_MP3; break; default: avpriv_request_sample(s, "Codec %d", codec); return AVERROR_PATCHWELCOME; } st->duration = av_get_audio_frame_duration(st->codec, size); avio_skip(s->pb, 0x40 - avio_tell(s->pb)); avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); return 0; }
static int swf_write_audio(AVFormatContext *s, AVCodecContext *enc, uint8_t *buf, int size) { SWFContext *swf = s->priv_data; /* Flash Player limit */ if (swf->swf_frame_number == 16000) av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n"); if (av_fifo_size(swf->audio_fifo) + size > AUDIO_FIFO_SIZE) { av_log(s, AV_LOG_ERROR, "audio fifo too small to mux audio essence\n"); return -1; } av_fifo_generic_write(swf->audio_fifo, buf, size, NULL); swf->sound_samples += av_get_audio_frame_duration(enc, size); /* if audio only stream make sure we add swf frames */ if (!swf->video_enc) swf_write_video(s, enc, 0, 0); return 0; }
/* Returns the number of sound data frames or negative on error */ static unsigned int get_aiff_header(AVFormatContext *s, int size, unsigned version) { AVIOContext *pb = s->pb; AVCodecContext *codec = s->streams[0]->codec; AIFFInputContext *aiff = s->priv_data; int exp; uint64_t val; double sample_rate; unsigned int num_frames; if (size & 1) size++; codec->codec_type = AVMEDIA_TYPE_AUDIO; codec->channels = avio_rb16(pb); num_frames = avio_rb32(pb); codec->bits_per_coded_sample = avio_rb16(pb); exp = avio_rb16(pb); val = avio_rb64(pb); sample_rate = ldexp(val, exp - 16383 - 63); codec->sample_rate = sample_rate; size -= 18; /* get codec id for AIFF-C */ if (version == AIFF_C_VERSION1) { codec->codec_tag = avio_rl32(pb); codec->codec_id = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag); size -= 4; } if (version != AIFF_C_VERSION1 || codec->codec_id == AV_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); aiff->block_duration = 1; } else { switch (codec->codec_id) { case AV_CODEC_ID_PCM_F32BE: case AV_CODEC_ID_PCM_F64BE: case AV_CODEC_ID_PCM_S16LE: case AV_CODEC_ID_PCM_ALAW: case AV_CODEC_ID_PCM_MULAW: aiff->block_duration = 1; break; case AV_CODEC_ID_ADPCM_IMA_QT: codec->block_align = 34*codec->channels; break; case AV_CODEC_ID_MACE3: codec->block_align = 2*codec->channels; break; case AV_CODEC_ID_MACE6: codec->block_align = 1*codec->channels; break; case AV_CODEC_ID_GSM: codec->block_align = 33; break; default: aiff->block_duration = 1; break; } if (codec->block_align > 0) aiff->block_duration = av_get_audio_frame_duration(codec, codec->block_align); } /* 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 = (av_get_bits_per_sample(codec->codec_id) * codec->channels) >> 3; if (aiff->block_duration) { codec->bit_rate = codec->sample_rate * (codec->block_align << 3) / aiff->block_duration; } /* Chunk is over */ if (size) avio_skip(pb, size); return num_frames; }
static int rsd_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; int i, version, start = 0x800; AVCodecContext *codec; AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avio_skip(pb, 3); // "RSD" version = avio_r8(pb) - '0'; codec = st->codec; codec->codec_type = AVMEDIA_TYPE_AUDIO; codec->codec_tag = avio_rl32(pb); codec->codec_id = ff_codec_get_id(rsd_tags, codec->codec_tag); if (!codec->codec_id) { char tag_buf[5]; av_get_codec_tag_string(tag_buf, sizeof(tag_buf), codec->codec_tag); for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) { if (codec->codec_tag == rsd_unsupported_tags[i]) { avpriv_request_sample(s, "Codec tag: %s", tag_buf); return AVERROR_PATCHWELCOME; } } av_log(s, AV_LOG_ERROR, "Unknown codec tag: %s\n", tag_buf); return AVERROR_INVALIDDATA; } codec->channels = avio_rl32(pb); if (!codec->channels) return AVERROR_INVALIDDATA; avio_skip(pb, 4); // Bit depth codec->sample_rate = avio_rl32(pb); if (!codec->sample_rate) return AVERROR_INVALIDDATA; avio_skip(pb, 4); // Unknown switch (codec->codec_id) { case AV_CODEC_ID_ADPCM_IMA_RAD: codec->block_align = 20 * codec->channels; if (pb->seekable) st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_THP: /* RSD3GADP is mono, so only alloc enough memory to store the coeff table for a single channel. */ start = avio_rl32(pb); if (ff_get_extradata(codec, s->pb, 32) < 0) return AVERROR(ENOMEM); for (i = 0; i < 16; i++) AV_WB16(codec->extradata + i * 2, AV_RL16(codec->extradata + i * 2)); if (pb->seekable) st->duration = (avio_size(pb) - start) / 8 * 14; break; case AV_CODEC_ID_PCM_S16LE: case AV_CODEC_ID_PCM_S16BE: if (version != 4) start = avio_rl32(pb); if (pb->seekable) st->duration = (avio_size(pb) - start) / 2 / codec->channels; break; } avio_skip(pb, start - avio_tell(pb)); avpriv_set_pts_info(st, 64, 1, codec->sample_rate); return 0; }
static int rsd_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; int i, ret, version, start = 0x800; AVCodecContext *codec; AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avio_skip(pb, 3); // "RSD" version = avio_r8(pb) - '0'; codec = st->codec; codec->codec_type = AVMEDIA_TYPE_AUDIO; codec->codec_tag = avio_rl32(pb); codec->codec_id = ff_codec_get_id(rsd_tags, codec->codec_tag); if (!codec->codec_id) { char tag_buf[32]; av_get_codec_tag_string(tag_buf, sizeof(tag_buf), codec->codec_tag); for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) { if (codec->codec_tag == rsd_unsupported_tags[i]) { avpriv_request_sample(s, "Codec tag: %s", tag_buf); return AVERROR_PATCHWELCOME; } } av_log(s, AV_LOG_ERROR, "Unknown codec tag: %s\n", tag_buf); return AVERROR_INVALIDDATA; } codec->channels = avio_rl32(pb); if (codec->channels <= 0 || codec->channels > INT_MAX / 36) { av_log(s, AV_LOG_ERROR, "Invalid number of channels: %d\n", codec->channels); return AVERROR_INVALIDDATA; } avio_skip(pb, 4); // Bit depth codec->sample_rate = avio_rl32(pb); if (!codec->sample_rate) return AVERROR_INVALIDDATA; avio_skip(pb, 4); // Unknown switch (codec->codec_id) { case AV_CODEC_ID_XMA2: codec->block_align = 2048; ff_alloc_extradata(codec, 34); if (!codec->extradata) return AVERROR(ENOMEM); memset(codec->extradata, 0, 34); break; case AV_CODEC_ID_ADPCM_PSX: codec->block_align = 16 * codec->channels; if (pb->seekable) st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_IMA_RAD: codec->block_align = 20 * codec->channels; if (pb->seekable) st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_IMA_WAV: if (version == 2) start = avio_rl32(pb); codec->bits_per_coded_sample = 4; codec->block_align = 36 * codec->channels; if (pb->seekable) st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_THP_LE: /* RSD3GADP is mono, so only alloc enough memory to store the coeff table for a single channel. */ start = avio_rl32(pb); if ((ret = ff_get_extradata(codec, s->pb, 32)) < 0) return ret; if (pb->seekable) st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_THP: codec->block_align = 8 * codec->channels; avio_skip(s->pb, 0x1A4 - avio_tell(s->pb)); if ((ret = ff_alloc_extradata(st->codec, 32 * st->codec->channels)) < 0) return ret; for (i = 0; i < st->codec->channels; i++) { avio_read(s->pb, st->codec->extradata + 32 * i, 32); avio_skip(s->pb, 8); } if (pb->seekable) st->duration = (avio_size(pb) - start) / (8 * st->codec->channels) * 14; break; case AV_CODEC_ID_PCM_S16LE: case AV_CODEC_ID_PCM_S16BE: if (version != 4) start = avio_rl32(pb); if (pb->seekable) st->duration = (avio_size(pb) - start) / 2 / codec->channels; break; } avio_skip(pb, start - avio_tell(pb)); if (codec->codec_id == AV_CODEC_ID_XMA2) { avio_skip(pb, avio_rb32(pb) + avio_rb32(pb)); st->duration = avio_rb32(pb); } avpriv_set_pts_info(st, 64, 1, codec->sample_rate); return 0; }
static int rtp_write_header(AVFormatContext *s1) { RTPMuxContext *s = s1->priv_data; int n; AVStream *st; if (s1->nb_streams != 1) { av_log(s1, AV_LOG_ERROR, "Only one stream supported in the RTP muxer\n"); return AVERROR(EINVAL); } st = s1->streams[0]; if (!is_supported(st->codec->codec_id)) { av_log(s1, AV_LOG_ERROR, "Unsupported codec %s\n", avcodec_get_name(st->codec->codec_id)); return -1; } if (s->payload_type < 0) s->payload_type = ff_rtp_get_payload_type(s1, st->codec); s->base_timestamp = av_get_random_seed(); s->timestamp = s->base_timestamp; s->cur_timestamp = 0; if (!s->ssrc) s->ssrc = av_get_random_seed(); s->first_packet = 1; s->first_rtcp_ntp_time = ff_ntp_time(); if (s1->start_time_realtime) /* Round the NTP time to whole milliseconds. */ s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 + NTP_OFFSET_US; if (s1->packet_size) { if (s1->pb->max_packet_size) s1->packet_size = FFMIN(s1->packet_size, s1->pb->max_packet_size); } else s1->packet_size = s1->pb->max_packet_size; if (s1->packet_size <= 12) { av_log(s1, AV_LOG_ERROR, "Max packet size %d too low\n", s1->packet_size); return AVERROR(EIO); } s->buf = av_malloc(s1->packet_size); if (s->buf == NULL) { return AVERROR(ENOMEM); } s->max_payload_size = s1->packet_size - 12; s->max_frames_per_packet = 0; if (s1->max_delay > 0) { if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { int frame_size = av_get_audio_frame_duration(st->codec, 0); if (!frame_size) frame_size = st->codec->frame_size; if (frame_size == 0) { av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n"); } else { s->max_frames_per_packet = av_rescale_q_rnd(s1->max_delay, AV_TIME_BASE_Q, (AVRational){ frame_size, st->codec->sample_rate }, AV_ROUND_DOWN); } } if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { /* FIXME: We should round down here... */ s->max_frames_per_packet = av_rescale_q(s1->max_delay, (AVRational){1, 1000000}, st->codec->time_base); } } avpriv_set_pts_info(st, 32, 1, 90000); switch(st->codec->codec_id) { case AV_CODEC_ID_MP2: case AV_CODEC_ID_MP3: s->buf_ptr = s->buf + 4; break; case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: break; case AV_CODEC_ID_MPEG2TS: n = s->max_payload_size / TS_PACKET_SIZE; if (n < 1) n = 1; s->max_payload_size = n * TS_PACKET_SIZE; s->buf_ptr = s->buf; break; case AV_CODEC_ID_H264: /* check for H.264 MP4 syntax */ if (st->codec->extradata_size > 4 && st->codec->extradata[0] == 1) { s->nal_length_size = (st->codec->extradata[4] & 0x03) + 1; } break; case AV_CODEC_ID_VORBIS: case AV_CODEC_ID_THEORA: if (!s->max_frames_per_packet) s->max_frames_per_packet = 15; s->max_frames_per_packet = av_clip(s->max_frames_per_packet, 1, 15); s->max_payload_size -= 6; // ident+frag+tdt/vdt+pkt_num+pkt_length s->num_frames = 0; goto defaultcase; case AV_CODEC_ID_VP8: av_log(s1, AV_LOG_ERROR, "RTP VP8 payload implementation is " "incompatible with the latest spec drafts.\n"); break; case AV_CODEC_ID_ADPCM_G722: /* Due to a historical error, the clock rate for G722 in RTP is * 8000, even if the sample rate is 16000. See RFC 3551. */ avpriv_set_pts_info(st, 32, 1, 8000); break; case AV_CODEC_ID_ILBC: if (st->codec->block_align != 38 && st->codec->block_align != 50) { av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n"); goto fail; } if (!s->max_frames_per_packet) s->max_frames_per_packet = 1; s->max_frames_per_packet = FFMIN(s->max_frames_per_packet, s->max_payload_size / st->codec->block_align); goto defaultcase; case AV_CODEC_ID_AMR_NB: case AV_CODEC_ID_AMR_WB: if (!s->max_frames_per_packet) s->max_frames_per_packet = 12; if (st->codec->codec_id == AV_CODEC_ID_AMR_NB) n = 31; else n = 61; /* max_header_toc_size + the largest AMR payload must fit */ if (1 + s->max_frames_per_packet + n > s->max_payload_size) { av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n"); goto fail; } if (st->codec->channels != 1) { av_log(s1, AV_LOG_ERROR, "Only mono is supported\n"); goto fail; } case AV_CODEC_ID_AAC: s->num_frames = 0; default: defaultcase: if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); } s->buf_ptr = s->buf; break; } return 0; fail: av_freep(&s->buf); return AVERROR(EINVAL); }
int VideoStore::writeAudioFramePacket(AVPacket *ipkt, AVStream *input_st){ /* See 01349 of http://www.ffmpeg.org/doxygen/trunk/ffmpeg_8c-source.html do_streamcopy */ if(!audio_st) return -1;//FIXME -ve return codes do not free packet in ffmpeg_camera at the moment /*if(!keyframeMessage) return -1;*/ char szErr[1024]; int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, video_st->time_base); AVPacket opkt; AVPicture pict;//Not sure how much we need this av_init_packet(&opkt); //opkt.stream_index = audio_st->index; //FIXME does the PTS/DTS code below still apply to our audio the same way? //Scale the PTS of the outgoing packet to be the correct time base if (ipkt->pts != AV_NOPTS_VALUE) opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, audio_st->time_base) - ost_tb_start_time; else opkt.pts = AV_NOPTS_VALUE; //Scale the DTS of the outgoing packet to be the correct time base if(ipkt->dts == AV_NOPTS_VALUE) opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, audio_st->time_base); else opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, audio_st->time_base); opkt.dts -= ost_tb_start_time; if (audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && ipkt->dts != AV_NOPTS_VALUE) { int duration = av_get_audio_frame_duration(input_st->codec, ipkt->size); if(!duration) duration = input_st->codec->frame_size; //FIXME where to get filter_in_rescale_delta_last opkt.dts = opkt.pts = av_rescale_delta(input_st->time_base, ipkt->dts, (AVRational){1, input_st->codec->sample_rate}, duration, &filter_in_rescale_delta_last, audio_st->time_base) - ost_tb_start_time; } opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, audio_st->time_base); opkt.pos=-1; opkt.flags = ipkt->flags; //TODO: Should be checking if not H264, mpeg1, etc //Maybe the check isn't needed if we're only going to do this for H264 video incoming opkt.data = ipkt->data; opkt.size = ipkt->size; opkt.stream_index = ipkt->stream_index; /*opkt.flags |= AV_PKT_FLAG_KEY;*/ int ret; ret = av_interleaved_write_frame(oc, &opkt); if(ret<0){ Fatal("Error encoding audio frame packet: %s\n", av_make_error_string(szErr,1024,ret)); } av_free_packet(&opkt); return 0; }
static int rv10_write_header(AVFormatContext *ctx, int data_size, int index_pos) { RMMuxContext *rm = ctx->priv_data; AVIOContext *s = ctx->pb; StreamInfo *stream; unsigned char *data_offset_ptr, *start_ptr; const char *desc, *mimetype; int nb_packets, packet_total_size, packet_max_size, size, packet_avg_size, i; int bit_rate, v, duration, flags, data_pos; AVDictionaryEntry *tag; start_ptr = s->buf_ptr; ffio_wfourcc(s, ".RMF"); avio_wb32(s,18); /* header size */ avio_wb16(s,0); avio_wb32(s,0); avio_wb32(s,4 + ctx->nb_streams); /* num headers */ ffio_wfourcc(s,"PROP"); avio_wb32(s, 50); avio_wb16(s, 0); packet_max_size = 0; packet_total_size = 0; nb_packets = 0; bit_rate = 0; duration = 0; for(i=0;i<ctx->nb_streams;i++) { StreamInfo *stream = &rm->streams[i]; bit_rate += stream->bit_rate; if (stream->packet_max_size > packet_max_size) packet_max_size = stream->packet_max_size; nb_packets += stream->nb_packets; packet_total_size += stream->packet_total_size; /* select maximum duration */ v = (int) (1000.0 * (float)stream->total_frames / stream->frame_rate); if (v > duration) duration = v; } avio_wb32(s, bit_rate); /* max bit rate */ avio_wb32(s, bit_rate); /* avg bit rate */ avio_wb32(s, packet_max_size); /* max packet size */ if (nb_packets > 0) packet_avg_size = packet_total_size / nb_packets; else packet_avg_size = 0; avio_wb32(s, packet_avg_size); /* avg packet size */ avio_wb32(s, nb_packets); /* num packets */ avio_wb32(s, duration); /* duration */ avio_wb32(s, BUFFER_DURATION); /* preroll */ avio_wb32(s, index_pos); /* index offset */ /* computation of data the data offset */ data_offset_ptr = s->buf_ptr; avio_wb32(s, 0); /* data offset : will be patched after */ avio_wb16(s, ctx->nb_streams); /* num streams */ flags = 1 | 2; /* save allowed & perfect play */ if (!s->seekable) flags |= 4; /* live broadcast */ avio_wb16(s, flags); /* comments */ ffio_wfourcc(s,"CONT"); size = 4 * 2 + 10; for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) { tag = av_dict_get(ctx->metadata, ff_rm_metadata[i], NULL, 0); if(tag) size += strlen(tag->value); } avio_wb32(s,size); avio_wb16(s,0); for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) { tag = av_dict_get(ctx->metadata, ff_rm_metadata[i], NULL, 0); put_str(s, tag ? tag->value : ""); } for(i=0;i<ctx->nb_streams;i++) { int codec_data_size; stream = &rm->streams[i]; if (stream->enc->codec_type == AVMEDIA_TYPE_AUDIO) { desc = "The Audio Stream"; mimetype = "audio/x-pn-realaudio"; codec_data_size = 73; } else { desc = "The Video Stream"; mimetype = "video/x-pn-realvideo"; codec_data_size = 34; } ffio_wfourcc(s,"MDPR"); size = 10 + 9 * 4 + strlen(desc) + strlen(mimetype) + codec_data_size; avio_wb32(s, size); avio_wb16(s, 0); avio_wb16(s, i); /* stream number */ avio_wb32(s, stream->bit_rate); /* max bit rate */ avio_wb32(s, stream->bit_rate); /* avg bit rate */ avio_wb32(s, stream->packet_max_size); /* max packet size */ if (stream->nb_packets > 0) packet_avg_size = stream->packet_total_size / stream->nb_packets; else packet_avg_size = 0; avio_wb32(s, packet_avg_size); /* avg packet size */ avio_wb32(s, 0); /* start time */ avio_wb32(s, BUFFER_DURATION); /* preroll */ /* duration */ if (!s->seekable || !stream->total_frames) avio_wb32(s, (int)(3600 * 1000)); else avio_wb32(s, (int)(stream->total_frames * 1000 / stream->frame_rate)); put_str8(s, desc); put_str8(s, mimetype); avio_wb32(s, codec_data_size); if (stream->enc->codec_type == AVMEDIA_TYPE_AUDIO) { int coded_frame_size, fscode, sample_rate; int frame_size = av_get_audio_frame_duration(stream->enc, 0); sample_rate = stream->enc->sample_rate; coded_frame_size = (stream->enc->bit_rate * frame_size) / (8 * sample_rate); /* audio codec info */ avio_write(s, ".ra", 3); avio_w8(s, 0xfd); avio_wb32(s, 0x00040000); /* version */ ffio_wfourcc(s, ".ra4"); avio_wb32(s, 0x01b53530); /* stream length */ avio_wb16(s, 4); /* unknown */ avio_wb32(s, 0x39); /* header size */ switch(sample_rate) { case 48000: case 24000: case 12000: fscode = 1; break; default: case 44100: case 22050: case 11025: fscode = 2; break; case 32000: case 16000: case 8000: fscode = 3; } avio_wb16(s, fscode); /* codec additional info, for AC-3, seems to be a frequency code */ /* special hack to compensate rounding errors... */ if (coded_frame_size == 557) coded_frame_size--; avio_wb32(s, coded_frame_size); /* frame length */ avio_wb32(s, 0x51540); /* unknown */ avio_wb32(s, 0x249f0); /* unknown */ avio_wb32(s, 0x249f0); /* unknown */ avio_wb16(s, 0x01); /* frame length : seems to be very important */ avio_wb16(s, coded_frame_size); avio_wb32(s, 0); /* unknown */ avio_wb16(s, stream->enc->sample_rate); /* sample rate */ avio_wb32(s, 0x10); /* unknown */ avio_wb16(s, stream->enc->channels); put_str8(s, "Int0"); /* codec name */ if (stream->enc->codec_tag) { avio_w8(s, 4); /* tag length */ avio_wl32(s, stream->enc->codec_tag); } else { av_log(ctx, AV_LOG_ERROR, "Invalid codec tag\n"); return -1; } avio_wb16(s, 0); /* title length */ avio_wb16(s, 0); /* author length */ avio_wb16(s, 0); /* copyright length */ avio_w8(s, 0); /* end of header */ } else { /* video codec info */ avio_wb32(s,34); /* size */ ffio_wfourcc(s, "VIDO"); if(stream->enc->codec_id == AV_CODEC_ID_RV10) ffio_wfourcc(s,"RV10"); else ffio_wfourcc(s,"RV20"); avio_wb16(s, stream->enc->width); avio_wb16(s, stream->enc->height); avio_wb16(s, (int) stream->frame_rate); /* frames per seconds ? */ avio_wb32(s,0); /* unknown meaning */ avio_wb16(s, (int) stream->frame_rate); /* unknown meaning */ avio_wb32(s,0); /* unknown meaning */ avio_wb16(s, 8); /* unknown meaning */ /* Seems to be the codec version: only use basic H263. The next versions seems to add a diffential DC coding as in MPEG... nothing new under the sun */ if(stream->enc->codec_id == AV_CODEC_ID_RV10) avio_wb32(s,0x10000000); else avio_wb32(s,0x20103001); //avio_wb32(s,0x10003000); } } /* patch data offset field */ data_pos = s->buf_ptr - start_ptr; rm->data_pos = data_pos; data_offset_ptr[0] = data_pos >> 24; data_offset_ptr[1] = data_pos >> 16; data_offset_ptr[2] = data_pos >> 8; data_offset_ptr[3] = data_pos; /* data stream */ ffio_wfourcc(s, "DATA"); avio_wb32(s,data_size + 10 + 8); avio_wb16(s,0); avio_wb32(s, nb_packets); /* number of packets */ avio_wb32(s,0); /* next data header */ return 0; }
int ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) { VocDecContext *voc = s->priv_data; AVCodecContext *dec = st->codec; AVIOContext *pb = s->pb; VocType type; int size, tmp_codec=-1; int sample_rate = 0; int channels = 1; int64_t duration; int ret; av_add_index_entry(st, avio_tell(pb), voc->pts, voc->remaining_size, 0, AVINDEX_KEYFRAME); while (!voc->remaining_size) { type = avio_r8(pb); if (type == VOC_TYPE_EOF) return AVERROR_EOF; voc->remaining_size = avio_rl24(pb); if (!voc->remaining_size) { if (!s->pb->seekable) return AVERROR(EIO); voc->remaining_size = avio_size(pb) - avio_tell(pb); } max_size -= 4; switch (type) { case VOC_TYPE_VOICE_DATA: if (!dec->sample_rate) { dec->sample_rate = 1000000 / (256 - avio_r8(pb)); if (sample_rate) dec->sample_rate = sample_rate; avpriv_set_pts_info(st, 64, 1, dec->sample_rate); dec->channels = channels; dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); } else avio_skip(pb, 1); tmp_codec = avio_r8(pb); voc->remaining_size -= 2; max_size -= 2; channels = 1; break; case VOC_TYPE_VOICE_DATA_CONT: break; case VOC_TYPE_EXTENDED: sample_rate = avio_rl16(pb); avio_r8(pb); channels = avio_r8(pb) + 1; sample_rate = 256000000 / (channels * (65536 - sample_rate)); voc->remaining_size = 0; max_size -= 4; break; case VOC_TYPE_NEW_VOICE_DATA: if (!dec->sample_rate) { dec->sample_rate = avio_rl32(pb); avpriv_set_pts_info(st, 64, 1, dec->sample_rate); dec->bits_per_coded_sample = avio_r8(pb); dec->channels = avio_r8(pb); } else avio_skip(pb, 6); tmp_codec = avio_rl16(pb); avio_skip(pb, 4); voc->remaining_size -= 12; max_size -= 12; break; default: avio_skip(pb, voc->remaining_size); max_size -= voc->remaining_size; voc->remaining_size = 0; break; } } if (tmp_codec >= 0) { tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec); if (dec->codec_id == AV_CODEC_ID_NONE) dec->codec_id = tmp_codec; else if (dec->codec_id != tmp_codec) av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n"); if (dec->codec_id == AV_CODEC_ID_NONE) { if (s->audio_codec_id == AV_CODEC_ID_NONE) { av_log(s, AV_LOG_ERROR, "unknown codec tag\n"); return AVERROR(EINVAL); } av_log(s, AV_LOG_WARNING, "unknown codec tag\n"); } } dec->bit_rate = dec->sample_rate * dec->channels * dec->bits_per_coded_sample; if (max_size <= 0) max_size = 2048; size = FFMIN(voc->remaining_size, max_size); voc->remaining_size -= size; ret = av_get_packet(pb, pkt, size); pkt->dts = pkt->pts = voc->pts; duration = av_get_audio_frame_duration(st->codec, size); if (duration > 0 && voc->pts != AV_NOPTS_VALUE) voc->pts += duration; else voc->pts = AV_NOPTS_VALUE; return ret; }
static int rtp_write_header(AVFormatContext *s1) { RTPMuxContext *s = s1->priv_data; int n; AVStream *st; if (s1->nb_streams != 1) { av_log(s1, AV_LOG_ERROR, "Only one stream supported in the RTP muxer\n"); return AVERROR(EINVAL); } st = s1->streams[0]; if (!is_supported(st->codec->codec_id)) { av_log(s1, AV_LOG_ERROR, "Unsupported codec %s\n", avcodec_get_name(st->codec->codec_id)); return -1; } if (s->payload_type < 0) { /* Re-validate non-dynamic payload types */ if (st->id < RTP_PT_PRIVATE) st->id = ff_rtp_get_payload_type(s1, st->codec, -1); s->payload_type = st->id; } else { /* private option takes priority */ st->id = s->payload_type; } s->base_timestamp = av_get_random_seed(); s->timestamp = s->base_timestamp; s->cur_timestamp = 0; if (!s->ssrc) s->ssrc = av_get_random_seed(); s->first_packet = 1; s->first_rtcp_ntp_time = ff_ntp_time(); if (s1->start_time_realtime) /* Round the NTP time to whole milliseconds. */ s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 + NTP_OFFSET_US; // Pick a random sequence start number, but in the lower end of the // available range, so that any wraparound doesn't happen immediately. // (Immediate wraparound would be an issue for SRTP.) if (s->seq < 0) { if (st->codec->flags & CODEC_FLAG_BITEXACT) { s->seq = 0; } else s->seq = av_get_random_seed() & 0x0fff; } else s->seq &= 0xffff; // Use the given parameter, wrapped to the right interval if (s1->packet_size) { if (s1->pb->max_packet_size) s1->packet_size = FFMIN(s1->packet_size, s1->pb->max_packet_size); } else s1->packet_size = s1->pb->max_packet_size; if (s1->packet_size <= 12) { av_log(s1, AV_LOG_ERROR, "Max packet size %d too low\n", s1->packet_size); return AVERROR(EIO); } s->buf = av_malloc(s1->packet_size); if (s->buf == NULL) { return AVERROR(ENOMEM); } s->max_payload_size = s1->packet_size - 12; s->max_frames_per_packet = 0; if (s1->max_delay > 0) { if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { int frame_size = av_get_audio_frame_duration(st->codec, 0); if (!frame_size) frame_size = st->codec->frame_size; if (frame_size == 0) { av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n"); } else { AVRational avr1 ={ frame_size, st->codec->sample_rate }; s->max_frames_per_packet = av_rescale_q_rnd(s1->max_delay,AV_TIME_BASE_Q,avr1, AV_ROUND_DOWN); } } if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { /* FIXME: We should round down here... */ AVRational avr2 = {1, 1000000}; s->max_frames_per_packet = av_rescale_q(s1->max_delay, avr2, st->codec->time_base); } } avpriv_set_pts_info(st, 32, 1, 90000); switch(st->codec->codec_id) { case AV_CODEC_ID_MP2: case AV_CODEC_ID_MP3: s->buf_ptr = s->buf + 4; break; case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: break; case AV_CODEC_ID_MPEG2TS: n = s->max_payload_size / TS_PACKET_SIZE; if (n < 1) n = 1; s->max_payload_size = n * TS_PACKET_SIZE; s->buf_ptr = s->buf; break; case AV_CODEC_ID_H264: /* check for H.264 MP4 syntax */ if (st->codec->extradata_size > 4 && st->codec->extradata[0] == 1) { s->nal_length_size = (st->codec->extradata[4] & 0x03) + 1; } break; case AV_CODEC_ID_VORBIS: case AV_CODEC_ID_THEORA: if (!s->max_frames_per_packet) s->max_frames_per_packet = 15; s->max_frames_per_packet = av_clip(s->max_frames_per_packet, 1, 15); s->max_payload_size -= 6; // ident+frag+tdt/vdt+pkt_num+pkt_length s->num_frames = 0; goto defaultcase; case AV_CODEC_ID_ADPCM_G722: /* Due to a historical error, the clock rate for G722 in RTP is * 8000, even if the sample rate is 16000. See RFC 3551. */ avpriv_set_pts_info(st, 32, 1, 8000); break; case AV_CODEC_ID_OPUS: if (st->codec->channels > 2) { av_log(s1, AV_LOG_ERROR, "Multistream opus not supported in RTP\n"); goto fail; } /* The opus RTP RFC says that all opus streams should use 48000 Hz * as clock rate, since all opus sample rates can be expressed in * this clock rate, and sample rate changes on the fly are supported. */ avpriv_set_pts_info(st, 32, 1, 48000); break; case AV_CODEC_ID_ILBC: if (st->codec->block_align != 38 && st->codec->block_align != 50) { av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n"); goto fail; } if (!s->max_frames_per_packet) s->max_frames_per_packet = 1; s->max_frames_per_packet = FFMIN(s->max_frames_per_packet, s->max_payload_size / st->codec->block_align); goto defaultcase; case AV_CODEC_ID_AMR_NB: case AV_CODEC_ID_AMR_WB: if (!s->max_frames_per_packet) s->max_frames_per_packet = 12; if (st->codec->codec_id == AV_CODEC_ID_AMR_NB) n = 31; else n = 61; /* max_header_toc_size + the largest AMR payload must fit */ if (1 + s->max_frames_per_packet + n > s->max_payload_size) { av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n"); goto fail; } if (st->codec->channels != 1) { av_log(s1, AV_LOG_ERROR, "Only mono is supported\n"); goto fail; } case AV_CODEC_ID_AAC: s->num_frames = 0; default: defaultcase: if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); } s->buf_ptr = s->buf; break; } return 0; fail: av_freep(&s->buf); return AVERROR(EINVAL); }
/* returns the size or -1 on error */ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags) { int bps, blkalign, bytespersec, frame_size; int hdrsize; int64_t hdrstart = avio_tell(pb); int waveformatextensible; uint8_t temp[256]; uint8_t *riff_extradata = temp; uint8_t *riff_extradata_start = temp; if (!enc->codec_tag || enc->codec_tag > 0xffff) return -1; /* We use the known constant frame size for the codec if known, otherwise * fall back on using AVCodecContext.frame_size, which is not as reliable * for indicating packet duration. */ frame_size = av_get_audio_frame_duration(enc, enc->block_align); waveformatextensible = (enc->channels > 2 && enc->channel_layout) || enc->sample_rate > 48000 || enc->codec_id == AV_CODEC_ID_EAC3 || av_get_bits_per_sample(enc->codec_id) > 16; if (waveformatextensible) avio_wl16(pb, 0xfffe); else avio_wl16(pb, enc->codec_tag); avio_wl16(pb, enc->channels); avio_wl32(pb, enc->sample_rate); if (enc->codec_id == AV_CODEC_ID_ATRAC3 || enc->codec_id == AV_CODEC_ID_G723_1 || enc->codec_id == AV_CODEC_ID_MP2 || enc->codec_id == AV_CODEC_ID_MP3 || enc->codec_id == AV_CODEC_ID_GSM_MS) { bps = 0; } else { if (!(bps = av_get_bits_per_sample(enc->codec_id))) { if (enc->bits_per_coded_sample) bps = enc->bits_per_coded_sample; else bps = 16; // default to 16 } } if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) { av_log(enc, AV_LOG_WARNING, "requested bits_per_coded_sample (%d) " "and actually stored (%d) differ\n", enc->bits_per_coded_sample, bps); } if (enc->codec_id == AV_CODEC_ID_MP2) { blkalign = (144 * enc->bit_rate - 1)/enc->sample_rate + 1; } else if (enc->codec_id == AV_CODEC_ID_MP3) { blkalign = 576 * (enc->sample_rate <= (24000 + 32000)/2 ? 1 : 2); } else if (enc->codec_id == AV_CODEC_ID_AC3) { blkalign = 3840; /* maximum bytes per frame */ } else if (enc->codec_id == AV_CODEC_ID_AAC) { blkalign = 768 * enc->channels; /* maximum bytes per frame */ } else if (enc->codec_id == AV_CODEC_ID_G723_1) { blkalign = 24; } else if (enc->block_align != 0) { /* specified by the codec */ blkalign = enc->block_align; } else blkalign = bps * enc->channels / av_gcd(8, bps); if (enc->codec_id == AV_CODEC_ID_PCM_U8 || enc->codec_id == AV_CODEC_ID_PCM_S24LE || enc->codec_id == AV_CODEC_ID_PCM_S32LE || enc->codec_id == AV_CODEC_ID_PCM_F32LE || enc->codec_id == AV_CODEC_ID_PCM_F64LE || enc->codec_id == AV_CODEC_ID_PCM_S16LE) { bytespersec = enc->sample_rate * blkalign; } else if (enc->codec_id == AV_CODEC_ID_G723_1) { bytespersec = 800; } else { bytespersec = enc->bit_rate / 8; } avio_wl32(pb, bytespersec); /* bytes per second */ avio_wl16(pb, blkalign); /* block align */ avio_wl16(pb, bps); /* bits per sample */ if (enc->codec_id == AV_CODEC_ID_MP3) { bytestream_put_le16(&riff_extradata, 1); /* wID */ bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */ bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */ bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */ bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */ } else if (enc->codec_id == AV_CODEC_ID_MP2) { /* fwHeadLayer */ bytestream_put_le16(&riff_extradata, 2); /* dwHeadBitrate */ bytestream_put_le32(&riff_extradata, enc->bit_rate); /* fwHeadMode */ bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8); /* fwHeadModeExt */ bytestream_put_le16(&riff_extradata, 0); /* wHeadEmphasis */ bytestream_put_le16(&riff_extradata, 1); /* fwHeadFlags */ bytestream_put_le16(&riff_extradata, 16); /* dwPTSLow */ bytestream_put_le32(&riff_extradata, 0); /* dwPTSHigh */ bytestream_put_le32(&riff_extradata, 0); } else if (enc->codec_id == AV_CODEC_ID_G723_1) { bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */ bytestream_put_le32(&riff_extradata, 0xaea2f732); bytestream_put_le16(&riff_extradata, 0xacde); } else if (enc->codec_id == AV_CODEC_ID_GSM_MS || enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) { /* wSamplesPerBlock */ bytestream_put_le16(&riff_extradata, frame_size); } else if (enc->extradata_size) { riff_extradata_start = enc->extradata; riff_extradata = enc->extradata + enc->extradata_size; } /* write WAVEFORMATEXTENSIBLE extensions */ if (waveformatextensible) { int write_channel_mask = enc->strict_std_compliance < FF_COMPLIANCE_NORMAL || enc->channel_layout < 0x40000; /* 22 is WAVEFORMATEXTENSIBLE size */ avio_wl16(pb, riff_extradata - riff_extradata_start + 22); /* ValidBitsPerSample || SamplesPerBlock || Reserved */ avio_wl16(pb, bps); /* dwChannelMask */ avio_wl32(pb, write_channel_mask ? enc->channel_layout : 0); /* GUID + next 3 */ if (enc->codec_id == AV_CODEC_ID_EAC3) { ff_put_guid(pb, ff_get_codec_guid(enc->codec_id, ff_codec_wav_guids)); } else { avio_wl32(pb, enc->codec_tag); avio_wl32(pb, 0x00100000); avio_wl32(pb, 0xAA000080); avio_wl32(pb, 0x719B3800); } } else if ((flags & FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX) || enc->codec_tag != 0x0001 /* PCM */ || riff_extradata - riff_extradata_start) { /* WAVEFORMATEX */ avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */ } /* else PCMWAVEFORMAT */ avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start); hdrsize = avio_tell(pb) - hdrstart; if (hdrsize & 1) { hdrsize++; avio_w8(pb, 0); } return hdrsize; }
/* returns the size or -1 on error */ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc) { int bps, blkalign, bytespersec, frame_size; int hdrsize = 18; int waveformatextensible; uint8_t temp[256]; uint8_t *riff_extradata = temp; uint8_t *riff_extradata_start = temp; if (!enc->codec_tag || enc->codec_tag > 0xffff) return -1; /* We use the known constant frame size for the codec if known, otherwise * fall back on using AVCodecContext.frame_size, which is not as reliable * for indicating packet duration. */ frame_size = av_get_audio_frame_duration(enc, enc->block_align); waveformatextensible = (enc->channels > 2 && enc->channel_layout) || enc->sample_rate > 48000 || av_get_bits_per_sample(enc->codec_id) > 16; if (waveformatextensible) avio_wl16(pb, 0xfffe); else avio_wl16(pb, enc->codec_tag); avio_wl16(pb, enc->channels); avio_wl32(pb, enc->sample_rate); if (enc->codec_id == AV_CODEC_ID_MP2 || enc->codec_id == AV_CODEC_ID_MP3 || enc->codec_id == AV_CODEC_ID_GSM_MS) { bps = 0; } else { if (!(bps = av_get_bits_per_sample(enc->codec_id))) { if (enc->bits_per_coded_sample) bps = enc->bits_per_coded_sample; else bps = 16; // default to 16 } } if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) { av_log(enc, AV_LOG_WARNING, "requested bits_per_coded_sample (%d) " "and actually stored (%d) differ\n", enc->bits_per_coded_sample, bps); } if (enc->codec_id == AV_CODEC_ID_MP2) { blkalign = frame_size; } else if (enc->codec_id == AV_CODEC_ID_MP3) { blkalign = 576 * (enc->sample_rate <= 24000 ? 1 : 2); } else if (enc->codec_id == AV_CODEC_ID_AC3) { blkalign = 3840; /* maximum bytes per frame */ } else if (enc->block_align != 0) { /* specified by the codec */ blkalign = enc->block_align; } else blkalign = bps * enc->channels / av_gcd(8, bps); if (enc->codec_id == AV_CODEC_ID_PCM_U8 || enc->codec_id == AV_CODEC_ID_PCM_S24LE || enc->codec_id == AV_CODEC_ID_PCM_S32LE || enc->codec_id == AV_CODEC_ID_PCM_F32LE || enc->codec_id == AV_CODEC_ID_PCM_F64LE || enc->codec_id == AV_CODEC_ID_PCM_S16LE) { bytespersec = enc->sample_rate * blkalign; } else { bytespersec = enc->bit_rate / 8; } avio_wl32(pb, bytespersec); /* bytes per second */ avio_wl16(pb, blkalign); /* block align */ avio_wl16(pb, bps); /* bits per sample */ if (enc->codec_id == AV_CODEC_ID_MP3) { hdrsize += 12; bytestream_put_le16(&riff_extradata, 1); /* wID */ bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */ bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */ bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */ bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */ } else if (enc->codec_id == AV_CODEC_ID_MP2) { hdrsize += 22; /* fwHeadLayer */ bytestream_put_le16(&riff_extradata, 2); /* dwHeadBitrate */ bytestream_put_le32(&riff_extradata, enc->bit_rate); /* fwHeadMode */ bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8); /* fwHeadModeExt */ bytestream_put_le16(&riff_extradata, 0); /* wHeadEmphasis */ bytestream_put_le16(&riff_extradata, 1); /* fwHeadFlags */ bytestream_put_le16(&riff_extradata, 16); /* dwPTSLow */ bytestream_put_le32(&riff_extradata, 0); /* dwPTSHigh */ bytestream_put_le32(&riff_extradata, 0); } else if (enc->codec_id == AV_CODEC_ID_GSM_MS || enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) { hdrsize += 2; /* wSamplesPerBlock */ bytestream_put_le16(&riff_extradata, frame_size); } else if (enc->extradata_size) { riff_extradata_start = enc->extradata; riff_extradata = enc->extradata + enc->extradata_size; hdrsize += enc->extradata_size; } /* write WAVEFORMATEXTENSIBLE extensions */ if (waveformatextensible) { hdrsize += 22; /* 22 is WAVEFORMATEXTENSIBLE size */ avio_wl16(pb, riff_extradata - riff_extradata_start + 22); /* ValidBitsPerSample || SamplesPerBlock || Reserved */ avio_wl16(pb, bps); /* dwChannelMask */ avio_wl32(pb, enc->channel_layout); /* GUID + next 3 */ avio_wl32(pb, enc->codec_tag); avio_wl32(pb, 0x00100000); avio_wl32(pb, 0xAA000080); avio_wl32(pb, 0x719B3800); } else { avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */ } avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start); if (hdrsize & 1) { hdrsize++; avio_w8(pb, 0); } return hdrsize; }
/* Returns the number of sound data frames or negative on error */ static int get_aiff_header(AVFormatContext *s, int size, unsigned version) { AVIOContext *pb = s->pb; AVCodecContext *codec = s->streams[0]->codec; AIFFInputContext *aiff = s->priv_data; int exp; uint64_t val; int sample_rate; unsigned int num_frames; if (size & 1) size++; codec->codec_type = AVMEDIA_TYPE_AUDIO; codec->channels = avio_rb16(pb); num_frames = avio_rb32(pb); codec->bits_per_coded_sample = avio_rb16(pb); exp = avio_rb16(pb) - 16383 - 63; val = avio_rb64(pb); if (exp <-63 || exp >63) { av_log(s, AV_LOG_ERROR, "exp %d is out of range\n", exp); return AVERROR_INVALIDDATA; } if (exp >= 0) sample_rate = val << exp; else sample_rate = (val + (1ULL<<(-exp-1))) >> -exp; codec->sample_rate = sample_rate; size -= 18; /* get codec id for AIFF-C */ if (size < 4) { version = AIFF; } else if (version == AIFF_C_VERSION1) { codec->codec_tag = avio_rl32(pb); codec->codec_id = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag); if (codec->codec_id == AV_CODEC_ID_NONE) { char tag[32]; av_get_codec_tag_string(tag, sizeof(tag), codec->codec_tag); avpriv_request_sample(s, "unknown or unsupported codec tag: %s", tag); } size -= 4; } if (version != AIFF_C_VERSION1 || codec->codec_id == AV_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); aiff->block_duration = 1; } else { switch (codec->codec_id) { case AV_CODEC_ID_PCM_F32BE: case AV_CODEC_ID_PCM_F64BE: case AV_CODEC_ID_PCM_S16LE: case AV_CODEC_ID_PCM_ALAW: case AV_CODEC_ID_PCM_MULAW: aiff->block_duration = 1; break; case AV_CODEC_ID_ADPCM_IMA_QT: codec->block_align = 34*codec->channels; break; case AV_CODEC_ID_MACE3: codec->block_align = 2*codec->channels; break; case AV_CODEC_ID_ADPCM_G726LE: codec->bits_per_coded_sample = 5; case AV_CODEC_ID_ADPCM_IMA_WS: case AV_CODEC_ID_ADPCM_G722: case AV_CODEC_ID_MACE6: case AV_CODEC_ID_SDX2_DPCM: codec->block_align = 1*codec->channels; break; case AV_CODEC_ID_GSM: codec->block_align = 33; break; default: aiff->block_duration = 1; break; } if (codec->block_align > 0) aiff->block_duration = av_get_audio_frame_duration(codec, codec->block_align); } /* 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 = (av_get_bits_per_sample(codec->codec_id) * codec->channels) >> 3; if (aiff->block_duration) { codec->bit_rate = codec->sample_rate * (codec->block_align << 3) / aiff->block_duration; } /* Chunk is over */ if (size) avio_skip(pb, size); return num_frames; }