

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 코드 작성 및 검사
<a name="producersdk-c-write"></a>

이 섹션에서는 GitHub의 [https://github.com/awslabs/amazon-kinesis-video-streams-producer-c](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c) 리포지토리 `samples` 폴더에 `KvsVideoOnlyStreamingSample.c` 있는 샘플 애플리케이션의 코드를 살펴봅니다. 이전 단계에서 이 코드를 다운로드했습니다. 이 샘플은 C 생산자 라이브러리를 사용하여 폴더 내부의 H.264 인코딩 비디오 프레임을 Kinesis 비디오 스트림`samples/h264SampleFrames`으로 전송하는 방법을 보여줍니다.

이 샘플 애플리케이션에는 세 개의 섹션이 있습니다.
+ 초기화 및 구성:
  + 플랫폼별 미디어 파이프라인 초기화 및 구성.
  + 파이프라인에 대한 KinesisVideoClient 및 KinesisVideoStream 초기화 및 구성, 콜백 설정, 시나리오별 인증 통합, 코덱 프라이빗 데이터 추출 및 제출, READY 상태로 스트림 가져오기.
+ 기본 루프:
  + 타임스탬프 및 플래그와 함께 미디어 파이프라인에서 프레임 가져오기.
  + KinesisVideoStream에 프레임 제출.
+ 해제:
  + (동기화) KinesisVideoStream 중지, KinesisVideoStream 확보, KinesisVideoClient 확보.

이 샘플 애플리케이션은 다음 작업을 완료합니다.
+ `createDefaultDeviceInfo` API를 호출하여 디바이스 또는 스토리지 구성에 대한 정보가 포함된 `deviceInfo` 객체를 생성합니다.

  ```
  // default storage size is 128MB. Use setDeviceInfoStorageSize after create to change storage size.
  CHK_STATUS(createDefaultDeviceInfo(&pDeviceInfo));
  // adjust members of pDeviceInfo here if needed
      pDeviceInfo->clientInfo.loggerLogLevel = LOG_LEVEL_DEBUG;
  ```
+ `createRealtimeVideoStreamInfoProvider` API를 호출하여 `StreamInfo` 객체를 생성합니다.

  ```
  CHK_STATUS(createRealtimeVideoStreamInfoProvider(streamName, DEFAULT_RETENTION_PERIOD, DEFAULT_BUFFER_DURATION, &pStreamInfo));
  // adjust members of pStreamInfo here if needed
  ```
+ `createDefaultCallbacksProviderWithAwsCredentials` API를 호출하여 정적 AWS 자격 증명을 기반으로 기본 콜백 공급자를 생성합니다.

  ```
  CHK_STATUS(createDefaultCallbacksProviderWithAwsCredentials(accessKey,
                                                                  secretKey,
                                                                  sessionToken,
                                                                  MAX_UINT64,
                                                                  region,
                                                                  cacertPath,
                                                                  NULL,
                                                                  NULL,
                                                                  FALSE,
                                                                  &pClientCallbacks));
  ```
+ `createKinesisVideoClient` API를 호출하여 디바이스 스토리지에 대한 정보가 포함된 `KinesisVideoClient` 객체를 생성하고 Kinesis Video Streams 이벤트에 대해 보고할 콜백을 유지합니다.

  ```
  CHK_STATUS(createKinesisVideoClient(pDeviceInfo, pClientCallbacks, &clientHandle));                
  ```
+ `createKinesisVideoStreamSync` API를 호출하여 `KinesisVideoStream` 객체를 생성합니다.

  ```
  CHK_STATUS(createKinesisVideoStreamSync(clientHandle, pStreamInfo, &streamHandle));                
  ```
+ 샘플 프레임을 설정하고 `PutKinesisVideoFrame` API를 호출하여 해당 프레임을 `KinesisVideoStream` 객체로 전송합니다.

  ```
   // setup sample frame
      MEMSET(frameBuffer, 0x00, frameSize);
      frame.frameData = frameBuffer;
      frame.version = FRAME_CURRENT_VERSION;
      frame.trackId = DEFAULT_VIDEO_TRACK_ID;
      frame.duration = HUNDREDS_OF_NANOS_IN_A_SECOND / DEFAULT_FPS_VALUE;
      frame.decodingTs = defaultGetTime(); // current time
      frame.presentationTs = frame.decodingTs;
  
      while(defaultGetTime() > streamStopTime) {
          frame.index = frameIndex;
          frame.flags = fileIndex % DEFAULT_KEY_FRAME_INTERVAL == 0 ? FRAME_FLAG_KEY_FRAME : FRAME_FLAG_NONE;
          frame.size = SIZEOF(frameBuffer);
  
          CHK_STATUS(readFrameData(&frame, frameFilePath));
  
          CHK_STATUS(putKinesisVideoFrame(streamHandle, &frame));
          defaultThreadSleep(frame.duration);
  
          frame.decodingTs += frame.duration;
          frame.presentationTs = frame.decodingTs;
          frameIndex++;
          fileIndex++;
          fileIndex = fileIndex % NUMBER_OF_FRAME_FILES;
      }
  ```
+ 해제:

  ```
  CHK_STATUS(stopKinesisVideoStreamSync(streamHandle));
  CHK_STATUS(freeKinesisVideoStream(&streamHandle));
  CHK_STATUS(freeKinesisVideoClient(&clientHandle));
  ```