[MPlayer-cvslog] r37298 - trunk/libmpdemux/video.c
reimar
subversion at mplayerhq.hu
Sat Oct 18 18:07:11 CEST 2014
Author: reimar
Date: Sat Oct 18 18:07:11 2014
New Revision: 37298
Log:
video.c: rework H.264 parser and add very basic HEVC parser.
Modified:
trunk/libmpdemux/video.c
Modified: trunk/libmpdemux/video.c
==============================================================================
--- trunk/libmpdemux/video.c Sat Oct 18 18:07:10 2014 (r37297)
+++ trunk/libmpdemux/video.c Sat Oct 18 18:07:11 2014 (r37298)
@@ -57,6 +57,7 @@ typedef enum {
VIDEO_MPEG12,
VIDEO_MPEG4,
VIDEO_H264,
+ VIDEO_HEVC,
VIDEO_VC1,
VIDEO_OTHER
} video_codec_t;
@@ -94,6 +95,9 @@ static video_codec_t find_video_codec(sh
else if((fmt == DEMUXER_TYPE_MPEG_PS || fmt == DEMUXER_TYPE_MPEG_TS) &&
(sh_video->format==mmioFOURCC('W', 'V', 'C', '1')))
return VIDEO_VC1;
+ else if((fmt == DEMUXER_TYPE_MPEG_PS || fmt == DEMUXER_TYPE_MPEG_TS) &&
+ (sh_video->format==mmioFOURCC('H', 'E', 'V', 'C')))
+ return VIDEO_HEVC;
else if (fmt == DEMUXER_TYPE_ASF && sh_video->bih && sh_video->bih->biCompression == mmioFOURCC('D', 'V', 'R', ' '))
return VIDEO_MPEG12;
else
@@ -268,6 +272,18 @@ switch(video_codec){
}
break;
}
+ case VIDEO_HEVC: {
+ videobuf_len=0; videobuf_code_len=0;
+ if(!videobuffer) {
+ videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
+ if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
+ else {
+ mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_ShMemAllocFail);
+ return 0;
+ }
+ }
+ break;
+ }
case VIDEO_MPEG12: {
if (d_video->demuxer->file_format == DEMUXER_TYPE_ASF) { // DVR-MS
if(!sh_video->bih) return 0;
@@ -519,40 +535,57 @@ int video_read_frame(sh_video_t* sh_vide
int in_picture = 0;
while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){
int i=sync_video_packet(d_video);
+ int mi = i & ~0x60;
int pos = videobuf_len+4;
if(!i) return -1;
+ if (in_picture) {
+ // here starts the access unit end detection code
+ // see the mail on MPlayer-dev-eng for details:
+ // Date: Sat, 17 Sep 2005 11:24:06 +0200
+ // Subject: Re: [MPlayer-dev-eng] [RFC] h264 ES parser problems
+ // Message-ID: <20050917092406.GA7699 at rz.uni-karlsruhe.de>
+ if (mi == 0x106 || mi == 0x107 || mi == 0x109) break; // SEI, SPS or access unit delim.
+ if (mi == 0x101 || mi == 0x102 || mi == 0x105) {
+ // assuming arbitrary slice ordering is not allowed, the
+ // first_mb_in_slice (golomb encoded) value should be 0 then
+ // for the first VCL NAL in a picture
+ if (demux_peekc(d_video) & 0x80)
+ break;
+ }
+ }
if(!read_video_packet(d_video)) return -1; // EOF
- if((i&~0x60) == 0x107 && i != 0x107) {
+ if(mi == 0x107 && i != 0x107) {
h264_parse_sps(&picture, &(videobuffer[pos]), videobuf_len - pos);
if(picture.fps > 0) {
sh_video->fps=picture.fps;
sh_video->frametime=1.0/picture.fps;
}
- i=sync_video_packet(d_video);
- if(!i) return -1;
- if(!read_video_packet(d_video)) return -1; // EOF
- }
-
- // here starts the access unit end detection code
- // see the mail on MPlayer-dev-eng for details:
- // Date: Sat, 17 Sep 2005 11:24:06 +0200
- // Subject: Re: [MPlayer-dev-eng] [RFC] h264 ES parser problems
- // Message-ID: <20050917092406.GA7699 at rz.uni-karlsruhe.de>
- if((i&~0x60) == 0x101 || (i&~0x60) == 0x102 || (i&~0x60) == 0x105)
+ } else if (mi == 0x101 || mi == 0x102 || mi == 0x105) {
// found VCL NAL with slice header i.e. start of current primary coded
// picture, so start scanning for the end now
in_picture = 1;
+ }
+ }
+ *start=videobuffer; in_size=videobuf_len;
+ videobuf_len=0;
+ } else if(video_codec == VIDEO_HEVC){
+ int in_picture = 0;
+ while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){
+ int i=sync_video_packet(d_video);
+ if(!i) return -1;
+
+ i = (i >> 1) & 0x3f;
if (in_picture) {
- i = sync_video_packet(d_video) & ~0x60; // code of next packet
- if(i == 0x106 || i == 0x109) break; // SEI or access unit delim.
- if(i == 0x101 || i == 0x102 || i == 0x105) {
- // assuming arbitrary slice ordering is not allowed, the
- // first_mb_in_slice (golomb encoded) value should be 0 then
- // for the first VCL NAL in a picture
- if (demux_peekc(d_video) & 0x80)
+ if ((i >= 32 && i <= 35) || i == 39 || (i >= 41 && i <= 44) || (i >= 48 || i <= 55)) break;
+ if (i <= 9 || (i >= 16 && i <= 21)) {
+ // TODO: check first slice segment flag - need to peek 2 bytes ahead
+// if (demux_peekc(d_video) & 0x80)
break;
}
}
+ if(!read_video_packet(d_video)) return -1; // EOF
+ if (i <= 9 || (i >= 16 && i <= 21))
+ in_picture = 1;
}
*start=videobuffer; in_size=videobuf_len;
videobuf_len=0;
More information about the MPlayer-cvslog
mailing list