You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	oggdec: add support for VP8 demuxing
Signed-off-by: James Almer <jamrial@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
				
					committed by
					
						 Michael Niedermayer
						Michael Niedermayer
					
				
			
			
				
	
			
			
			
						parent
						
							4aa9c91508
						
					
				
				
					commit
					d890db5f53
				
			| @@ -16,6 +16,7 @@ version <next> | ||||
| - stereoscopic 3d metadata handling | ||||
| - WebP encoding via libwebp | ||||
| - ATRAC3+ decoder | ||||
| - VP8 in Ogg demuxing | ||||
|  | ||||
|  | ||||
| version 2.1: | ||||
|   | ||||
| @@ -261,6 +261,7 @@ OBJS-$(CONFIG_OGG_DEMUXER)               += oggdec.o         \ | ||||
|                                             oggparsespeex.o  \ | ||||
|                                             oggparsetheora.o \ | ||||
|                                             oggparsevorbis.o \ | ||||
|                                             oggparsevp8.o    \ | ||||
|                                             vorbiscomment.o  \ | ||||
|                                             flac_picture.o | ||||
| OBJS-$(CONFIG_OGG_MUXER)                 += oggenc.o \ | ||||
|   | ||||
| @@ -48,6 +48,7 @@ static const struct ogg_codec * const ogg_codecs[] = { | ||||
|     &ff_flac_codec, | ||||
|     &ff_celt_codec, | ||||
|     &ff_opus_codec, | ||||
|     &ff_vp8_codec, | ||||
|     &ff_old_dirac_codec, | ||||
|     &ff_old_flac_codec, | ||||
|     &ff_ogm_video_codec, | ||||
|   | ||||
| @@ -125,6 +125,7 @@ extern const struct ogg_codec ff_skeleton_codec; | ||||
| extern const struct ogg_codec ff_speex_codec; | ||||
| extern const struct ogg_codec ff_theora_codec; | ||||
| extern const struct ogg_codec ff_vorbis_codec; | ||||
| extern const struct ogg_codec ff_vp8_codec; | ||||
|  | ||||
| int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, const uint8_t *buf, int size); | ||||
|  | ||||
|   | ||||
							
								
								
									
										137
									
								
								libavformat/oggparsevp8.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								libavformat/oggparsevp8.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| /* | ||||
|  * On2 VP8 parser for Ogg | ||||
|  * Copyright (C) 2013 James Almer | ||||
|  * | ||||
|  * This file is part of FFmpeg. | ||||
|  * | ||||
|  * FFmpeg is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2.1 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * FFmpeg is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with FFmpeg; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
|  | ||||
| #include "libavutil/intreadwrite.h" | ||||
| #include "avformat.h" | ||||
| #include "internal.h" | ||||
| #include "oggdec.h" | ||||
|  | ||||
| #define VP8_HEADER_SIZE 26 | ||||
|  | ||||
| static int vp8_header(AVFormatContext *s, int idx) | ||||
| { | ||||
|     struct ogg *ogg = s->priv_data; | ||||
|     struct ogg_stream *os = ogg->streams + idx; | ||||
|     uint8_t *p = os->buf + os->pstart; | ||||
|     AVStream *st = s->streams[idx]; | ||||
|     AVRational framerate; | ||||
|  | ||||
|     if (os->psize < 7 || p[0] != 0x4f) | ||||
|         return 0; | ||||
|  | ||||
|     switch (p[5]){ | ||||
|     case 0x01: | ||||
|         if (os->psize < VP8_HEADER_SIZE) { | ||||
|             av_log(s, AV_LOG_ERROR, "Invalid OggVP8 header packet"); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         } | ||||
|  | ||||
|         if (p[6] != 1) { | ||||
|             av_log(s, AV_LOG_WARNING, "Unknown OggVP8 version %d.%d\n", p[6], p[7]); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         } | ||||
|  | ||||
|         st->codec->width            = AV_RB16(p +  8); | ||||
|         st->codec->height           = AV_RB16(p + 10); | ||||
|         st->sample_aspect_ratio.num = AV_RB24(p + 12); | ||||
|         st->sample_aspect_ratio.den = AV_RB24(p + 15); | ||||
|         framerate.den               = AV_RB32(p + 18); | ||||
|         framerate.num               = AV_RB32(p + 22); | ||||
|  | ||||
|         avpriv_set_pts_info(st, 64, framerate.num, framerate.den); | ||||
|         st->codec->codec_type = AVMEDIA_TYPE_VIDEO; | ||||
|         st->codec->codec_id   = AV_CODEC_ID_VP8; | ||||
|         st->need_parsing      = AVSTREAM_PARSE_HEADERS; | ||||
|         break; | ||||
|     case 0x02: | ||||
|         if (p[6] != 0x20) | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         ff_vorbis_comment(s, &st->metadata, p + 7, os->psize - 7); | ||||
|         break; | ||||
|     default: | ||||
|         av_log(s, AV_LOG_ERROR, "Unknown VP8 header type 0x%02X\n", p[5]); | ||||
|         return AVERROR_INVALIDDATA; | ||||
|     } | ||||
|  | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| static uint64_t vp8_gptopts(AVFormatContext *s, int idx, uint64_t granule, int64_t *dts) | ||||
| { | ||||
|     struct ogg *ogg = s->priv_data; | ||||
|     struct ogg_stream *os = ogg->streams + idx; | ||||
|  | ||||
|     uint64_t pts  = (granule >> 32); | ||||
|     uint32_t dist = (granule >>  3) & 0x07ffffff; | ||||
|  | ||||
|     if (!dist) | ||||
|         os->pflags |= AV_PKT_FLAG_KEY; | ||||
|  | ||||
|     if (dts) | ||||
|         *dts = pts; | ||||
|  | ||||
|     return pts; | ||||
| } | ||||
|  | ||||
| static int vp8_packet(AVFormatContext *s, int idx) | ||||
| { | ||||
|     struct ogg *ogg = s->priv_data; | ||||
|     struct ogg_stream *os = ogg->streams + idx; | ||||
|     uint8_t *p = os->buf + os->pstart; | ||||
|  | ||||
|     if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { | ||||
|         int seg; | ||||
|         int duration; | ||||
|         uint8_t *last_pkt = p; | ||||
|         uint8_t *next_pkt; | ||||
|  | ||||
|         seg = os->segp; | ||||
|         duration = (last_pkt[0] >> 4) & 1; | ||||
|         next_pkt = last_pkt += os->psize; | ||||
|         for (; seg < os->nsegs; seg++) { | ||||
|             if (os->segments[seg] < 255) { | ||||
|                 duration += (last_pkt[0] >> 4) & 1; | ||||
|                 last_pkt  = next_pkt + os->segments[seg]; | ||||
|             } | ||||
|             next_pkt += os->segments[seg]; | ||||
|         } | ||||
|         os->lastpts = os->lastdts = vp8_gptopts(s, idx, os->granule, NULL) - duration; | ||||
|         if(s->streams[idx]->start_time == AV_NOPTS_VALUE) { | ||||
|             s->streams[idx]->start_time = os->lastpts; | ||||
|             if (s->streams[idx]->duration) | ||||
|                 s->streams[idx]->duration -= s->streams[idx]->start_time; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (os->psize > 0) | ||||
|         os->pduration = (p[0] >> 4) & 1; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| const struct ogg_codec ff_vp8_codec = { | ||||
|     .magic     = "OVP80", | ||||
|     .magicsize = 5, | ||||
|     .header    = vp8_header, | ||||
|     .packet    = vp8_packet, | ||||
|     .gptopts   = vp8_gptopts, | ||||
|     .nb_header = 1, | ||||
| }; | ||||
| @@ -31,7 +31,7 @@ | ||||
|  | ||||
| #define LIBAVFORMAT_VERSION_MAJOR 55 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 22 | ||||
| #define LIBAVFORMAT_VERSION_MICRO 100 | ||||
| #define LIBAVFORMAT_VERSION_MICRO 101 | ||||
|  | ||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
|                                                LIBAVFORMAT_VERSION_MINOR, \ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user