当mp4的profile为high的时候,avpacket==1并不能判断是否是关键帧,很多不是的也被误判断成关键帧了,具体做法应该是,进一步判断字节:
int is_keyframe_h264(AVPacket* pkt) { // printf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", // pkt->data[0], pkt->data[1], pkt->data[2], pkt->data[3], pkt->data[4], // pkt->data[5], pkt->data[6], pkt->data[7], pkt->data[8], pkt->data[9]); int length = 0; unsigned char* p_buffer = pkt->data; int i_buffer = pkt->size; if ( (pkt->data[0] == 0 && pkt->data[1] == 0 && pkt->data[2] == 0 && pkt->data[3] == 1) || (pkt->data[0] == 0 && pkt->data[1] == 0 && pkt->data[2] == 1) ) { while (i_buffer > 3) { if (pkt->data[0] == 0 && pkt->data[1] == 0 && pkt->data[2] == 0 && pkt->data[3] == 1) { p_buffer += 4; i_buffer -= 4; int nal_type = p_buffer[0] & 0x1f; // printf("1 pkt.size %d length %d nal_type %d\n", pkt->size, length, nal_type); if (nal_type == 5) return 1; } if (pkt->data[0] == 0 && pkt->data[1] == 0 && pkt->data[2] == 1) { p_buffer += 3; i_buffer -= 3; int nal_type = p_buffer[0] & 0x1f; // printf("2 pkt.size %d length %d nal_type %d\n", pkt->size, length, nal_type); if (nal_type == 5) return 1; } p_buffer++; i_buffer--; } } else { while (i_buffer > 4) { unsigned char* p = (unsigned char*)&length; p[3] = p_buffer[0]; p[2] = p_buffer[1]; p[1] = p_buffer[2]; p[0] = p_buffer[3]; p_buffer += 4; i_buffer -= 4; int nal_type = p_buffer[0] & 0x1f; //printf("3 p_buffer[0] 0x%02x pkt.size %d length %d nal_type %d\n", p_buffer[0], pkt->size, length, nal_type); //if (nal_type == 5) return 1; return 1; p_buffer += length; i_buffer -= length; } } // printf("this h264 frame is not keyframe\n"); return 0; } int is_keyframe(AVCodec *dec, AVPacket* pkt) { if (dec && dec->name) { int cpylen = strlen((const char*)dec->name); if (cpylen >= 4) { if (0 == memcmp(dec->name, "h264", 4)) { return is_keyframe_h264(pkt); } } } return 1; }
