From 98ecefcc2309d1b5078a9cf3d27f5f78465b5310 Mon Sep 17 00:00:00 2001
From: Dana <Dana_Lee1016@126.com>
Date: 星期日, 30 十一月 2025 10:36:47 +0800
Subject: [PATCH] 1.h264 完整 可以跑 ;提交相关文件

---
 gradlew              |  185 +++++++++++++
 如何检查test.h264文件.md   |  184 +++++++++++++
 test.h264            |    0 
 check_h264.py        |  209 ++++++++++++++
 README_H264_CHECK.md |  120 ++++++++
 gradlew.bat          |   89 ++++++
 keystore.properties  |    4 
 7 files changed, 791 insertions(+), 0 deletions(-)

diff --git a/README_H264_CHECK.md b/README_H264_CHECK.md
new file mode 100644
index 0000000..3481192
--- /dev/null
+++ b/README_H264_CHECK.md
@@ -0,0 +1,120 @@
+# H264鏂囦欢妫�鏌ュ伐鍏蜂娇鐢ㄨ鏄�
+
+## 蹇�熸鏌�
+
+### 鏂规硶1: 鐩存帴浠庤澶囪矾寰勬鏌ワ紙濡傛灉鏂囦欢鍦ㄦ湰鍦帮級
+
+```bash
+python check_h264.py test.h264
+```
+
+### 鏂规硶2: 浠嶢ndroid璁惧涓嬭浇鏂囦欢鍚庢鏌�
+
+1. **杩炴帴Android璁惧骞跺惎鐢║SB璋冭瘯**
+
+2. **鏌ユ壘鏂囦欢璺緞**
+   
+   Android璁惧涓婄殑鏂囦欢璺緞閫氬父鏄細
+   ```
+   /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264
+   ```
+   
+   鎴栬�呬娇鐢╝db鏌ユ壘锛�
+   ```bash
+   adb shell "find /sdcard -name test.h264 2>/dev/null"
+   ```
+
+3. **涓嬭浇鏂囦欢鍒版湰鍦�**
+   ```bash
+   adb pull /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264 ./test.h264
+   ```
+
+4. **杩愯妫�鏌ュ伐鍏�**
+   ```bash
+   python check_h264.py test.h264
+   ```
+
+## 妫�鏌ュ唴瀹�
+
+宸ュ叿浼氭鏌ヤ互涓嬪唴瀹癸細
+
+1. 鉁� **鏂囦欢鏄惁瀛樺湪**
+2. 鉁� **鏂囦欢澶у皬**锛堝簲璇ュぇ浜�100瀛楄妭锛�
+3. 鉁� **NALU鍗曞厓鏁伴噺**锛堣嚦灏戝簲璇ユ湁SPS/PPS + 1涓叧閿抚锛�
+4. 鉁� **鏄惁鍖呭惈SPS**锛堝簭鍒楀弬鏁伴泦锛屽繀闇�锛�
+5. 鉁� **鏄惁鍖呭惈PPS**锛堝浘鍍忓弬鏁伴泦锛屽繀闇�锛�
+6. 鉁� **鏄惁鍖呭惈IDR鍏抽敭甯�**锛堝繀闇�锛�
+7. 鉁� **鏄惁鏈夊涓抚**
+
+## 棰勬湡缁撴灉
+
+涓�涓彲浠ユ挱鏀剧殑H264鏂囦欢搴旇鍖呭惈锛�
+
+- 鉁� 鑷冲皯1涓猄PS (绫诲瀷7)
+- 鉁� 鑷冲皯1涓狿PS (绫诲瀷8)
+- 鉁� 鑷冲皯1涓狪DR鍏抽敭甯� (绫诲瀷5)
+- 鉁� 澶氫釜NALU鍗曞厓锛堝缓璁�>10涓級
+
+## 甯歌闂
+
+### Q: 鏂囦欢鍙湁1甯ф�庝箞鍔烇紵
+
+**A:** 杩欐槸涔嬪墠鐨勯棶棰樸�傜幇鍦ㄧ殑浠g爜宸茬粡淇锛�
+- 鉁� 姝g‘澶勭悊SPS/PPS閰嶇疆
+- 鉁� 鍦ㄥ叧閿抚鏃跺悎骞禨PS/PPS
+- 鉁� 鏀硅繘缂栫爜寰幆锛岀‘淇濆鐞嗘墍鏈夎緭鍑�
+- 鉁� 娣诲姞娓呯┖缂栫爜鍣ㄥ姛鑳�
+
+**寤鸿锛�**
+1. 閲嶆柊缂栬瘧骞惰繍琛屽簲鐢�
+2. 褰曞埗鑷冲皯3-5绉掕棰�
+3. 鍋滄缂栫爜鍚庢鏌ユ枃浠�
+
+### Q: 鏂囦欢鏃犳硶鎾斁鎬庝箞鍔烇紵
+
+**鍙兘鍘熷洜锛�**
+1. 鉂� 缂哄皯SPS/PPS - 妫�鏌ユ槸鍚﹁緭鍑轰簡閰嶇疆鏁版嵁
+2. 鉂� 鏂囦欢鏍煎紡閿欒 - 妫�鏌ユ槸鍚︽槸Annex-B鏍煎紡
+3. 鉂� 鍙湁1甯� - 妫�鏌ョ紪鐮佸惊鐜槸鍚︽甯稿伐浣�
+
+**瑙e喅鏂规锛�**
+1. 鏌ョ湅Logcat鏃ュ織锛屾悳绱� "H264Encoder"
+2. 妫�鏌ユ槸鍚︽湁 "SPS/PPS included" 鏃ュ織
+3. 妫�鏌ユ槸鍚︽湁 "Frame encoded" 鏃ュ織
+4. 浣跨敤姝ゅ伐鍏锋鏌ユ枃浠剁粨鏋�
+
+### Q: 濡備綍鎾斁H264鏂囦欢锛�
+
+鍙互浣跨敤浠ヤ笅鎾斁鍣細
+- **VLC Media Player**锛堟帹鑽愶級
+- **ffplay** (FFmpeg鑷甫)
+- **MPC-HC**
+- **PotPlayer**
+
+鐩存帴鍙屽嚮 `.h264` 鏂囦欢鎴栨嫋鏀惧埌鎾斁鍣ㄧ獥鍙e嵆鍙��
+
+## 璋冭瘯寤鸿
+
+濡傛灉鏂囦欢鏃犳硶鎾斁锛岃妫�鏌ワ細
+
+1. **鏌ョ湅Logcat鏃ュ織**
+   ```bash
+   adb logcat -s H264Encoder:D MainActivity:D
+   ```
+
+2. **妫�鏌ュ叧閿棩蹇�**
+   - "SPS/PPS included in key frame data" - 璇存槑SPS/PPS宸插悎骞�
+   - "Frame encoded: ..." - 璇存槑鏈夊抚杈撳嚭
+   - "Encoder output EOS" - 璇存槑姝e父缁撴潫
+
+3. **楠岃瘉鏂囦欢缁撴瀯**
+   ```bash
+   python check_h264.py test.h264
+   ```
+
+4. **浣跨敤hexdump鏌ョ湅鏂囦欢澶�**
+   ```bash
+   hexdump -C test.h264 | head -20
+   ```
+   搴旇鐪嬪埌锛歚00 00 00 01` 鎴� `00 00 01`锛圓nnex-B璧峰鐮侊級
+
diff --git a/check_h264.py b/check_h264.py
new file mode 100644
index 0000000..307e7a2
--- /dev/null
+++ b/check_h264.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+H264鏂囦欢妫�鏌ュ伐鍏�
+妫�鏌ョ敓鎴愮殑test.h264鏂囦欢鏄惁绗﹀悎鎾斁瑕佹眰
+"""
+
+import os
+import sys
+
+def check_h264_file(file_path):
+    """妫�鏌264鏂囦欢鏄惁绗﹀悎鎾斁瑕佹眰"""
+    print(f"妫�鏌ユ枃浠�: {file_path}\n")
+    
+    # 1. 妫�鏌ユ枃浠舵槸鍚﹀瓨鍦�
+    if not os.path.exists(file_path):
+        print("鉂� 鏂囦欢涓嶅瓨鍦紒")
+        print(f"   棰勬湡璺緞: {file_path}")
+        print("\n鎻愮ず锛�")
+        print("   - 濡傛灉鏄疉ndroid璁惧锛岄渶瑕佸厛閫氳繃adb pull涓嬭浇鏂囦欢")
+        print(f"   - 鎴栬�呭皢鏂囦欢澶嶅埗鍒板綋鍓嶇洰褰�")
+        return False
+    
+    # 2. 妫�鏌ユ枃浠跺ぇ灏�
+    file_size = os.path.getsize(file_path)
+    print(f"鉁� 鏂囦欢澶у皬: {file_size} 瀛楄妭 ({file_size / 1024:.2f} KB)")
+    
+    if file_size == 0:
+        print("鉂� 鏂囦欢涓虹┖锛�")
+        return False
+    
+    if file_size < 100:
+        print("鈿狅笍  璀﹀憡: 鏂囦欢澶皬锛屽彲鑳藉彧鏈塖PS/PPS鎴�1甯ф暟鎹�")
+    
+    # 3. 璇诲彇鏂囦欢鍐呭骞跺垎鏋�
+    try:
+        with open(file_path, 'rb') as f:
+            data = f.read()
+    except Exception as e:
+        print(f"鉂� 璇诲彇鏂囦欢澶辫触: {e}")
+        return False
+    
+    # 妫�鏌ALU鍗曞厓
+    nal_start_code_3 = bytes([0x00, 0x00, 0x01])
+    nal_start_code_4 = bytes([0x00, 0x00, 0x00, 0x01])
+    
+    nalu_list = []
+    i = 0
+    
+    # 鏌ユ壘鎵�鏈塏ALU鍗曞厓
+    while i < len(data):
+        # 鏌ユ壘璧峰鐮�
+        found = False
+        
+        # 鏌ユ壘4瀛楄妭璧峰鐮�
+        if i + 4 <= len(data) and data[i:i+4] == nal_start_code_4:
+            start_pos = i + 4
+            found = True
+        # 鏌ユ壘3瀛楄妭璧峰鐮�
+        elif i + 3 <= len(data) and data[i:i+3] == nal_start_code_3:
+            # 纭繚鍓嶉潰涓嶆槸0x00 (閬垮厤璇垽)
+            if i == 0 or data[i-1] != 0x00:
+                start_pos = i + 3
+                found = True
+        
+        if found:
+            # 鏌ユ壘涓嬩竴涓捣濮嬬爜
+            next_start = -1
+            
+            # 鍏堟壘4瀛楄妭璧峰鐮�
+            for j in range(start_pos, len(data) - 3):
+                if j + 4 <= len(data) and data[j:j+4] == nal_start_code_4:
+                    next_start = j
+                    break
+            
+            # 濡傛灉娌℃壘鍒�4瀛楄妭鐨勶紝鎵�3瀛楄妭鐨�
+            if next_start == -1:
+                for j in range(start_pos, len(data) - 2):
+                    if j + 3 <= len(data) and data[j:j+3] == nal_start_code_3:
+                        # 纭繚鍓嶉潰涓嶆槸0x00
+                        if j == 0 or data[j-1] != 0x00:
+                            next_start = j
+                            break
+            
+            # 鎻愬彇NALU鏁版嵁
+            if next_start == -1:
+                nalu_data = data[start_pos:]
+            else:
+                nalu_data = data[start_pos:next_start]
+            
+            if len(nalu_data) > 0:
+                # 鑾峰彇NALU绫诲瀷 (绗竴涓瓧鑺傜殑浣�5浣�)
+                nal_type = nalu_data[0] & 0x1F
+                nalu_list.append({
+                    'type': nal_type,
+                    'size': len(nalu_data),
+                    'name': get_nalu_type_name(nal_type)
+                })
+            
+            i = next_start if next_start != -1 else len(data)
+        else:
+            i += 1
+    
+    # 4. 鍒嗘瀽NALU鍗曞厓
+    print(f"\n鉁� 鎵惧埌 {len(nalu_list)} 涓狽ALU鍗曞厓\n")
+    
+    if len(nalu_list) == 0:
+        print("鉂� 鏈壘鍒颁换浣昇ALU鍗曞厓锛佹枃浠舵牸寮忓彲鑳戒笉姝g‘")
+        return False
+    
+    # 缁熻涓嶅悓绫诲瀷鐨凬ALU
+    nal_type_count = {}
+    for nalu in nalu_list:
+        nal_type = nalu['type']
+        if nal_type not in nal_type_count:
+            nal_type_count[nal_type] = 0
+        nal_type_count[nal_type] += 1
+    
+    print("NALU绫诲瀷缁熻:")
+    for nal_type in sorted(nal_type_count.keys()):
+        count = nal_type_count[nal_type]
+        name = get_nalu_type_name(nal_type)
+        print(f"  {name} (绫诲瀷{nal_type}): {count} 涓�")
+    
+    # 5. 妫�鏌ュ叧閿姹�
+    print("\n妫�鏌ラ」:")
+    
+    has_sps = 7 in nal_type_count
+    has_pps = 8 in nal_type_count
+    has_idr = 5 in nal_type_count
+    has_non_idr = 1 in nal_type_count
+    
+    # SPS/PPS妫�鏌�
+    if has_sps:
+        print(f"  鉁� 鍖呭惈SPS (搴忓垪鍙傛暟闆�) - {nal_type_count[7]} 涓�")
+    else:
+        print("  鉂� 缂哄皯SPS (搴忓垪鍙傛暟闆�) - 蹇呴渶锛�")
+    
+    if has_pps:
+        print(f"  鉁� 鍖呭惈PPS (鍥惧儚鍙傛暟闆�) - {nal_type_count[8]} 涓�")
+    else:
+        print("  鉂� 缂哄皯PPS (鍥惧儚鍙傛暟闆�) - 蹇呴渶锛�")
+    
+    # 鍏抽敭甯ф鏌�
+    if has_idr:
+        print(f"  鉁� 鍖呭惈IDR鍏抽敭甯� - {nal_type_count[5]} 涓�")
+    else:
+        print("  鉂� 缂哄皯IDR鍏抽敭甯�")
+    
+    # 闈炲叧閿抚妫�鏌�
+    if has_non_idr:
+        print(f"  鉁� 鍖呭惈闈濱DR甯� - {nal_type_count[1]} 涓�")
+    else:
+        print("  鈿狅笍  娌℃湁闈濱DR甯э紙鍙湁鍏抽敭甯э級")
+    
+    # 6. 鎬讳綋璇勪及
+    print("\n" + "="*50)
+    can_play = has_sps and has_pps and has_idr
+    
+    if can_play:
+        if len(nalu_list) >= 3:
+            print("鉁� 鏂囦欢搴旇鍙互鎾斁锛�")
+            print(f"   鍖呭惈瀹屾暣鐨凷PS/PPS鍜� {len(nalu_list)} 涓狽ALU鍗曞厓")
+        else:
+            print("鈿狅笍  鏂囦欢缁撴瀯瀹屾暣锛屼絾甯ф暟杈冨皯")
+            print("   寤鸿褰曞埗鏇撮暱鏃堕棿浠ヨ幏寰楁洿澶氬抚")
+    else:
+        print("鉂� 鏂囦欢鍙兘鏃犳硶鎾斁")
+        if not has_sps or not has_pps:
+            print("   鍘熷洜: 缂哄皯SPS/PPS鍙傛暟闆�")
+        if not has_idr:
+            print("   鍘熷洜: 缂哄皯IDR鍏抽敭甯�")
+    
+    print("="*50)
+    
+    return can_play
+
+def get_nalu_type_name(nal_type):
+    """鑾峰彇NALU绫诲瀷鍚嶇О"""
+    nal_names = {
+        1: "闈濱DR缂栫爜鐗�",
+        2: "缂栫爜鐗囨暟鎹垎鍖篈",
+        3: "缂栫爜鐗囨暟鎹垎鍖築",
+        4: "缂栫爜鐗囨暟鎹垎鍖篊",
+        5: "IDR鍥惧儚缂栫爜鐗�",
+        6: "SEI (琛ュ厖澧炲己淇℃伅)",
+        7: "SPS (搴忓垪鍙傛暟闆�)",
+        8: "PPS (鍥惧儚鍙傛暟闆�)",
+        9: "璁块棶鍗曞厓鍒嗛殧绗�",
+        10: "搴忓垪缁撴潫",
+        11: "娴佺粨鏉�",
+        12: "濉厖鏁版嵁"
+    }
+    return nal_names.get(nal_type, f"鏈煡绫诲瀷{nal_type}")
+
+if __name__ == "__main__":
+    # 榛樿鏂囦欢璺緞
+    default_path = "test.h264"
+    
+    # 濡傛灉鎻愪緵浜嗗懡浠よ鍙傛暟锛屼娇鐢ㄥ弬鏁颁綔涓烘枃浠惰矾寰�
+    file_path = sys.argv[1] if len(sys.argv) > 1 else default_path
+    
+    print("H264鏂囦欢妫�鏌ュ伐鍏�")
+    print("="*50)
+    
+    success = check_h264_file(file_path)
+    
+    sys.exit(0 if success else 1)
+
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=`expr $i + 1`
+    done
+    case $i in
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/keystore.properties b/keystore.properties
new file mode 100644
index 0000000..4504553
--- /dev/null
+++ b/keystore.properties
@@ -0,0 +1,4 @@
+storePassword = 123456
+keyPassword = 123456
+keyAlias = key0
+storeFile = ../key/key.jks
\ No newline at end of file
diff --git a/test.h264 b/test.h264
new file mode 100644
index 0000000..6d2cdb8
--- /dev/null
+++ b/test.h264
Binary files differ
diff --git "a/\345\246\202\344\275\225\346\243\200\346\237\245test.h264\346\226\207\344\273\266.md" "b/\345\246\202\344\275\225\346\243\200\346\237\245test.h264\346\226\207\344\273\266.md"
new file mode 100644
index 0000000..8058f55
--- /dev/null
+++ "b/\345\246\202\344\275\225\346\243\200\346\237\245test.h264\346\226\207\344\273\266.md"
@@ -0,0 +1,184 @@
+# 濡備綍妫�鏌est.h264鏂囦欢鑳藉惁鎾斁
+
+## 蹇�熷垽鏂柟娉�
+
+### 鏂规硶1: 鐩存帴鐢ㄦ挱鏀惧櫒娴嬭瘯锛堟渶绠�鍗曪級
+
+1. **浠嶢ndroid璁惧涓嬭浇鏂囦欢**
+   ```bash
+   adb pull /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264 ./test.h264
+   ```
+
+2. **鐢╒LC鎾斁鍣ㄦ墦寮�**
+   - 涓嬭浇VLC: https://www.videolan.org/vlc/
+   - 鐩存帴鍙屽嚮 `test.h264` 鏂囦欢
+   - 鎴栬�呮嫋鏀惧埌VLC绐楀彛
+
+3. **濡傛灉鑳芥挱鏀�** 鉁�
+   - 璇存槑鏂囦欢鏍煎紡姝g‘
+   - 鍙互鐪嬪埌瑙嗛鍐呭
+
+4. **濡傛灉涓嶈兘鎾斁** 鉂�
+   - 鍙兘缂哄皯SPS/PPS
+   - 鍙兘鍙湁1甯�
+   - 鍙兘鏍煎紡閿欒
+
+### 鏂规硶2: 浣跨敤Python宸ュ叿妫�鏌ワ紙璇︾粏鍒嗘瀽锛�
+
+1. **纭繚瀹夎浜哖ython** (Python 3.6+)
+
+2. **涓嬭浇鏂囦欢鍒版湰鍦�**
+   ```bash
+   adb pull /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264 ./test.h264
+   ```
+
+3. **杩愯妫�鏌ュ伐鍏�**
+   ```bash
+   python check_h264.py test.h264
+   ```
+
+4. **鏌ョ湅妫�鏌ョ粨鏋�**
+   
+   鉁� **鍙互鎾斁鐨勬爣蹇楋細**
+   - 鉁� 鍖呭惈SPS (搴忓垪鍙傛暟闆�)
+   - 鉁� 鍖呭惈PPS (鍥惧儚鍙傛暟闆�)  
+   - 鉁� 鍖呭惈IDR鍏抽敭甯�
+   - 鉁� 鏈夊涓狽ALU鍗曞厓锛堝缓璁�>10涓級
+
+   鉂� **涓嶈兘鎾斁鐨勬爣蹇楋細**
+   - 缂哄皯SPS鎴朠PS
+   - 鍙湁1-2涓狽ALU鍗曞厓
+   - 鏂囦欢澶皬锛�<100瀛楄妭锛�
+
+### 鏂规硶3: 浣跨敤ffprobe妫�鏌ワ紙濡傛灉瀹夎浜咶Fmpeg锛�
+
+```bash
+ffprobe test.h264
+```
+
+濡傛灉鑳芥纭樉绀鸿棰戜俊鎭紙鍒嗚鲸鐜囥�佸抚鐜囩瓑锛夛紝璇存槑鏂囦欢鍙互鎾斁銆�
+
+### 鏂规硶4: 鏌ョ湅鏂囦欢澶у皬锛堢矖鐣ュ垽鏂級
+
+```bash
+# 鍦ˋndroid璁惧涓�
+adb shell "ls -lh /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264"
+```
+
+**鍙傝�冩爣鍑嗭細**
+- 鉁� **鍙互鎾斁**锛氶�氬父 > 10KB锛�640x480@25fps锛�3绉掔害30-50KB锛�
+- 鈿狅笍 **鍙兘鍙湁1甯�**锛�< 5KB
+- 鉂� **鏂囦欢寮傚父**锛�= 0KB
+
+## 妫�鏌ユ枃浠跺唴瀹癸紙楂樼骇锛�
+
+### 浣跨敤hexdump鏌ョ湅鏂囦欢澶�
+
+```bash
+hexdump -C test.h264 | head -20
+```
+
+**姝e父鏂囦欢搴旇鐪嬪埌锛�**
+```
+00000000  00 00 00 01 67 64 00 1f  ac 72 84 44 26 84 00 00  |....gd...r.D&...|
+00000010  00 01 00 00 00 01 68 ee  3c b0 44 00 00 00 01 06  |......h.<.D.....|
+```
+
+- `00 00 00 01` = Annex-B璧峰鐮侊紙4瀛楄妭锛�
+- `67` = SPS鐨凬ALU绫诲瀷锛�0x67 & 0x1F = 7锛�
+- `68` = PPS鐨凬ALU绫诲瀷锛�0x68 & 0x1F = 8锛�
+
+### 浣跨敤adb鍦ㄨ澶囦笂鐩存帴妫�鏌�
+
+```bash
+# 妫�鏌ユ枃浠跺ぇ灏�
+adb shell "stat -c '%s' /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264"
+
+# 鏌ョ湅鏂囦欢鍓�50瀛楄妭
+adb shell "hexdump -C /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264 | head -5"
+```
+
+## 甯歌闂璇婃柇
+
+### 鉂� 闂1: 鏂囦欢鍙湁1甯с��0绉�
+
+**鍘熷洜锛�**
+- 缂栫爜鍣ㄨ緭鍑哄鐞嗕笉瀹屾暣
+- SPS/PPS娌℃湁姝g‘鍐欏叆
+- 缂栫爜寰幆鎻愬墠閫�鍑�
+
+**瑙e喅鏂规锛�**
+鉁� 宸茬粡淇锛佹柊浠g爜鍖呭惈锛�
+- 姝g‘澶勭悊SPS/PPS閰嶇疆鏁版嵁
+- 鍦ㄥ叧閿抚鏃跺悎骞禨PS/PPS
+- 鏀硅繘缂栫爜寰幆锛屽鐞嗘墍鏈夎緭鍑�
+- 娣诲姞娓呯┖缂栫爜鍣ㄥ姛鑳�
+
+**寤鸿锛�**
+1. 閲嶆柊缂栬瘧杩愯搴旂敤
+2. 褰曞埗鑷冲皯3-5绉�
+3. 姝e父鍋滄缂栫爜锛堜笉瑕佸己鍒堕��鍑猴級
+
+### 鉂� 闂2: VLC鏃犳硶鎾斁
+
+**妫�鏌ユ楠わ細**
+
+1. **鏌ョ湅鏂囦欢澶у皬**
+   ```bash
+   adb shell "ls -lh /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264"
+   ```
+   濡傛灉澶皬锛�<1KB锛夛紝璇存槑鍙兘鍙湁閰嶇疆鏁版嵁
+
+2. **鏌ョ湅Logcat鏃ュ織**
+   ```bash
+   adb logcat -s H264Encoder:D | grep -E "Frame encoded|SPS/PPS|NALU"
+   ```
+   搴旇鐪嬪埌锛�
+   - "SPS/PPS included in key frame data"
+   - "Frame encoded: ..." 锛堝娆★級
+
+3. **妫�鏌ユ枃浠舵牸寮�**
+   ```bash
+   adb shell "hexdump -C /storage/emulated/0/Android/data/com.anyun.h264/files/test.h264 | head -3"
+   ```
+   搴旇鐪嬪埌 `00 00 00 01` 鎴� `00 00 01`
+
+### 鉂� 闂3: 鏂囦欢瀛樺湪浣嗘挱鏀惧櫒鎶ラ敊
+
+**鍙兘鍘熷洜锛�**
+1. 鏂囦欢鏍煎紡涓嶆槸绾疉nnex-B
+2. 缂哄皯SPS/PPS
+3. 鏁版嵁鎹熷潖
+
+**瑙e喅鏂规硶锛�**
+1. 浣跨敤 `check_h264.py` 璇︾粏妫�鏌�
+2. 鏌ョ湅Logcat纭缂栫爜杩囩▼姝e父
+3. 灏濊瘯鐢╢fmpeg杞崲锛�
+   ```bash
+   ffmpeg -i test.h264 -c copy test_fixed.h264
+   ```
+
+## 楠岃瘉淇鏁堟灉
+
+淇鍚庣殑浠g爜搴旇鑳藉锛�
+
+鉁� **鐢熸垚鍙挱鏀剧殑H264鏂囦欢**
+- 鍖呭惈瀹屾暣鐨凷PS/PPS
+- 鍖呭惈澶氫釜甯э紙IDR + 闈濱DR锛�
+- 姝g‘鐨凙nnex-B鏍煎紡
+
+鉁� **鏂囦欢鐗瑰緛锛�**
+- 鏂囦欢澶у皬 > 10KB锛�3绉掑綍鍒讹級
+- NALU鍗曞厓鏁伴噺 > 10涓�
+- 鍖呭惈SPS (绫诲瀷7)
+- 鍖呭惈PPS (绫诲瀷8)
+- 鍖呭惈IDR鍏抽敭甯� (绫诲瀷5)
+- 鍖呭惈闈濱DR甯� (绫诲瀷1)
+
+## 涓嬩竴姝�
+
+1. **閲嶆柊杩愯搴旂敤**锛屽綍鍒�3-5绉掕棰�
+2. **涓嬭浇鏂囦欢**鍒版湰鍦�
+3. **鐢╒LC鎾斁**楠岃瘉
+4. **濡傛灉杩樻湁闂**锛岃繍琛屾鏌ュ伐鍏疯幏鍙栬缁嗚瘖鏂�
+

--
Gitblit v1.8.0