-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Config packets must be prepended to the next media packet. Extract the logic to a new sc_packet_merger helper to simplify the demuxer code.
- Loading branch information
Showing
5 changed files
with
104 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include "packet_merger.h" | ||
|
||
#include "util/log.h" | ||
|
||
void | ||
sc_packet_merger_init(struct sc_packet_merger *merger) { | ||
merger->config = NULL; | ||
} | ||
|
||
void | ||
sc_packet_merger_destroy(struct sc_packet_merger *merger) { | ||
free(merger->config); | ||
} | ||
|
||
bool | ||
sc_packet_merger_merge(struct sc_packet_merger *merger, AVPacket *packet) { | ||
bool is_config = packet->pts == AV_NOPTS_VALUE; | ||
|
||
if (is_config) { | ||
free(merger->config); | ||
|
||
merger->config = malloc(packet->size); | ||
if (!merger->config) { | ||
LOG_OOM(); | ||
return false; | ||
} | ||
|
||
memcpy(merger->config, packet->data, packet->size); | ||
merger->config_size = packet->size; | ||
} else if (merger->config) { | ||
size_t config_size = merger->config_size; | ||
size_t media_size = packet->size; | ||
|
||
if (av_grow_packet(packet, config_size)) { | ||
LOG_OOM(); | ||
return false; | ||
} | ||
|
||
memmove(packet->data + config_size, packet->data, media_size); | ||
memcpy(packet->data, merger->config, config_size); | ||
|
||
free(merger->config); | ||
merger->config = NULL; | ||
// merger->size is meaningless when merger->config is NULL | ||
} | ||
|
||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#ifndef SC_PACKET_MERGER_H | ||
#define SC_PACKET_MERGER_H | ||
|
||
#include "common.h" | ||
|
||
#include <stdbool.h> | ||
#include <stdint.h> | ||
#include <libavcodec/avcodec.h> | ||
|
||
/** | ||
* Config packets (containing the SPS/PPS) are sent in-band. A new config | ||
* packet is sent whenever a new encoding session is started (on start and on | ||
* device orientation change). | ||
* | ||
* Every time a config packet is received, it must be sent alone (for recorder | ||
* extradata), then concatenated to the next media packet (for correct decoding | ||
* and recording). | ||
* | ||
* This helper reads every input packet and modifies each media packet which | ||
* immediately follows a config packet to prepend the config packet payload. | ||
*/ | ||
|
||
struct sc_packet_merger { | ||
uint8_t *config; | ||
size_t config_size; | ||
}; | ||
|
||
void | ||
sc_packet_merger_init(struct sc_packet_merger *merger); | ||
|
||
void | ||
sc_packet_merger_destroy(struct sc_packet_merger *merger); | ||
|
||
/** | ||
* If the packet is a config packet, then keep its data for later. | ||
* Otherwise (if the packet is a media packet), then if a config packet is | ||
* pending, prepend the config packet to this packet (so the packet is | ||
* modified!). | ||
*/ | ||
bool | ||
sc_packet_merger_merge(struct sc_packet_merger *merger, AVPacket *packet); | ||
|
||
#endif |