From: Michael Niedermayer Date: Tue, 6 Dec 2011 00:37:27 +0000 (+0100) Subject: Merge remote-tracking branch 'qatar/master' X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=b404ab9e74d3bca12d5989c366f5cfd746279067;p=ffmpeg Merge remote-tracking branch 'qatar/master' * qatar/master: mov: Don't av_malloc(0). avconv: only allocate 1 AVFrame per input stream avconv: fix memleaks due to not freeing the AVFrame for audio h264-fate: remove -strict 1 except where necessary (mr4/5-tandberg). misc Doxygen markup improvements doxygen: eliminate Qt-style doxygen syntax g722: Add a regression test for muxing/demuxing in wav g722: Change bits per sample to 4 g722dec: Signal skipping the lower bits via AVOptions instead of bits_per_coded_sample api-example: update to use avcodec_decode_audio4() avplay: use avcodec_decode_audio4() avplay: use a separate buffer for playing silence avformat: use avcodec_decode_audio4() in avformat_find_stream_info() avconv: use avcodec_decode_audio4() instead of avcodec_decode_audio3() mov: Allow empty stts atom. doc: document preferred Doxygen syntax and make patcheck detect it Conflicts: avconv.c ffplay.c libavcodec/mlpdec.c libavcodec/version.h libavformat/mov.c tests/codec-regression.sh tests/fate/h264.mak Merged-by: Michael Niedermayer --- b404ab9e74d3bca12d5989c366f5cfd746279067 diff --cc avconv.c index 1e645b8c756,54aa89b117a..1351deea8b2 --- a/avconv.c +++ b/avconv.c @@@ -1820,10 -1751,10 +1828,9 @@@ static int transcode_video(InputStream quality = same_quant ? decoded_frame->quality : 0; if (!*got_output) { /* no picture yet */ - av_freep(&decoded_frame); return ret; } - ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pkt_pts, - decoded_frame->pkt_dts); + ist->next_pts = ist->pts = decoded_frame->best_effort_timestamp; if (pkt->duration) ist->next_pts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q); else if (ist->st->codec->time_base.num != 0) { @@@ -1847,15 -1778,18 +1854,17 @@@ #if CONFIG_AVFILTER if (ost->input_video_filter) { - AVRational sar; - if (ist->st->sample_aspect_ratio.num) - sar = ist->st->sample_aspect_ratio; - else - sar = ist->st->codec->sample_aspect_ratio; - av_vsrc_buffer_add_frame(ost->input_video_filter, decoded_frame, ist->pts, sar); + if (!decoded_frame->sample_aspect_ratio.num) + decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio; + decoded_frame->pts = ist->pts; + + av_vsrc_buffer_add_frame(ost->input_video_filter, decoded_frame, AV_VSRC_BUF_FLAG_OVERWRITE); - if (!(filtered_frame = avcodec_alloc_frame())) { - ret = AVERROR(ENOMEM); - goto fail; - } + if (!ist->filtered_frame && !(ist->filtered_frame = avcodec_alloc_frame())) { + av_free(buffer_to_free); + return AVERROR(ENOMEM); + } else + avcodec_get_frame_defaults(ist->filtered_frame); + filtered_frame = ist->filtered_frame; frame_available = avfilter_poll_frame(ost->output_video_filter->inputs[0]); } while (frame_available) { diff --cc doc/examples/decoding_encoding.c index ee0cb585f52,970a90eaba2..f87a8c9c416 --- a/doc/examples/decoding_encoding.c +++ b/doc/examples/decoding_encoding.c @@@ -29,10 -28,17 +29,11 @@@ * format handling */ -#include -#include -#include - -#ifdef HAVE_AV_CONFIG_H -#undef HAVE_AV_CONFIG_H -#endif - +#include "libavutil/imgutils.h" +#include "libavutil/opt.h" #include "libavcodec/avcodec.h" #include "libavutil/mathematics.h" + #include "libavutil/samplefmt.h" #define INBUF_SIZE 4096 #define AUDIO_INBUF_SIZE 20480 diff --cc ffmpeg.c index 707d9a66d9a,c731cec53b4..e10f0a23db0 --- a/ffmpeg.c +++ b/ffmpeg.c @@@ -168,38 -230,15 +168,39 @@@ static uint8_t *audio_buf static uint8_t *audio_out; static unsigned int allocated_audio_out_size, allocated_audio_buf_size; - static void *samples; -static short *samples; - -static AVBitStreamFilterContext *video_bitstream_filters=NULL; -static AVBitStreamFilterContext *audio_bitstream_filters=NULL; -static AVBitStreamFilterContext *subtitle_bitstream_filters=NULL; +static uint8_t *input_tmp= NULL; #define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass" -struct InputStream; +typedef struct InputStream { + int file_index; + AVStream *st; + int discard; /* true if stream data should be discarded */ + int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */ + AVCodec *dec; ++ AVFrame *decoded_frame; ++ AVFrame *filtered_frame; + + int64_t start; /* time when read started */ + int64_t next_pts; /* synthetic pts for cases where pkt.pts + is not defined */ + int64_t pts; /* current pts */ + double ts_scale; + int is_start; /* is 1 at the start and after a discontinuity */ + int showed_multi_packet_warning; + AVDictionary *opts; +} InputStream; + +typedef struct InputFile { + AVFormatContext *ctx; + int eof_reached; /* true if eof reached */ + int ist_index; /* index of first stream in input_streams */ + int buffer_size; /* current total buffer size */ + int64_t ts_offset; + int nb_streams; /* number of stream that ffmpeg is aware of; may be different + from ctx.nb_streams if new streams appear during av_read_frame() */ + int rate_emu; +} InputFile; typedef struct OutputStream { int file_index; /* file index */ @@@ -658,8 -462,11 +659,11 @@@ void av_noreturn exit_program(int ret for(i=0;ist->codec; @@@ -853,6 -768,6 +853,9 @@@ int osize = av_get_bytes_per_sample(enc->sample_fmt); int isize = av_get_bytes_per_sample(dec->sample_fmt); const int coded_bps = av_get_bits_per_sample(enc->codec->id); ++ uint8_t *buf = decoded_frame->data[0]; ++ int size = decoded_frame->nb_samples * dec->channels * isize; ++ int64_t allocated_for_size = size; need_realloc: audio_buf_size= (allocated_for_size + isize*dec->channels - 1) / (isize*dec->channels); @@@ -1550,536 -1441,462 +1553,540 @@@ static void print_report(OutputFile *ou } } -static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size) +static void flush_encoders(OutputStream *ost_table, int nb_ostreams) { - int fill_char = 0x00; - if (sample_fmt == AV_SAMPLE_FMT_U8) - fill_char = 0x80; - memset(buf, fill_char, size); -} + int i, ret; -/* pkt = NULL means EOF (needed to flush decoder buffers) */ -static int output_packet(InputStream *ist, int ist_index, - OutputStream **ost_table, int nb_ostreams, - const AVPacket *pkt) -{ - AVFormatContext *os; - OutputStream *ost; - int ret, i; - int got_output; - AVFrame picture; - void *buffer_to_free = NULL; - static unsigned int samples_size= 0; - AVSubtitle subtitle, *subtitle_to_free; - int64_t pkt_pts = AV_NOPTS_VALUE; -#if CONFIG_AVFILTER - int frame_available; -#endif - float quality; - - AVPacket avpkt; - int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt); - - if(ist->next_pts == AV_NOPTS_VALUE) - ist->next_pts= ist->pts; + for (i = 0; i < nb_ostreams; i++) { + OutputStream *ost = &ost_table[i]; + AVCodecContext *enc = ost->st->codec; + AVFormatContext *os = output_files[ost->file_index].ctx; - if (pkt == NULL) { - /* EOF handling */ - av_init_packet(&avpkt); - avpkt.data = NULL; - avpkt.size = 0; - goto handle_eof; - } else { - avpkt = *pkt; - } + if (!ost->encoding_needed) + continue; - if(pkt->dts != AV_NOPTS_VALUE) - ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); - if(pkt->pts != AV_NOPTS_VALUE) - pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q); + if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1) + continue; + if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == CODEC_ID_RAWVIDEO) + continue; - //while we have more to decode or while the decoder did output something on EOF - while (avpkt.size > 0 || (!pkt && got_output)) { - uint8_t *data_buf, *decoded_data_buf; - int data_size, decoded_data_size; - handle_eof: - ist->pts= ist->next_pts; + for(;;) { + AVPacket pkt; + int fifo_bytes; + av_init_packet(&pkt); + pkt.stream_index= ost->index; - if(avpkt.size && avpkt.size != pkt->size && - ((!ist->showed_multi_packet_warning && verbose>0) || verbose>1)){ - fprintf(stderr, "Multiple frames in a packet from stream %d\n", pkt->stream_index); - ist->showed_multi_packet_warning=1; - } + switch (ost->st->codec->codec_type) { + case AVMEDIA_TYPE_AUDIO: + fifo_bytes = av_fifo_size(ost->fifo); + ret = 0; + /* encode any samples remaining in fifo */ + if (fifo_bytes > 0) { + int osize = av_get_bytes_per_sample(enc->sample_fmt); + int fs_tmp = enc->frame_size; + + av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); + if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { + enc->frame_size = fifo_bytes / (osize * enc->channels); + } else { /* pad */ + int frame_bytes = enc->frame_size*osize*enc->channels; + if (allocated_audio_buf_size < frame_bytes) + exit_program(1); + generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes); + } - /* decode the packet if needed */ - decoded_data_buf = NULL; /* fail safe */ - decoded_data_size= 0; - data_buf = avpkt.data; - data_size = avpkt.size; - subtitle_to_free = NULL; - if (ist->decoding_needed) { - switch(ist->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO:{ - if(pkt && samples_size < FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE)) { - samples_size = FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE); - av_free(samples); - samples= av_malloc(samples_size); + ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf); + pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den, + ost->st->time_base.num, enc->sample_rate); + enc->frame_size = fs_tmp; } - decoded_data_size= samples_size; - /* XXX: could avoid copy if PCM 16 bits with same - endianness as CPU */ - ret = avcodec_decode_audio3(ist->st->codec, samples, &decoded_data_size, - &avpkt); - if (ret < 0) - return ret; - avpkt.data += ret; - avpkt.size -= ret; - data_size = ret; - got_output = decoded_data_size > 0; - /* Some bug in mpeg audio decoder gives */ - /* decoded_data_size < 0, it seems they are overflows */ - if (!got_output) { - /* no audio frame */ - continue; + if (ret <= 0) { + ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL); } - decoded_data_buf = (uint8_t *)samples; - ist->next_pts += ((int64_t)AV_TIME_BASE/bps * decoded_data_size) / - (ist->st->codec->sample_rate * ist->st->codec->channels); - break;} - case AVMEDIA_TYPE_VIDEO: - decoded_data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2; - /* XXX: allocate picture correctly */ - avcodec_get_frame_defaults(&picture); - avpkt.pts = pkt_pts; - avpkt.dts = ist->pts; - pkt_pts = AV_NOPTS_VALUE; - - ret = avcodec_decode_video2(ist->st->codec, - &picture, &got_output, &avpkt); - quality = same_quality ? picture.quality : 0; - if (ret < 0) - return ret; - if (!got_output) { - /* no picture yet */ - goto discard_packet; - } - ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, picture.pkt_pts, picture.pkt_dts); - if (ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; - ist->next_pts += ((int64_t)AV_TIME_BASE * - ist->st->codec->time_base.num * ticks) / - ist->st->codec->time_base.den; - } - avpkt.size = 0; - buffer_to_free = NULL; - pre_process_video_frame(ist, (AVPicture *)&picture, &buffer_to_free); - break; - case AVMEDIA_TYPE_SUBTITLE: - ret = avcodec_decode_subtitle2(ist->st->codec, - &subtitle, &got_output, &avpkt); - if (ret < 0) - return ret; - if (!got_output) { - goto discard_packet; + if (ret < 0) { + av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n"); + exit_program(1); } - subtitle_to_free = &subtitle; - avpkt.size = 0; - break; - default: - return -1; - } - } else { - switch(ist->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / - ist->st->codec->sample_rate; + audio_size += ret; + pkt.flags |= AV_PKT_FLAG_KEY; break; case AVMEDIA_TYPE_VIDEO: - if (ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; - ist->next_pts += ((int64_t)AV_TIME_BASE * - ist->st->codec->time_base.num * ticks) / - ist->st->codec->time_base.den; + ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n"); + exit_program(1); + } + video_size += ret; + if(enc->coded_frame && enc->coded_frame->key_frame) + pkt.flags |= AV_PKT_FLAG_KEY; + if (ost->logfile && enc->stats_out) { + fprintf(ost->logfile, "%s", enc->stats_out); } break; + default: + ret=-1; } - ret = avpkt.size; - avpkt.size = 0; + + if (ret <= 0) + break; + pkt.data = bit_buffer; + pkt.size = ret; + if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); + write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters); } + } +} -#if CONFIG_AVFILTER - if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - for (i = 0; i < nb_ostreams; i++) { - ost = ost_table[i]; - if (ost->input_video_filter && ost->source_index == ist_index) { - AVRational sar; - if (ist->st->sample_aspect_ratio.num) - sar = ist->st->sample_aspect_ratio; - else - sar = ist->st->codec->sample_aspect_ratio; - // add it to be filtered - av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, - ist->pts, - sar); - } +/* + * Check whether a packet from ist should be written into ost at this time + */ +static int check_output_constraints(InputStream *ist, OutputStream *ost) +{ + OutputFile *of = &output_files[ost->file_index]; + int ist_index = ist - input_streams; + + if (ost->source_index != ist_index) + return 0; + + if (of->start_time && ist->pts < of->start_time) + return 0; + + if (of->recording_time != INT64_MAX && + av_compare_ts(ist->pts, AV_TIME_BASE_Q, of->recording_time + of->start_time, + (AVRational){1, 1000000}) >= 0) { + ost->is_past_recording_time = 1; + return 0; + } + + return 1; +} + +static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt) +{ + OutputFile *of = &output_files[ost->file_index]; + int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); + AVPicture pict; + AVPacket opkt; + + av_init_packet(&opkt); + + if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && + !ost->copy_initial_nonkeyframes) + return; + + /* force the input stream PTS */ + if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) + audio_size += pkt->size; + else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + video_size += pkt->size; + ost->sync_opts++; + } + + opkt.stream_index = ost->index; + if (pkt->pts != AV_NOPTS_VALUE) + opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time; + else + opkt.pts = AV_NOPTS_VALUE; + + if (pkt->dts == AV_NOPTS_VALUE) + opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base); + else + opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); + opkt.dts -= ost_tb_start_time; + + opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); + opkt.flags = pkt->flags; + + //FIXME remove the following 2 lines they shall be replaced by the bitstream filters + if( ost->st->codec->codec_id != CODEC_ID_H264 + && ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO + && ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO + ) { + if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) + opkt.destruct = av_destruct_packet; + } else { + opkt.data = pkt->data; + opkt.size = pkt->size; + } + if (of->ctx->oformat->flags & AVFMT_RAWPICTURE) { + /* store AVPicture in AVPacket, as expected by the output format */ + avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height); + opkt.data = (uint8_t *)&pict; + opkt.size = sizeof(AVPicture); + opkt.flags |= AV_PKT_FLAG_KEY; + } + + write_frame(of->ctx, &opkt, ost->st->codec, ost->bitstream_filters); + ost->st->codec->frame_number++; + ost->frame_number++; + av_free_packet(&opkt); +} + +static void rate_emu_sleep(InputStream *ist) +{ + if (input_files[ist->file_index].rate_emu) { + int64_t pts = av_rescale(ist->pts, 1000000, AV_TIME_BASE); + int64_t now = av_gettime() - ist->start; + if (pts > now) + usleep(pts - now); + } +} + +static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output) +{ - static unsigned int samples_size = 0; ++ AVFrame *decoded_frame; ++ AVCodecContext *avctx = ist->st->codec; + int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt); - uint8_t *decoded_data_buf = NULL; - int decoded_data_size = 0; + int i, ret; + - if (pkt && samples_size < FFMAX(pkt->size * bps, AVCODEC_MAX_AUDIO_FRAME_SIZE)) { - av_free(samples); - samples_size = FFMAX(pkt->size * bps, AVCODEC_MAX_AUDIO_FRAME_SIZE); - samples = av_malloc(samples_size); - } - decoded_data_size = samples_size; ++ if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame())) ++ return AVERROR(ENOMEM); ++ else ++ avcodec_get_frame_defaults(ist->decoded_frame); ++ decoded_frame = ist->decoded_frame; + - ret = avcodec_decode_audio3(ist->st->codec, samples, &decoded_data_size, - pkt); - if (ret < 0) ++ ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt); ++ if (ret < 0) { + return ret; - *got_output = decoded_data_size > 0; ++ } + - /* Some bug in mpeg audio decoder gives */ - /* decoded_data_size < 0, it seems they are overflows */ + if (!*got_output) { + /* no audio frame */ + return ret; + } + - decoded_data_buf = (uint8_t *)samples; - ist->next_pts += ((int64_t)AV_TIME_BASE/bps * decoded_data_size) / - (ist->st->codec->sample_rate * ist->st->codec->channels); ++ /* if the decoder provides a pts, use it instead of the last packet pts. ++ the decoder could be delaying output by a packet or more. */ ++ if (decoded_frame->pts != AV_NOPTS_VALUE) ++ ist->next_pts = decoded_frame->pts; ++ ++ /* increment next_pts to use for the case where the input stream does not ++ have timestamps or there are multiple frames in the packet */ ++ ist->next_pts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) / ++ avctx->sample_rate; + + // preprocess audio (volume) + if (audio_volume != 256) { - switch (ist->st->codec->sample_fmt) { ++ int decoded_data_size = decoded_frame->nb_samples * avctx->channels * bps; ++ void *samples = decoded_frame->data[0]; ++ switch (avctx->sample_fmt) { + case AV_SAMPLE_FMT_U8: + { + uint8_t *volp = samples; + for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { + int v = (((*volp - 128) * audio_volume + 128) >> 8) + 128; + *volp++ = av_clip_uint8(v); } + break; } -#endif - - // preprocess audio (volume) - if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (audio_volume != 256) { - short *volp; - volp = samples; - for(i=0;i<(decoded_data_size / sizeof(short));i++) { - int v = ((*volp) * audio_volume + 128) >> 8; - if (v < -32768) v = -32768; - if (v > 32767) v = 32767; - *volp++ = v; - } + case AV_SAMPLE_FMT_S16: + { + int16_t *volp = samples; + for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { + int v = ((*volp) * audio_volume + 128) >> 8; + *volp++ = av_clip_int16(v); } + break; } - - /* frame rate emulation */ - if (rate_emu) { - int64_t pts = av_rescale(ist->pts, 1000000, AV_TIME_BASE); - int64_t now = av_gettime() - ist->start; - if (pts > now) - usleep(pts - now); + case AV_SAMPLE_FMT_S32: + { + int32_t *volp = samples; + for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { + int64_t v = (((int64_t)*volp * audio_volume + 128) >> 8); + *volp++ = av_clipl_int32(v); + } + break; } - /* if output time reached then transcode raw format, - encode packets and output them */ - if (start_time == 0 || ist->pts >= start_time) - for(i=0;isource_index == ist_index) { -#if CONFIG_AVFILTER - frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || - !ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]); - while (frame_available) { - AVRational ist_pts_tb; - if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) - get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb); - if (ost->picref) - ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); -#endif - os = output_files[ost->file_index]; - - /* set the input output pts pairs */ - //ost->sync_ipts = (double)(ist->pts + input_files[ist->file_index].ts_offset - start_time)/ AV_TIME_BASE; - - if (ost->encoding_needed) { - av_assert0(ist->decoding_needed); - switch(ost->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - do_audio_out(os, ost, ist, decoded_data_buf, decoded_data_size); - break; - case AVMEDIA_TYPE_VIDEO: + case AV_SAMPLE_FMT_FLT: + { + float *volp = samples; + float scale = audio_volume / 256.f; + for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { + *volp++ *= scale; + } + break; + } + case AV_SAMPLE_FMT_DBL: + { + double *volp = samples; + double scale = audio_volume / 256.; + for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { + *volp++ *= scale; + } + break; + } + default: + av_log(NULL, AV_LOG_FATAL, + "Audio volume adjustment on sample format %s is not supported.\n", + av_get_sample_fmt_name(ist->st->codec->sample_fmt)); + exit_program(1); + } + } + + rate_emu_sleep(ist); + + for (i = 0; i < nb_output_streams; i++) { + OutputStream *ost = &output_streams[i]; + + if (!check_output_constraints(ist, ost) || !ost->encoding_needed) + continue; - do_audio_out(output_files[ost->file_index].ctx, ost, ist, - decoded_data_buf, decoded_data_size); ++ do_audio_out(output_files[ost->file_index].ctx, ost, ist, decoded_frame); + } ++ + return ret; +} + +static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_t *pkt_pts, int64_t *pkt_dts) +{ + AVFrame *decoded_frame, *filtered_frame = NULL; + void *buffer_to_free = NULL; + int i, ret = 0; + float quality = 0; #if CONFIG_AVFILTER - if (ost->picref->video && !ost->frame_aspect_ratio) - ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect; + int frame_available = 1; #endif - do_video_out(os, ost, ist, &picture, &frame_size, - same_quality ? quality : ost->st->codec->global_quality); - if (vstats_filename && frame_size) - do_video_stats(os, ost, frame_size); - break; - case AVMEDIA_TYPE_SUBTITLE: - do_subtitle_out(os, ost, ist, &subtitle, - pkt->pts); - break; - default: - abort(); - } - } else { - AVFrame avframe; //FIXME/XXX remove this - AVPacket opkt; - int64_t ost_tb_start_time= av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base); + int duration=0; + int64_t *best_effort_timestamp; + AVRational *frame_sample_aspect; - if (!(decoded_frame = avcodec_alloc_frame())) - av_init_packet(&opkt); ++ if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame())) + return AVERROR(ENOMEM); ++ else ++ avcodec_get_frame_defaults(ist->decoded_frame); ++ decoded_frame = ist->decoded_frame; + pkt->pts = *pkt_pts; + pkt->dts = *pkt_dts; + *pkt_pts = AV_NOPTS_VALUE; + + if (pkt->duration) { + duration = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q); + } else if(ist->st->codec->time_base.num != 0) { + int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; + duration = ((int64_t)AV_TIME_BASE * + ist->st->codec->time_base.num * ticks) / + ist->st->codec->time_base.den; + } - if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes) -#if !CONFIG_AVFILTER - continue; -#else - goto cont; -#endif + if(*pkt_dts != AV_NOPTS_VALUE && duration) { + *pkt_dts += duration; + }else + *pkt_dts = AV_NOPTS_VALUE; + + ret = avcodec_decode_video2(ist->st->codec, + decoded_frame, got_output, pkt); + if (ret < 0) - goto fail; ++ return ret; - /* no reencoding needed : output the packet directly */ - /* force the input stream PTS */ + quality = same_quant ? decoded_frame->quality : 0; + if (!*got_output) { + /* no picture yet */ - av_freep(&decoded_frame); + return ret; + } - avcodec_get_frame_defaults(&avframe); - ost->st->codec->coded_frame= &avframe; - avframe.key_frame = pkt->flags & AV_PKT_FLAG_KEY; + best_effort_timestamp= av_opt_ptr(avcodec_get_frame_class(), decoded_frame, "best_effort_timestamp"); + if(*best_effort_timestamp != AV_NOPTS_VALUE) + ist->next_pts = ist->pts = *best_effort_timestamp; - if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - audio_size += data_size; - else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - video_size += data_size; - ost->sync_opts++; - } + ist->next_pts += duration; + pkt->size = 0; - opkt.stream_index= ost->index; - if(pkt->pts != AV_NOPTS_VALUE) - opkt.pts= av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time; - else - opkt.pts= AV_NOPTS_VALUE; - - if (pkt->dts == AV_NOPTS_VALUE) - opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base); - else - opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); - opkt.dts -= ost_tb_start_time; - - opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); - opkt.flags= pkt->flags; - - //FIXME remove the following 2 lines they shall be replaced by the bitstream filters - if( ost->st->codec->codec_id != CODEC_ID_H264 - && ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO - && ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO - ) { - if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & AV_PKT_FLAG_KEY)) - opkt.destruct= av_destruct_packet; - } else { - opkt.data = data_buf; - opkt.size = data_size; - } + pre_process_video_frame(ist, (AVPicture *)decoded_frame, &buffer_to_free); - write_frame(os, &opkt, ost->st->codec, ost->bitstream_filters); - ost->st->codec->frame_number++; - ost->frame_number++; - av_free_packet(&opkt); - } #if CONFIG_AVFILTER - cont: - frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && - ost->output_video_filter && avfilter_poll_frame(ost->output_video_filter->inputs[0]); - if (ost->picref) - avfilter_unref_buffer(ost->picref); - } -#endif - } - } - - av_free(buffer_to_free); - /* XXX: allocate the subtitles in the codec ? */ - if (subtitle_to_free) { - avsubtitle_free(subtitle_to_free); - subtitle_to_free = NULL; + frame_sample_aspect= av_opt_ptr(avcodec_get_frame_class(), decoded_frame, "sample_aspect_ratio"); + for(i=0;inum) + *frame_sample_aspect = ist->st->sample_aspect_ratio; + decoded_frame->pts = ist->pts; + + av_vsrc_buffer_add_frame(ost->input_video_filter, decoded_frame, AV_VSRC_BUF_FLAG_OVERWRITE); } } - discard_packet: - if (pkt == NULL) { - /* EOF handling */ +#endif - for(i=0;isource_index == ist_index) { - AVCodecContext *enc= ost->st->codec; - os = output_files[ost->file_index]; - - if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1) - continue; - if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE)) - continue; - - if (ost->encoding_needed) { - for(;;) { - AVPacket pkt; - int fifo_bytes; - av_init_packet(&pkt); - pkt.stream_index= ost->index; - - switch(ost->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - fifo_bytes = av_fifo_size(ost->fifo); - ret = 0; - /* encode any samples remaining in fifo */ - if (fifo_bytes > 0) { - int osize = av_get_bytes_per_sample(enc->sample_fmt); - int fs_tmp = enc->frame_size; - - av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); - if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { - enc->frame_size = fifo_bytes / (osize * enc->channels); - } else { /* pad */ - int frame_bytes = enc->frame_size*osize*enc->channels; - if (allocated_audio_buf_size < frame_bytes) - exit_program(1); - generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes); - } - - ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf); - pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den, - ost->st->time_base.num, enc->sample_rate); - enc->frame_size = fs_tmp; - } - if(ret <= 0) { - ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL); - } - if (ret < 0) { - fprintf(stderr, "Audio encoding failed\n"); - exit_program(1); - } - audio_size += ret; - pkt.flags |= AV_PKT_FLAG_KEY; - break; - case AVMEDIA_TYPE_VIDEO: - ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); - if (ret < 0) { - fprintf(stderr, "Video encoding failed\n"); - exit_program(1); - } - video_size += ret; - if(enc->coded_frame && enc->coded_frame->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; - if (ost->logfile && enc->stats_out) { - fprintf(ost->logfile, "%s", enc->stats_out); - } - break; - default: - ret=-1; - } + rate_emu_sleep(ist); - if(ret<=0) - break; - pkt.data= bit_buffer; - pkt.size= ret; - if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) - pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); - write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters); - } + for (i = 0; i < nb_output_streams; i++) { + OutputStream *ost = &output_streams[i]; + int frame_size; + + if (!check_output_constraints(ist, ost) || !ost->encoding_needed) + continue; + +#if CONFIG_AVFILTER + if (ost->input_video_filter) { + frame_available = avfilter_poll_frame(ost->output_video_filter->inputs[0]); + } + while (frame_available) { + if (ost->output_video_filter) { + AVRational ist_pts_tb = ost->output_video_filter->inputs[0]->time_base; + if (av_buffersink_get_buffer_ref(ost->output_video_filter, &ost->picref, 0) < 0) + goto cont; - if (!filtered_frame && !(filtered_frame = avcodec_alloc_frame())) { - ret = AVERROR(ENOMEM); - goto fail; - } ++ if (!ist->filtered_frame && !(ist->filtered_frame = avcodec_alloc_frame())) { ++ av_free(buffer_to_free); ++ return AVERROR(ENOMEM); ++ } else ++ avcodec_get_frame_defaults(ist->filtered_frame); ++ filtered_frame = ist->filtered_frame; + *filtered_frame= *decoded_frame; //for me_threshold + if (ost->picref) { + avfilter_fill_frame_from_video_buffer_ref(filtered_frame, ost->picref); + ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); } } + if (ost->picref->video && !ost->frame_aspect_ratio) + ost->st->codec->sample_aspect_ratio = ost->picref->video->sample_aspect_ratio; +#else + filtered_frame = decoded_frame; +#endif + + do_video_out(output_files[ost->file_index].ctx, ost, ist, filtered_frame, &frame_size, + same_quant ? quality : ost->st->codec->global_quality); + if (vstats_filename && frame_size) + do_video_stats(output_files[ost->file_index].ctx, ost, frame_size); +#if CONFIG_AVFILTER + cont: + frame_available = ost->output_video_filter && avfilter_poll_frame(ost->output_video_filter->inputs[0]); + avfilter_unref_buffer(ost->picref); } - av_freep(&filtered_frame); +#endif } - fail: - return 0; + av_free(buffer_to_free); - av_freep(&decoded_frame); + return ret; } -static void print_sdp(AVFormatContext **avc, int n) +static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) { - char sdp[2048]; + AVSubtitle subtitle; + int i, ret = avcodec_decode_subtitle2(ist->st->codec, + &subtitle, got_output, pkt); + if (ret < 0) + return ret; + if (!*got_output) + return ret; - av_sdp_create(avc, n, sdp, sizeof(sdp)); - printf("SDP:\n%s\n", sdp); - fflush(stdout); + rate_emu_sleep(ist); + + for (i = 0; i < nb_output_streams; i++) { + OutputStream *ost = &output_streams[i]; + + if (!check_output_constraints(ist, ost) || !ost->encoding_needed) + continue; + + do_subtitle_out(output_files[ost->file_index].ctx, ost, ist, &subtitle, pkt->pts); + } + + avsubtitle_free(&subtitle); + return ret; } -static int copy_chapters(int infile, int outfile) +/* pkt = NULL means EOF (needed to flush decoder buffers) */ +static int output_packet(InputStream *ist, + OutputStream *ost_table, int nb_ostreams, + const AVPacket *pkt) { - AVFormatContext *is = input_files[infile].ctx; - AVFormatContext *os = output_files[outfile]; - int i; + int ret = 0, i; + int got_output; + int64_t pkt_dts = AV_NOPTS_VALUE; + int64_t pkt_pts = AV_NOPTS_VALUE; - for (i = 0; i < is->nb_chapters; i++) { - AVChapter *in_ch = is->chapters[i], *out_ch; - int64_t ts_off = av_rescale_q(start_time - input_files[infile].ts_offset, - AV_TIME_BASE_Q, in_ch->time_base); - int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX : - av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base); + AVPacket avpkt; + if (ist->next_pts == AV_NOPTS_VALUE) + ist->next_pts = ist->pts; - if (in_ch->end < ts_off) - continue; - if (rt != INT64_MAX && in_ch->start > rt + ts_off) + if (pkt == NULL) { + /* EOF handling */ + av_init_packet(&avpkt); + avpkt.data = NULL; + avpkt.size = 0; + goto handle_eof; + } else { + avpkt = *pkt; + } + + if(pkt->dts != AV_NOPTS_VALUE){ + if(ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed) + ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); + pkt_dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); + } + if(pkt->pts != AV_NOPTS_VALUE) + pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q); + + //while we have more to decode or while the decoder did output something on EOF + while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) { + handle_eof: + + ist->pts = ist->next_pts; + + if (avpkt.size && avpkt.size != pkt->size) { + av_log(NULL, ist->showed_multi_packet_warning ? AV_LOG_VERBOSE : AV_LOG_WARNING, + "Multiple frames in a packet from stream %d\n", pkt->stream_index); + ist->showed_multi_packet_warning = 1; + } + + switch(ist->st->codec->codec_type) { + case AVMEDIA_TYPE_AUDIO: + ret = transcode_audio (ist, &avpkt, &got_output); + break; + case AVMEDIA_TYPE_VIDEO: + ret = transcode_video (ist, &avpkt, &got_output, &pkt_pts, &pkt_dts); break; + case AVMEDIA_TYPE_SUBTITLE: + ret = transcode_subtitles(ist, &avpkt, &got_output); + break; + default: + return -1; + } - out_ch = av_mallocz(sizeof(AVChapter)); - if (!out_ch) - return AVERROR(ENOMEM); + if (ret < 0) + return ret; + // touch data and size only if not EOF + if (pkt) { + if(ist->st->codec->codec_type != AVMEDIA_TYPE_AUDIO) + ret = avpkt.size; + avpkt.data += ret; + avpkt.size -= ret; + } + if (!got_output) { + continue; + } + } - out_ch->id = in_ch->id; - out_ch->time_base = in_ch->time_base; - out_ch->start = FFMAX(0, in_ch->start - ts_off); - out_ch->end = FFMIN(rt, in_ch->end - ts_off); + /* handle stream copy */ + if (!ist->decoding_needed) { + rate_emu_sleep(ist); + ist->pts = ist->next_pts; + switch (ist->st->codec->codec_type) { + case AVMEDIA_TYPE_AUDIO: + ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / + ist->st->codec->sample_rate; + break; + case AVMEDIA_TYPE_VIDEO: + if (pkt->duration) { + ist->next_pts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q); + } else if(ist->st->codec->time_base.num != 0) { + int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; + ist->next_pts += ((int64_t)AV_TIME_BASE * + ist->st->codec->time_base.num * ticks) / + ist->st->codec->time_base.den; + } + break; + } + } + for (i = 0; pkt && i < nb_ostreams; i++) { + OutputStream *ost = &ost_table[i]; - if (metadata_chapters_autocopy) - av_dict_copy(&out_ch->metadata, in_ch->metadata, 0); + if (!check_output_constraints(ist, ost) || ost->encoding_needed) + continue; - os->nb_chapters++; - os->chapters = av_realloc(os->chapters, sizeof(AVChapter)*os->nb_chapters); - if (!os->chapters) - return AVERROR(ENOMEM); - os->chapters[os->nb_chapters - 1] = out_ch; + do_streamcopy(ist, ost, pkt); } + return 0; } diff --cc ffplay.c index c1fe937ec44,69cd6179f99..976ac06d7b1 --- a/ffplay.c +++ b/ffplay.c @@@ -151,33 -153,18 +151,33 @@@ typedef struct VideoState AVStream *audio_st; PacketQueue audioq; int audio_hw_buf_size; - /* samples output by the codec. we reserve more space for avsync - compensation, resampling and format conversion */ - DECLARE_ALIGNED(16,uint8_t,audio_buf1)[AVCODEC_MAX_AUDIO_FRAME_SIZE * 4]; + DECLARE_ALIGNED(16,uint8_t,audio_buf2)[AVCODEC_MAX_AUDIO_FRAME_SIZE * 4]; + uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE]; uint8_t *audio_buf; + uint8_t *audio_buf1; unsigned int audio_buf_size; /* in bytes */ int audio_buf_index; /* in bytes */ + int audio_write_buf_size; AVPacket audio_pkt_temp; AVPacket audio_pkt; enum AVSampleFormat audio_src_fmt; - AVAudioConvert *reformat_ctx; + enum AVSampleFormat audio_tgt_fmt; + int audio_src_channels; + int audio_tgt_channels; + int64_t audio_src_channel_layout; + int64_t audio_tgt_channel_layout; + int audio_src_freq; + int audio_tgt_freq; + struct SwrContext *swr_ctx; + double audio_current_pts; + double audio_current_pts_drift; + int frame_drops_early; + int frame_drops_late; + AVFrame *frame; - int show_audio; /* if true, display audio samples */ + enum ShowMode { + SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB + } show_mode; int16_t sample_array[SAMPLE_ARRAY_SIZE]; int sample_array_index; int last_i_start; @@@ -1998,8 -1964,8 +1998,8 @@@ static int synchronize_audio(VideoStat max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n; if (wanted_size < min_size) wanted_size = min_size; - else if (wanted_size > FFMIN3(max_size, sizeof(is->audio_buf1), sizeof(is->audio_buf2))) - wanted_size = FFMIN3(max_size, sizeof(is->audio_buf1), sizeof(is->audio_buf2)); - else if (wanted_size > max_size) - wanted_size = max_size; ++ else if (wanted_size > FFMIN3(max_size, samples_size, sizeof(is->audio_buf2))) ++ wanted_size = FFMIN3(max_size, samples_size, sizeof(is->audio_buf2)); /* add or remove samples to correction the synchro */ if (wanted_size < samples_size) { @@@ -2042,8 -2008,7 +2042,8 @@@ static int audio_decode_frame(VideoStat AVPacket *pkt_temp = &is->audio_pkt_temp; AVPacket *pkt = &is->audio_pkt; AVCodecContext *dec= is->audio_st->codec; - int n, len1, data_size, got_frame; + int len1, len2, data_size, resampled_data_size; - int64_t dec_channel_layout; ++ int64_t dec_channel_layout, got_frame; double pts; int new_packet = 0; int flush_complete = 0; @@@ -2073,50 -2041,45 +2076,53 @@@ flush_complete = 1; continue; } + data_size = av_samples_get_buffer_size(NULL, dec->channels, + is->frame->nb_samples, + dec->sample_fmt, 1); - if (dec->sample_fmt != is->audio_src_fmt) { - if (is->reformat_ctx) - av_audio_convert_free(is->reformat_ctx); - is->reformat_ctx= av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1, - dec->sample_fmt, 1, NULL, 0); - if (!is->reformat_ctx) { - fprintf(stderr, "Cannot convert %s sample format to %s sample format\n", + dec_channel_layout = (dec->channel_layout && dec->channels == av_get_channel_layout_nb_channels(dec->channel_layout)) ? dec->channel_layout : av_get_default_channel_layout(dec->channels); + + if (dec->sample_fmt != is->audio_src_fmt || dec_channel_layout != is->audio_src_channel_layout || dec->sample_rate != is->audio_src_freq) { + if (is->swr_ctx) + swr_free(&is->swr_ctx); + is->swr_ctx = swr_alloc_set_opts(NULL, + is->audio_tgt_channel_layout, is->audio_tgt_fmt, is->audio_tgt_freq, + dec_channel_layout, dec->sample_fmt, dec->sample_rate, + 0, NULL); + if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) { + fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n", + dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt), - av_get_sample_fmt_name(AV_SAMPLE_FMT_S16)); - break; + dec->channels, + is->audio_tgt_freq, + av_get_sample_fmt_name(is->audio_tgt_fmt), + is->audio_tgt_channels); + break; } - is->audio_src_fmt= dec->sample_fmt; + is->audio_src_channel_layout = dec_channel_layout; + is->audio_src_channels = dec->channels; + is->audio_src_freq = dec->sample_rate; + is->audio_src_fmt = dec->sample_fmt; } - if (is->reformat_ctx) { - const void *ibuf[6]= { is->frame->data[0] }; - void *obuf[6]; - int istride[6]= {av_get_bytes_per_sample(dec->sample_fmt)}; - int ostride[6]= {2}; - int len= data_size/istride[0]; - obuf[0] = av_realloc(is->audio_buf1, FFALIGN(len * ostride[0], 32)); - if (!obuf[0]) { - return AVERROR(ENOMEM); - } - is->audio_buf1 = obuf[0]; - if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) { - printf("av_audio_convert() failed\n"); + resampled_data_size = data_size; + if (is->swr_ctx) { - const uint8_t *in[] = {is->audio_buf1}; ++ const uint8_t *in[] = { is->frame->data[0] }; + uint8_t *out[] = {is->audio_buf2}; + len2 = swr_convert(is->swr_ctx, out, sizeof(is->audio_buf2) / is->audio_tgt_channels / av_get_bytes_per_sample(is->audio_tgt_fmt), + in, data_size / dec->channels / av_get_bytes_per_sample(dec->sample_fmt)); + if (len2 < 0) { + fprintf(stderr, "audio_resample() failed\n"); break; } - is->audio_buf = is->audio_buf1; - /* FIXME: existing code assume that data_size equals framesize*channels*2 - remove this legacy cruft */ - data_size= len*2; - }else{ + if (len2 == sizeof(is->audio_buf2) / is->audio_tgt_channels / av_get_bytes_per_sample(is->audio_tgt_fmt)) { + fprintf(stderr, "warning: audio buffer is probably too small\n"); + swr_init(is->swr_ctx); + } + is->audio_buf = is->audio_buf2; + resampled_data_size = len2 * is->audio_tgt_channels * av_get_bytes_per_sample(is->audio_tgt_fmt); + } else { - is->audio_buf= is->audio_buf1; + is->audio_buf = is->frame->data[0]; } /* if no pts, then compute it */ @@@ -2178,11 -2138,10 +2180,10 @@@ static void sdl_audio_callback(void *op audio_size = audio_decode_frame(is, &pts); if (audio_size < 0) { /* if error, just output silence */ - is->audio_buf = is->audio_buf1; - is->audio_buf_size = 256 * is->audio_tgt_channels * av_get_bytes_per_sample(is->audio_tgt_fmt); - memset(is->audio_buf, 0, is->audio_buf_size); + is->audio_buf = is->silence_buf; + is->audio_buf_size = sizeof(is->silence_buf); } else { - if (is->show_audio) + if (is->show_mode != SHOW_MODE_VIDEO) update_sample_display(is, (int16_t *)is->audio_buf, audio_size); audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size, pts); @@@ -2353,9 -2279,13 +2354,12 @@@ static void stream_component_close(Vide SDL_CloseAudio(); packet_queue_end(&is->audioq); + if (is->swr_ctx) + swr_free(&is->swr_ctx); av_free_packet(&is->audio_pkt); - if (is->reformat_ctx) - av_audio_convert_free(is->reformat_ctx); - is->reformat_ctx = NULL; + av_freep(&is->audio_buf1); + is->audio_buf = NULL; + av_freep(&is->frame); if (is->rdft) { av_rdft_end(is->rdft); diff --cc libavcodec/mlpdec.c index 4b439ddb67f,357e28728d3..e91295084cc --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@@ -122,24 -122,21 +122,24 @@@ typedef struct MLPDecodeContext AVCodecContext *avctx; AVFrame frame; - //! Current access unit being read has a major sync. + /// Current access unit being read has a major sync. int is_major_sync_unit; - //! Set if a valid major sync block has been read. Otherwise no decoding is possible. + /// Set if a valid major sync block has been read. Otherwise no decoding is possible. uint8_t params_valid; - //! Number of substreams contained within this stream. + /// Number of substreams contained within this stream. uint8_t num_substreams; - //! Index of the last substream to decode - further substreams are skipped. + /// Index of the last substream to decode - further substreams are skipped. uint8_t max_decoded_substream; - //! Stream needs channel reordering to comply with FFmpeg's channel order ++ /// Stream needs channel reordering to comply with FFmpeg's channel order + uint8_t needs_reordering; + - //! number of PCM samples contained in each frame + /// number of PCM samples contained in each frame int access_unit_size; - //! next power of two above the number of samples in each frame + /// next power of two above the number of samples in each frame int access_unit_size_pow2; SubStream substream[MAX_SUBSTREAMS]; diff --cc libavcodec/version.h index 70dbd0001e6,3918b139da7..14b04bac019 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@@ -21,7 -21,7 +21,7 @@@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 - #define LIBAVCODEC_VERSION_MINOR 40 -#define LIBAVCODEC_VERSION_MINOR 26 ++#define LIBAVCODEC_VERSION_MINOR 41 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --cc libavformat/oggdec.c index 16025803481,36e2c452da4..ceb4091c6ed --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@@ -27,8 -26,9 +26,8 @@@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - **/ + */ - #include #include "oggdec.h" #include "avformat.h" diff --cc tests/codec-regression.sh index c0f8d3ddb95,0e6151b4490..2d5d690352f --- a/tests/codec-regression.sh +++ b/tests/codec-regression.sh @@@ -347,13 -291,13 +347,18 @@@ do_audio_encoding ac3.rm "-vn -acodec a #$tiny_psnr $pcm_dst $pcm_ref 2 1024 fi +if [ -n "$do_g723_1" ] ; then +do_audio_encoding g723_1.tco "-b:a 6.3k -ac 1 -ar 8000 -acodec g723_1" +do_audio_decoding +fi + + if [ -n "$do_g722" ] ; then + do_audio_encoding g722.wav "-b 64k -ac 1 -ar 16000 -acodec g722" + do_audio_decoding + fi + if [ -n "$do_g726" ] ; then -do_audio_encoding g726.wav "-b 32k -ac 1 -ar 8000 -acodec g726" +do_audio_encoding g726.wav "-b:a 32k -ac 1 -ar 8000 -acodec g726" do_audio_decoding fi diff --cc tests/fate/h264.mak index 8728717a186,c519f74a8fd..69e12f9b976 --- a/tests/fate/h264.mak +++ b/tests/fate/h264.mak @@@ -330,15 -315,8 +330,15 @@@ fate-h264-conformance-frext-pph10i4_pan fate-h264-conformance-frext-pph10i5_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le fate-h264-conformance-frext-pph10i6_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le fate-h264-conformance-frext-pph10i7_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le +fate-h264-conformance-frext-pph422i1_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH422I1_Panasonic_A.264 -pix_fmt yuv422p10le +fate-h264-conformance-frext-pph422i2_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH422I2_Panasonic_A.264 -pix_fmt yuv422p10le +fate-h264-conformance-frext-pph422i3_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH422I3_Panasonic_A.264 -pix_fmt yuv422p10le +fate-h264-conformance-frext-pph422i4_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH422I4_Panasonic_A.264 -pix_fmt yuv422p10le +fate-h264-conformance-frext-pph422i5_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH422I5_Panasonic_A.264 -pix_fmt yuv422p10le +fate-h264-conformance-frext-pph422i6_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH422I6_Panasonic_A.264 -pix_fmt yuv422p10le +fate-h264-conformance-frext-pph422i7_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH422I7_Panasonic_A.264 -pix_fmt yuv422p10le - fate-h264-conformance-hcbp2_hhi_a: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/HCBP2_HHI_A.264 - fate-h264-conformance-hcmp1_hhi_a: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/HCMP1_HHI_A.264 + fate-h264-conformance-hcbp2_hhi_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/HCBP2_HHI_A.264 + fate-h264-conformance-hcmp1_hhi_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/HCMP1_HHI_A.264 fate-h264-conformance-ls_sva_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/LS_SVA_D.264 fate-h264-conformance-midr_mw_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MIDR_MW_D.264 fate-h264-conformance-mps_mw_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MPS_MW_A.264 diff --cc tests/ref/acodec/g722 index 00000000000,a1fc72a3bbf..1ca02e219bd mode 000000,100644..100644 --- a/tests/ref/acodec/g722 +++ b/tests/ref/acodec/g722 @@@ -1,0 -1,4 +1,4 @@@ -b380355e0360b4e50ee78f33fd60a0f5 *./tests/data/acodec/g722.wav ++156f63e3391b95020ae882dbae6eccf3 *./tests/data/acodec/g722.wav + 47991 ./tests/data/acodec/g722.wav -82fdd5bb059336e0550de7ba5947c5bb *./tests/data/g722.acodec.out.wav -stddev: 8860.44 PSNR: 17.38 MAXDIFF:33814 bytes: 191732/ 1058400 ++8f65de513acc08b37a488d6a802b4f00 *./tests/data/g722.acodec.out.wav ++stddev: 8860.50 PSNR: 17.38 MAXDIFF:33814 bytes: 191732/ 1058400