You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	flac muxer: support reading updated extradata from side data
This commit is contained in:
		| @@ -31,6 +31,9 @@ | ||||
| typedef struct FlacMuxerContext { | ||||
|     const AVClass *class; | ||||
|     int write_header; | ||||
|  | ||||
|     /* updated streaminfo sent by the encoder at the end */ | ||||
|     uint8_t *streaminfo; | ||||
| } FlacMuxerContext; | ||||
|  | ||||
| static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_bytes, | ||||
| @@ -80,7 +83,8 @@ static int flac_write_header(struct AVFormatContext *s) | ||||
|     if (!c->write_header) | ||||
|         return 0; | ||||
|  | ||||
|     ret = ff_flac_write_header(s->pb, codec, 0); | ||||
|     ret = ff_flac_write_header(s->pb, codec->extradata, | ||||
|                                codec->extradata_size, 0); | ||||
|     if (ret) | ||||
|         return ret; | ||||
|  | ||||
| @@ -118,17 +122,14 @@ static int flac_write_header(struct AVFormatContext *s) | ||||
| static int flac_write_trailer(struct AVFormatContext *s) | ||||
| { | ||||
|     AVIOContext *pb = s->pb; | ||||
|     uint8_t *streaminfo; | ||||
|     enum FLACExtradataFormat format; | ||||
|     int64_t file_size; | ||||
|     FlacMuxerContext *c = s->priv_data; | ||||
|     uint8_t *streaminfo = c->streaminfo ? c->streaminfo : | ||||
|                                           s->streams[0]->codec->extradata; | ||||
|  | ||||
|     if (!c->write_header) | ||||
|     if (!c->write_header || !streaminfo) | ||||
|         return 0; | ||||
|  | ||||
|     if (!avpriv_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo)) | ||||
|         return -1; | ||||
|  | ||||
|     if (pb->seekable) { | ||||
|         /* rewrite the STREAMINFO header block data */ | ||||
|         file_size = avio_tell(pb); | ||||
| @@ -139,12 +140,32 @@ static int flac_write_trailer(struct AVFormatContext *s) | ||||
|     } else { | ||||
|         av_log(s, AV_LOG_WARNING, "unable to rewrite FLAC header.\n"); | ||||
|     } | ||||
|  | ||||
|     av_freep(&c->streaminfo); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt) | ||||
| { | ||||
|     avio_write(s->pb, pkt->data, pkt->size); | ||||
|     FlacMuxerContext *c = s->priv_data; | ||||
|     uint8_t *streaminfo; | ||||
|     int streaminfo_size; | ||||
|  | ||||
|     /* check for updated streaminfo */ | ||||
|     streaminfo = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, | ||||
|                                          &streaminfo_size); | ||||
|     if (streaminfo && streaminfo_size == FLAC_STREAMINFO_SIZE) { | ||||
|         av_freep(&c->streaminfo); | ||||
|  | ||||
|         c->streaminfo = av_malloc(FLAC_STREAMINFO_SIZE); | ||||
|         if (!c->streaminfo) | ||||
|             return AVERROR(ENOMEM); | ||||
|         memcpy(c->streaminfo, streaminfo, FLAC_STREAMINFO_SIZE); | ||||
|     } | ||||
|  | ||||
|     if (pkt->size) | ||||
|         avio_write(s->pb, pkt->data, pkt->size); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -26,8 +26,8 @@ | ||||
| #include "libavcodec/bytestream.h" | ||||
| #include "avformat.h" | ||||
|  | ||||
| int ff_flac_write_header(AVIOContext *pb, AVCodecContext *codec, | ||||
|                          int last_block); | ||||
| int ff_flac_write_header(AVIOContext *pb, uint8_t *extradata, | ||||
|                          int extradata_size, int last_block); | ||||
|  | ||||
| int ff_flac_is_native_layout(uint64_t channel_layout); | ||||
|  | ||||
|   | ||||
| @@ -26,8 +26,8 @@ | ||||
| #include "avformat.h" | ||||
| #include "flacenc.h" | ||||
|  | ||||
| int ff_flac_write_header(AVIOContext *pb, AVCodecContext *codec, | ||||
|                          int last_block) | ||||
| int ff_flac_write_header(AVIOContext *pb, uint8_t *extradata, | ||||
|                          int extradata_size, int last_block) | ||||
| { | ||||
|     uint8_t header[8] = { | ||||
|         0x66, 0x4C, 0x61, 0x43, 0x00, 0x00, 0x00, 0x22 | ||||
| @@ -35,14 +35,14 @@ int ff_flac_write_header(AVIOContext *pb, AVCodecContext *codec, | ||||
|  | ||||
|     header[4] = last_block ? 0x80 : 0x00; | ||||
|  | ||||
|     if (codec->extradata_size < FLAC_STREAMINFO_SIZE) | ||||
|     if (extradata_size < FLAC_STREAMINFO_SIZE) | ||||
|         return AVERROR_INVALIDDATA; | ||||
|  | ||||
|     /* write "fLaC" stream marker and first metadata block header */ | ||||
|     avio_write(pb, header, 8); | ||||
|  | ||||
|     /* write STREAMINFO */ | ||||
|     avio_write(pb, codec->extradata, FLAC_STREAMINFO_SIZE); | ||||
|     avio_write(pb, extradata, FLAC_STREAMINFO_SIZE); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -477,7 +477,8 @@ static int put_flac_codecpriv(AVFormatContext *s, | ||||
|     int write_comment = (codec->channel_layout && | ||||
|                          !(codec->channel_layout & ~0x3ffffULL) && | ||||
|                          !ff_flac_is_native_layout(codec->channel_layout)); | ||||
|     int ret = ff_flac_write_header(pb, codec, !write_comment); | ||||
|     int ret = ff_flac_write_header(pb, codec->extradata, codec->extradata_size, | ||||
|                                    !write_comment); | ||||
|  | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user