You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	flac demuxer: improve seeking
This commit is contained in:
		| @@ -489,6 +489,14 @@ static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf, | ||||
|                                         &fpc->wrap_buf, | ||||
|                                         &fpc->wrap_buf_allocated_size); | ||||
|  | ||||
|  | ||||
|     if (fpc->pc->flags & PARSER_FLAG_USE_CODEC_TS){ | ||||
|         if (header->fi.is_var_size) | ||||
|           fpc->pc->pts = header->fi.frame_or_sample_num; | ||||
|         else if (header->best_child) | ||||
|           fpc->pc->pts = header->fi.frame_or_sample_num * header->fi.blocksize; | ||||
|     } | ||||
|  | ||||
|     fpc->best_header_valid = 0; | ||||
|     fpc->last_fi_valid = 1; | ||||
|     fpc->last_fi = header->fi; | ||||
| @@ -516,6 +524,11 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, | ||||
|             s->duration = fi.blocksize; | ||||
|             if (!avctx->sample_rate) | ||||
|                 avctx->sample_rate = fi.samplerate; | ||||
|             if (fpc->pc->flags & PARSER_FLAG_USE_CODEC_TS){ | ||||
|                 fpc->pc->pts = fi.frame_or_sample_num; | ||||
|                 if (!fi.is_var_size) | ||||
|                   fpc->pc->pts *= fi.blocksize; | ||||
|             } | ||||
|         } | ||||
|         *poutbuf      = buf; | ||||
|         *poutbuf_size = buf_size; | ||||
|   | ||||
| @@ -162,12 +162,57 @@ static int flac_probe(AVProbeData *p) | ||||
|     return AVPROBE_SCORE_EXTENSION; | ||||
| } | ||||
|  | ||||
| static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_index, | ||||
|                                              int64_t *ppos, int64_t pos_limit) | ||||
| { | ||||
|     AVPacket pkt, out_pkt; | ||||
|     AVStream *st = s->streams[stream_index]; | ||||
|     int ret; | ||||
|  | ||||
|     if (avio_seek(s->pb, *ppos, SEEK_SET) < 0) | ||||
|         return AV_NOPTS_VALUE; | ||||
|  | ||||
|     av_init_packet(&pkt); | ||||
|     st->parser = av_parser_init(st->codec->codec_id); | ||||
|     if (!st->parser){ | ||||
|         return AV_NOPTS_VALUE; | ||||
|     } | ||||
|     st->parser->flags |= PARSER_FLAG_USE_CODEC_TS; | ||||
|  | ||||
|     for (;;){ | ||||
|         ret = ff_raw_read_partial_packet(s, &pkt); | ||||
|         if (ret < 0){ | ||||
|             if (ret == AVERROR(EAGAIN)) | ||||
|                 continue; | ||||
|             else | ||||
|                 return AV_NOPTS_VALUE; | ||||
|         } | ||||
|         av_init_packet(&out_pkt); | ||||
|         ret = av_parser_parse2(st->parser, st->codec, | ||||
|                                &out_pkt.data, &out_pkt.size, pkt.data, pkt.size, | ||||
|                                pkt.pts, pkt.dts, *ppos); | ||||
|  | ||||
|         if (out_pkt.size){ | ||||
|             int size = out_pkt.size; | ||||
|             av_free_packet(&out_pkt); | ||||
|             if (st->parser->pts != AV_NOPTS_VALUE){ | ||||
|                 // seeking may not have started from beginning of a frame | ||||
|                 // calculate frame start position from next frame backwards | ||||
|                 *ppos = st->parser->next_frame_offset - size; | ||||
|                 return st->parser->pts; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return AV_NOPTS_VALUE; | ||||
| } | ||||
|  | ||||
| AVInputFormat ff_flac_demuxer = { | ||||
|     .name           = "flac", | ||||
|     .long_name      = NULL_IF_CONFIG_SMALL("raw FLAC"), | ||||
|     .read_probe     = flac_probe, | ||||
|     .read_header    = flac_read_header, | ||||
|     .read_packet    = ff_raw_read_partial_packet, | ||||
|     .read_timestamp = flac_read_timestamp, | ||||
|     .flags          = AVFMT_GENERIC_INDEX, | ||||
|     .extensions     = "flac", | ||||
|     .raw_codec_id   = AV_CODEC_ID_FLAC, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user