diff --git a/libavformat/mov.c b/libavformat/mov.c
index a0b6fcd..dfea295 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -6053,6 +6053,170 @@ static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVSt
     return 0;
 }
 
+static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    int atom_remaining;
+    atom_remaining = atom.size;
+
+    if (atom_remaining < 8)
+        return AVERROR_INVALIDDATA;
+
+    int version;
+    version = avio_r8(pb);
+    atom_remaining--;
+
+    unsigned int flags;
+    flags = avio_rb24(pb);
+    atom_remaining -= 3;
+
+    unsigned int grouping_type;
+    grouping_type = avio_rb32(pb);
+    atom_remaining -= 4;
+
+    unsigned int default_length;
+    if (version >= 1) {
+        default_length = avio_rb32(pb);
+	atom_remaining -= 4;
+    } else {
+        default_length = 0;
+    }
+
+    unsigned int default_sample_description_index;
+    if (version >= 2) {
+        default_sample_description_index = avio_rb32(pb);
+	atom_remaining -= 4;
+    } else {
+        default_sample_description_index = 0;
+    }
+
+    unsigned int entry_count;
+    entry_count = avio_rb32(pb);
+    atom_remaining -= 4;
+
+    unsigned int i;
+    for (i = 0; i < entry_count; i++) {
+	    unsigned int description_length;
+	    if ((version >= 1) && (default_length == 0)) {
+		    description_length = avio_rb32(pb);
+		    atom_remaining -= 4;
+	    } else {
+		    description_length = default_length;
+	    }
+
+	    int entry_remaining;
+	    entry_remaining = description_length;
+
+	    if (entry_remaining > atom_remaining)
+		    return AVERROR_INVALIDDATA;
+
+	    switch (grouping_type) {
+	    case MKBETAG('s', 'e', 'i', 'g'): {
+
+		    if (c->fc->nb_streams < 1)
+			    return 0;
+
+		    AVStream *st;
+		    st = c->fc->streams[c->fc->nb_streams - 1];
+
+		    MOVStreamContext *sc;
+		    sc = st->priv_data;
+
+		    if (!sc->cenc.default_encrypted_sample) {
+			    sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
+			    if (!sc->cenc.default_encrypted_sample) {
+				    return AVERROR(ENOMEM);
+			    }
+		    }
+    
+		    avio_r8(pb); //reserved
+		    entry_remaining--;
+		    atom_remaining--;
+
+		    uint8_t pattern = avio_r8(pb);
+		    entry_remaining--;
+		    atom_remaining--;
+
+		    unsigned int crypt_byte_block;
+		    crypt_byte_block = (pattern & 0xf0) >> 4;
+
+		    sc->cenc.default_encrypted_sample->crypt_byte_block = crypt_byte_block;
+
+		    unsigned int skip_byte_block;
+		    skip_byte_block = pattern & 0x0f;
+
+		    sc->cenc.default_encrypted_sample->skip_byte_block = skip_byte_block;
+
+		    unsigned int isProtected;
+		    isProtected = avio_r8(pb);
+		    entry_remaining--;
+		    atom_remaining--;
+
+		    if (isProtected && !sc->cenc.encryption_index) {
+			    sc->cenc.encryption_index = av_mallocz(sizeof (MOVEncryptionIndex));
+			    if (!sc->cenc.encryption_index)
+				    return AVERROR(ENOMEM);
+		    }
+
+		    unsigned int Per_Sample_IV_Size;
+		    Per_Sample_IV_Size = avio_r8(pb);
+		    entry_remaining--;
+		    atom_remaining--;
+
+		    if ((Per_Sample_IV_Size != 0) &&
+			(Per_Sample_IV_Size != 8) &&
+			(Per_Sample_IV_Size != 16)) {
+			    return AVERROR_INVALIDDATA;
+		    }
+
+		    sc->cenc.per_sample_iv_size = Per_Sample_IV_Size;
+
+		    uint8_t KID[16];
+		    if (avio_read(pb, KID, 16) != 16)
+			    return AVERROR_INVALIDDATA;
+		    entry_remaining -= 16;
+		    atom_remaining -= 16;
+
+		    memcpy(sc->cenc.default_encrypted_sample->key_id, KID, 16);
+
+		    if ((isProtected == 1) && (Per_Sample_IV_Size == 0)) {
+
+			    unsigned int constant_IV_size;
+			    constant_IV_size = avio_r8(pb);
+			    entry_remaining--;
+			    atom_remaining--;
+
+			    if ((constant_IV_size != 8) &&
+				(constant_IV_size != 16)) {
+				    return AVERROR_INVALIDDATA;
+			    }
+
+			    uint8_t constant_IV[16];
+			    memset(constant_IV, 0, sizeof (constant_IV));
+			    if (avio_read(pb, constant_IV, constant_IV_size) != constant_IV_size)
+				    return AVERROR_INVALIDDATA;
+			    entry_remaining -= 16;
+			    atom_remaining -= 16;
+
+			    memcpy(sc->cenc.default_encrypted_sample->iv, constant_IV, 16);
+		    }
+
+		    break;
+	    }
+
+	    default:
+		    break;
+	    }
+
+	    if (entry_remaining > 0) {
+		    avio_skip(pb, entry_remaining);
+		    atom_remaining -= entry_remaining;
+		    entry_remaining = 0;
+	    }
+    }
+
+    return 0;
+}
+
 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVEncryptionInfo **encrypted_samples;
@@ -6953,6 +7117,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('-','-','-','-'), mov_read_custom },
 { MKTAG('s','i','n','f'), mov_read_default },
 { MKTAG('f','r','m','a'), mov_read_frma },
+{ MKTAG('s','g','p','d'), mov_read_sgpd },
 { MKTAG('s','e','n','c'), mov_read_senc },
 { MKTAG('s','a','i','z'), mov_read_saiz },
 { MKTAG('s','a','i','o'), mov_read_saio },
